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 */ 154