1 /* Copyright (C) 2007-2008 The Android Open Source Project 2 ** 3 ** This software is licensed under the terms of the GNU General Public 4 ** License version 2, as published by the Free Software Foundation, and 5 ** may be copied, distributed, and modified under those terms. 6 ** 7 ** This program is distributed in the hope that it will be useful, 8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 ** GNU General Public License for more details. 11 */ 12 13 /* this file implements the support of the new 'hardware control' 14 * qemud communication channel, which is used by libs/hardware on 15 * the system image to communicate with the emulator program for 16 * emulating the following: 17 * 18 * - power management 19 * - led(s) brightness 20 * - vibrator 21 * - flashlight 22 */ 23 #include "android/hw-control.h" 24 #include "cbuffer.h" 25 #include "android/hw-qemud.h" 26 #include "android/utils/misc.h" 27 #include "android/utils/debug.h" 28 #include "qemu-char.h" 29 #include <stdio.h> 30 #include <string.h> 31 32 #define D(...) VERBOSE_PRINT(hw_control,__VA_ARGS__) 33 34 /* define T_ACTIVE to 1 to debug transport communications */ 35 #define T_ACTIVE 0 36 37 #if T_ACTIVE 38 #define T(...) VERBOSE_PRINT(hw_control,__VA_ARGS__) 39 #else 40 #define T(...) ((void)0) 41 #endif 42 43 typedef struct { 44 void* client; 45 AndroidHwControlFuncs client_funcs; 46 QemudService* service; 47 } HwControl; 48 49 /* handle query */ 50 static void hw_control_do_query( HwControl* h, uint8_t* query, int querylen ); 51 52 /* called when a qemud client sends a command */ 53 static void 54 _hw_control_qemud_client_recv( void* opaque, 55 uint8_t* msg, 56 int msglen, 57 QemudClient* client ) 58 { 59 hw_control_do_query(opaque, msg, msglen); 60 } 61 62 /* called when a qemud client connects to the service */ 63 static QemudClient* 64 _hw_control_qemud_connect( void* opaque, QemudService* service, int channel ) 65 { 66 QemudClient* client; 67 68 client = qemud_client_new( service, channel, 69 opaque, 70 _hw_control_qemud_client_recv, 71 NULL ); 72 73 qemud_client_set_framing(client, 1); 74 return client; 75 } 76 77 78 static uint8_t* 79 if_starts_with( uint8_t* buf, int buflen, const char* prefix ) 80 { 81 int prefixlen = strlen(prefix); 82 83 if (buflen < prefixlen || memcmp(buf, prefix, prefixlen)) 84 return NULL; 85 86 return (uint8_t*)buf + prefixlen; 87 } 88 89 90 static void 91 hw_control_do_query( HwControl* h, 92 uint8_t* query, 93 int querylen ) 94 { 95 uint8_t* q; 96 97 T("%s: query %4d '%.*s'", __FUNCTION__, querylen, querylen, query ); 98 99 q = if_starts_with( query, querylen, "power:light:brightness:" ); 100 if (q != NULL) { 101 if (h->client_funcs.light_brightness) { 102 char* qq = strchr((const char*)q, ':'); 103 int value; 104 if (qq == NULL) { 105 D("%s: badly formatted", __FUNCTION__ ); 106 return; 107 } 108 *qq++ = 0; 109 value = atoi(qq); 110 h->client_funcs.light_brightness( h->client, (char*)q, value ); 111 } 112 return; 113 } 114 } 115 116 117 static void 118 hw_control_init( HwControl* control, 119 void* client, 120 const AndroidHwControlFuncs* client_funcs ) 121 { 122 control->client = client; 123 control->client_funcs = client_funcs[0]; 124 control->service = qemud_service_register( "hw-control", 0, 125 control, 126 _hw_control_qemud_connect ); 127 } 128 129 void 130 android_hw_control_init( void* opaque, const AndroidHwControlFuncs* funcs ) 131 { 132 static HwControl hwstate[1]; 133 134 hw_control_init(hwstate, opaque, funcs); 135 D("%s: hw-control qemud handler initialized", __FUNCTION__); 136 } 137