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