blob: 874a32f2451842b8b7f6846209c0a3835e6dbd89 [file] [log] [blame]
The Android Open Source Project65f2d3a2009-03-18 17:39:47 -07001/*
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
22/* the following is helper code that is used by the QEMU-specific
23 * hardware HAL modules to communicate with the emulator program
24 * through the 'qemud' multiplexing daemon.
25 *
26 * see the documentation comments for details in
27 * development/emulator/qemud/qemud.c
28 *
29 * all definitions here are built into the HAL module to avoid
30 * having to write a tiny shared library for this.
31 */
32
33/* we expect the D macro to be defined to a function macro
34 * that sends its formatted string argument(s) to the log.
35 * If not, ignore the traces.
36 */
37#ifndef D
38# define D(...) ((void)0)
39#endif
40
41static __inline__ int
42qemud_fd_write(int fd, const void* buff, int len)
43{
44 int len2;
45 do {
46 len2 = write(fd, buff, len);
47 } while (len2 < 0 && errno == EINTR);
48 return len2;
49}
50
51static __inline__ int
52qemud_fd_read(int fd, void* buff, int len)
53{
54 int len2;
55 do {
56 len2 = read(fd, buff, len);
57 } while (len2 < 0 && errno == EINTR);
58 return len2;
59}
60
61static __inline__ int
62qemud_channel_open(const char* name)
63{
64 int fd;
65 int namelen = strlen(name);
66 char answer[2];
67
68 /* connect to qemud control socket */
69 fd = socket_local_client( "qemud",
70 ANDROID_SOCKET_NAMESPACE_RESERVED,
71 SOCK_STREAM );
72 if (fd < 0) {
73 D("no qemud control socket: %s", strerror(errno));
74 return -1;
75 }
76
77 /* send service name to connect */
78 if (qemud_fd_write(fd, name, namelen) != namelen) {
79 D("can't send service name to qemud: %s",
80 strerror(errno));
81 close(fd);
82 return -1;
83 }
84
85 /* read answer from daemon */
86 if (qemud_fd_read(fd, answer, 2) != 2 ||
87 answer[0] != 'O' || answer[1] != 'K') {
88 D("cant' connect to %s service through qemud", name);
89 close(fd);
90 return -1;
91 }
92 return fd;
93}
94
95static __inline__ int
96qemud_channel_send(int fd, const void* msg, int msglen)
97{
98 char header[5];
99
100 if (msglen < 0)
101 msglen = strlen((const char*)msg);
102
103 if (msglen == 0)
104 return 0;
105
106 snprintf(header, sizeof header, "%04x", msglen);
107 if (qemud_fd_write(fd, header, 4) != 4) {
108 D("can't write qemud frame header: %s", strerror(errno));
109 return -1;
110 }
111
112 if (qemud_fd_write(fd, msg, msglen) != msglen) {
113 D("can4t write qemud frame payload: %s", strerror(errno));
114 return -1;
115 }
116 return 0;
117}
118
119static __inline__ int
120qemud_channel_recv(int fd, void* msg, int msgsize)
121{
122 char header[5];
123 int size, avail;
124
125 if (qemud_fd_read(fd, header, 4) != 4) {
126 D("can't read qemud frame header: %s", strerror(errno));
127 return -1;
128 }
129 header[4] = 0;
130 if (sscanf(header, "%04x", &size) != 1) {
131 D("malformed qemud frame header: '%.*s'", 4, header);
132 return -1;
133 }
134 if (size > msgsize)
135 return -1;
136
137 if (qemud_fd_read(fd, msg, size) != size) {
138 D("can't read qemud frame payload: %s", strerror(errno));
139 return -1;
140 }
141 return size;
142}
143
144#endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_H */