1cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project/* 2cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * 4cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * you may not use this file except in compliance with the License. 6cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * You may obtain a copy of the License at 7cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * 8cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * 10cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * See the License for the specific language governing permissions and 14cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * limitations under the License. 15cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project */ 16cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 17cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project/* this file contains various functions used by all libhardware modules 18cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project * that support QEMU emulation 19cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project */ 20cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include "qemu.h" 21cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#define LOG_TAG "hardware-qemu" 22cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <cutils/log.h> 23cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <cutils/properties.h> 24cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <cutils/sockets.h> 25cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <errno.h> 26cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <fcntl.h> 27cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <termios.h> 28cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <stdio.h> 29cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#include <stdarg.h> 30cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 31cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#define QEMU_DEBUG 0 32cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 33cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#if QEMU_DEBUG 34b381b932acfa441da5607f37ac4ef6573ed5be96Steve Block# define D(...) ALOGD(__VA_ARGS__) 35cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#else 36cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project# define D(...) ((void)0) 37cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project#endif 38cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 392dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine#include "hardware/qemu_pipe.h" 40cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 41cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint 42cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectqemu_check(void) 43cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 44cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project static int in_qemu = -1; 45cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 46cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (__builtin_expect(in_qemu < 0,0)) { 47cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char propBuf[PROPERTY_VALUE_MAX]; 48cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project property_get("ro.kernel.qemu", propBuf, ""); 49cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project in_qemu = (propBuf[0] == '1'); 50cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 51cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return in_qemu; 52cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 53cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 54e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Projectstatic int 55e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Projectqemu_fd_write( int fd, const char* cmd, int len ) 56e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project{ 57e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project int len2; 58e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project do { 59e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project len2 = write(fd, cmd, len); 60e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } while (len2 < 0 && errno == EINTR); 61e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return len2; 62e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project} 63e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 64e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Projectstatic int 65e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Projectqemu_fd_read( int fd, char* buff, int len ) 66e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project{ 67e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project int len2; 68e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project do { 69e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project len2 = read(fd, buff, len); 70e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } while (len2 < 0 && errno == EINTR); 71e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return len2; 72e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project} 73e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 742dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkinestatic int 752dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkineqemu_channel_open_qemud_pipe( QemuChannel* channel, 762dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine const char* name ) 772dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine{ 782dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine int fd; 792dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine char pipe_name[512]; 802dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine 812dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine snprintf(pipe_name, sizeof(pipe_name), "qemud:%s", name); 822dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine fd = qemu_pipe_open(pipe_name); 832dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine if (fd < 0) { 842dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine D("no qemud pipe: %s", strerror(errno)); 852dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine return -1; 862dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine } 872dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine 882dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine channel->is_qemud = 1; 892dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine channel->fd = fd; 902dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine return 0; 912dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine} 92e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 93e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Projectstatic int 94e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Projectqemu_channel_open_qemud( QemuChannel* channel, 95e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project const char* name ) 96e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project{ 97e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project int fd, ret, namelen = strlen(name); 98e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project char answer[2]; 99e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 100e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project fd = socket_local_client( "qemud", 101e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project ANDROID_SOCKET_NAMESPACE_RESERVED, 102e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project SOCK_STREAM ); 103e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (fd < 0) { 104e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project D("no qemud control socket: %s", strerror(errno)); 105e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return -1; 106e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } 107e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 108e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project /* send service name to connect */ 109e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (qemu_fd_write(fd, name, namelen) != namelen) { 110e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project D("can't send service name to qemud: %s", 111e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project strerror(errno)); 112e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project close(fd); 113e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return -1; 114e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } 115e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 116e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project /* read answer from daemon */ 117e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (qemu_fd_read(fd, answer, 2) != 2 || 118e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project answer[0] != 'O' || answer[1] != 'K') { 119e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project D("cant' connect to %s service through qemud", name); 120e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project close(fd); 121e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return -1; 122e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } 123e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 124e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project channel->is_qemud = 1; 125e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project channel->fd = fd; 126e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return 0; 127e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project} 128e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 129e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 130e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Projectstatic int 131e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Projectqemu_channel_open_qemud_old( QemuChannel* channel, 132e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project const char* name ) 133e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project{ 134e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project int fd; 135e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 136e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project snprintf(channel->device, sizeof channel->device, 137e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project "qemud_%s", name); 138e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 139e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project fd = socket_local_client( channel->device, 140e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project ANDROID_SOCKET_NAMESPACE_RESERVED, 141e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project SOCK_STREAM ); 142e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (fd < 0) { 143e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project D("no '%s' control socket available: %s", 144e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project channel->device, strerror(errno)); 145e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return -1; 146e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } 147e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 148e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project close(fd); 149e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project channel->is_qemud_old = 1; 150e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return 0; 151e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project} 152e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 153e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 154e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Projectstatic int 155e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Projectqemu_channel_open_tty( QemuChannel* channel, 156e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project const char* name, 157e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project int mode ) 158e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project{ 159e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project char key[PROPERTY_KEY_MAX]; 160e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project char prop[PROPERTY_VALUE_MAX]; 161e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project int ret; 162e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 163e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project ret = snprintf(key, sizeof key, "ro.kernel.android.%s", name); 164e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (ret >= (int)sizeof key) 165e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return -1; 166e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 167e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (property_get(key, prop, "") == 0) { 168e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project D("no kernel-provided %s device name", name); 169e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return -1; 170e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } 171e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 172e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project ret = snprintf(channel->device, sizeof channel->device, 173e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project "/dev/%s", prop); 174e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (ret >= (int)sizeof channel->device) { 175e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project D("%s device name too long: '%s'", name, prop); 176e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return -1; 177e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } 178e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 179e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project channel->is_tty = !memcmp("/dev/tty", channel->device, 8); 180e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return 0; 181e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project} 182cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 183cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint 184cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectqemu_channel_open( QemuChannel* channel, 185cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project const char* name, 186cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int mode ) 187cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 188cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int fd = -1; 189cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 190cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* initialize the channel is needed */ 191cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (!channel->is_inited) 192cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project { 193e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project channel->is_inited = 1; 194cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 195cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project do { 1962dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine if (qemu_channel_open_qemud_pipe(channel, name) == 0) 1972dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine break; 1982dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkine 199e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (qemu_channel_open_qemud(channel, name) == 0) 200cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project break; 201cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 202e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (qemu_channel_open_qemud_old(channel, name) == 0) 203cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project break; 204cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 205e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (qemu_channel_open_tty(channel, name, mode) == 0) 206cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project break; 207cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 208e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project channel->is_available = 0; 209e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return -1; 210cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } while (0); 211cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 212e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project channel->is_available = 1; 213cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 214cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 215cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* try to open the file */ 216cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (!channel->is_available) { 217cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project errno = ENOENT; 218e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return -1; 219e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } 220e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 221e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (channel->is_qemud) { 222e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project return dup(channel->fd); 223e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } 224e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project 225e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project if (channel->is_qemud_old) { 226cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project do { 227cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project fd = socket_local_client( channel->device, 228cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ANDROID_SOCKET_NAMESPACE_RESERVED, 229cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project SOCK_STREAM ); 230cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } while (fd < 0 && errno == EINTR); 231e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project } 232e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project else /* /dev/ttySn ? */ 233e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project { 234cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project do { 235cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project fd = open(channel->device, mode); 236cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } while (fd < 0 && errno == EINTR); 237cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 238cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* disable ECHO on serial lines */ 239cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (fd >= 0 && channel->is_tty) { 240cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project struct termios ios; 241cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project tcgetattr( fd, &ios ); 242cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ios.c_lflag = 0; /* disable ECHO, ICANON, etc... */ 243cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project tcsetattr( fd, TCSANOW, &ios ); 244cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 245cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 246cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return fd; 247cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 248cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 249cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 250cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic int 2512dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkineqemu_command_vformat( char* buffer, 252cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int buffer_size, 253cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project const char* format, 254cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project va_list args ) 255cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 256cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char header[5]; 257cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int len; 258cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 259cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (buffer_size < 6) 260cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 261cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 262cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project len = vsnprintf(buffer+4, buffer_size-4, format, args); 263cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (len >= buffer_size-4) 264cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 265cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 266cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project snprintf(header, sizeof header, "%04x", len); 267cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project memcpy(buffer, header, 4); 268cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return len + 4; 269cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 270cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 271cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectextern int 2722dbd8949b2ac0aaa98f89a467c14bff857505794Vladimir Chtchetkineqemu_command_format( char* buffer, 273cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int buffer_size, 274cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project const char* format, 275cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ... ) 276cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 277cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project va_list args; 278cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int ret; 279cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 280cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project va_start(args, format); 281cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ret = qemu_command_format(buffer, buffer_size, format, args); 282cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project va_end(args); 283cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return ret; 284cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 285cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 286cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 287cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic int 288cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectqemu_control_fd(void) 289cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 290cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project static QemuChannel channel[1]; 291cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int fd; 292cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 293e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project fd = qemu_channel_open( channel, "hw-control", O_RDWR ); 294cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (fd < 0) { 295cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project D("%s: could not open control channel: %s", __FUNCTION__, 296cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project strerror(errno)); 297cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 298cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return fd; 299cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 300cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 301cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectstatic int 302cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectqemu_control_send(const char* cmd, int len) 303cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 304cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int fd, len2; 305cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 306cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (len < 0) { 307cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project errno = EINVAL; 308cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 309cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 310cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 311cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project fd = qemu_control_fd(); 312cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (fd < 0) 313cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 314cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 315e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project len2 = qemu_fd_write(fd, cmd, len); 316cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project close(fd); 317cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (len2 != len) { 318cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project D("%s: could not send everything %d < %d", 319cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project __FUNCTION__, len2, len); 320cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 321cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 322cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return 0; 323cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 324cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 325cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 326cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectint 327cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectqemu_control_command( const char* fmt, ... ) 328cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 329cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project va_list args; 330cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char command[256]; 331cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int len, fd; 332cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 333cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project va_start(args, fmt); 334cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project len = qemu_command_vformat( command, sizeof command, fmt, args ); 335cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project va_end(args); 336cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 337cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (len < 0 || len >= (int)sizeof command) { 338cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (len < 0) { 339cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project D("%s: could not send: %s", __FUNCTION__, strerror(errno)); 340cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } else { 341cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project D("%s: too large %d > %d", __FUNCTION__, len, (int)(sizeof command)); 342cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 343cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project errno = EINVAL; 344cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 345cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 346cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 347cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return qemu_control_send( command, len ); 348cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 349cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 350cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Projectextern int qemu_control_query( const char* question, int questionlen, 351cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char* answer, int answersize ) 352cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project{ 353cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project int ret, fd, len, result = -1; 354cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project char header[5], *end; 355cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 356cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (questionlen <= 0) { 357cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project errno = EINVAL; 358cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 359cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 360cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 361cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project fd = qemu_control_fd(); 362cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (fd < 0) 363cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return -1; 364cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 365e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project ret = qemu_fd_write( fd, question, questionlen ); 366cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ret != questionlen) { 367cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project D("%s: could not write all: %d < %d", __FUNCTION__, 368cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project ret, questionlen); 369cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project goto Exit; 370cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 371cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 372cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* read a 4-byte header giving the length of the following content */ 373e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project ret = qemu_fd_read( fd, header, 4 ); 374cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ret != 4) { 375cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project D("%s: could not read header (%d != 4)", 376cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project __FUNCTION__, ret); 377cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project goto Exit; 378cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 379cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 380e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project header[4] = 0; 381cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project len = strtol( header, &end, 16 ); 382cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if ( len < 0 || end == NULL || end != header+4 || len > answersize ) { 383cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project D("%s: could not parse header: '%s'", 384cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project __FUNCTION__, header); 385cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project goto Exit; 386cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 387cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 388cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project /* read the answer */ 389e18b7b21c2fe0788e6cf1a1a055a25c2e5bc2dd8The Android Open Source Project ret = qemu_fd_read( fd, answer, len ); 390cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project if (ret != len) { 391cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project D("%s: could not read all of answer %d < %d", 392cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project __FUNCTION__, ret, len); 393cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project goto Exit; 394cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project } 395cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 396cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project result = len; 397cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project 398cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source ProjectExit: 399cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project close(fd); 400cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project return result; 401cc490161f6af9e4a6842ee827e4bfc43bc4509d5The Android Open Source Project} 402