Android Hardware Abstraction Layer
qemud.h
Go to the documentation of this file.
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(...) ((void)0)
41 #endif
42 
43 static __inline__ int
44 qemud_fd_write(int fd, const void* buff, int len)
45 {
46  int len2;
47  do {
48  len2 = write(fd, buff, len);
49  } while (len2 < 0 && errno == EINTR);
50  return len2;
51 }
52 
53 static __inline__ int
54 qemud_fd_read(int fd, void* buff, int len)
55 {
56  int len2;
57  do {
58  len2 = read(fd, buff, len);
59  } while (len2 < 0 && errno == EINTR);
60  return len2;
61 }
62 
63 static __inline__ int
64 qemud_channel_open(const char* name)
65 {
66  int fd;
67  int namelen = strlen(name);
68  char answer[2];
69  char pipe_name[256];
70 
71  /* First, try to connect to the pipe. */
72  snprintf(pipe_name, sizeof(pipe_name), "qemud:%s", name);
73  fd = qemu_pipe_open(pipe_name);
74  if (fd < 0) {
75  D("QEMUD pipe is not available for %s: %s", name, strerror(errno));
76  /* If pipe is not available, connect to qemud control socket */
77  fd = socket_local_client( "qemud",
78  ANDROID_SOCKET_NAMESPACE_RESERVED,
79  SOCK_STREAM );
80  if (fd < 0) {
81  D("no qemud control socket: %s", strerror(errno));
82  return -1;
83  }
84 
85  /* send service name to connect */
86  if (qemud_fd_write(fd, name, namelen) != namelen) {
87  D("can't send service name to qemud: %s",
88  strerror(errno));
89  close(fd);
90  return -1;
91  }
92 
93  /* read answer from daemon */
94  if (qemud_fd_read(fd, answer, 2) != 2 ||
95  answer[0] != 'O' || answer[1] != 'K') {
96  D("cant' connect to %s service through qemud", name);
97  close(fd);
98  return -1;
99  }
100  }
101  return fd;
102 }
103 
104 static __inline__ int
105 qemud_channel_send(int fd, const void* msg, int msglen)
106 {
107  char header[5];
108 
109  if (msglen < 0)
110  msglen = strlen((const char*)msg);
111 
112  if (msglen == 0)
113  return 0;
114 
115  snprintf(header, sizeof header, "%04x", msglen);
116  if (qemud_fd_write(fd, header, 4) != 4) {
117  D("can't write qemud frame header: %s", strerror(errno));
118  return -1;
119  }
120 
121  if (qemud_fd_write(fd, msg, msglen) != msglen) {
122  D("can4t write qemud frame payload: %s", strerror(errno));
123  return -1;
124  }
125  return 0;
126 }
127 
128 static __inline__ int
129 qemud_channel_recv(int fd, void* msg, int msgsize)
130 {
131  char header[5];
132  int size, avail;
133 
134  if (qemud_fd_read(fd, header, 4) != 4) {
135  D("can't read qemud frame header: %s", strerror(errno));
136  return -1;
137  }
138  header[4] = 0;
139  if (sscanf(header, "%04x", &size) != 1) {
140  D("malformed qemud frame header: '%.*s'", 4, header);
141  return -1;
142  }
143  if (size > msgsize)
144  return -1;
145 
146  if (qemud_fd_read(fd, msg, size) != size) {
147  D("can't read qemud frame payload: %s", strerror(errno));
148  return -1;
149  }
150  return size;
151 }
152 
153 #endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_H */