• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_INCLUDE_HARDWARE_QEMUD_H
18 #define ANDROID_INCLUDE_HARDWARE_QEMUD_H
19 
20 #include <cutils/sockets.h>
21 #include "qemu_pipe.h"
22 
23 /* the following is helper code that is used by the QEMU-specific
24  * hardware HAL modules to communicate with the emulator program
25  * through the 'qemud' multiplexing daemon, or through the qemud
26  * pipe.
27  *
28  * see the documentation comments for details in
29  * development/emulator/qemud/qemud.c
30  *
31  * all definitions here are built into the HAL module to avoid
32  * having to write a tiny shared library for this.
33  */
34 
35 /* we expect the D macro to be defined to a function macro
36  * that sends its formatted string argument(s) to the log.
37  * If not, ignore the traces.
38  */
39 #ifndef D
40 #  define  D(...)   do{}while(0)
41 #endif
42 
43 
44 static __inline__ int
qemud_channel_open(const char * name)45 qemud_channel_open(const char*  name)
46 {
47     int  fd;
48     int  namelen = strlen(name);
49     char answer[2];
50     char pipe_name[256];
51 
52     /* First, try to connect to the pipe. */
53     snprintf(pipe_name, sizeof(pipe_name), "qemud:%s", name);
54     fd = qemu_pipe_open(pipe_name);
55     D("%s: pipe name %s (name %s) fd %d", __FUNCTION__, pipe_name, name, fd);
56     if (fd < 0) {
57         D("QEMUD pipe is not available for %s: %s", name, strerror(errno));
58         /* If pipe is not available, connect to qemud control socket */
59         fd = socket_local_client( "qemud",
60                                   ANDROID_SOCKET_NAMESPACE_RESERVED,
61                                   SOCK_STREAM );
62         if (fd < 0) {
63             D("no qemud control socket: %s", strerror(errno));
64             return -1;
65         }
66 
67         /* send service name to connect */
68         if (!WriteFully(fd, name, namelen)) {
69             D("can't send service name to qemud: %s",
70                strerror(errno));
71             close(fd);
72             return -1;
73         }
74 
75         /* read answer from daemon */
76         if (!ReadFully(fd, answer, 2) ||
77             answer[0] != 'O' || answer[1] != 'K') {
78             D("cant' connect to %s service through qemud", name);
79             close(fd);
80             return -1;
81         }
82     }
83     return fd;
84 }
85 
86 static __inline__ int
qemud_channel_send(int fd,const void * msg,int msglen)87 qemud_channel_send(int  fd, const void*  msg, int  msglen)
88 {
89     char  header[5];
90 
91     if (msglen < 0)
92         msglen = strlen((const char*)msg);
93 
94     if (msglen == 0)
95         return 0;
96 
97     snprintf(header, sizeof header, "%04x", msglen);
98     if (!WriteFully(fd, header, 4)) {
99         D("can't write qemud frame header: %s", strerror(errno));
100         return -1;
101     }
102 
103     if (!WriteFully(fd, msg, msglen)) {
104         D("can4t write qemud frame payload: %s", strerror(errno));
105         return -1;
106     }
107     return 0;
108 }
109 
110 static __inline__ int
qemud_channel_recv(int fd,void * msg,int msgsize)111 qemud_channel_recv(int  fd, void*  msg, int  msgsize)
112 {
113     char  header[5];
114     int   size;
115 
116     if (!ReadFully(fd, header, 4)) {
117         D("can't read qemud frame header: %s", strerror(errno));
118         return -1;
119     }
120     header[4] = 0;
121     if (sscanf(header, "%04x", &size) != 1) {
122         D("malformed qemud frame header: '%.*s'", 4, header);
123         return -1;
124     }
125     if (size > msgsize)
126         return -1;
127 
128     if (!ReadFully(fd, msg, size)) {
129         D("can't read qemud frame payload: %s", strerror(errno));
130         return -1;
131     }
132     return size;
133 }
134 
135 #endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_H */
136