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/globals.h" 27 #include "android/utils/misc.h" 28 #include "android/utils/debug.h" 29 #include "qemu-char.h" 30 #include <stdio.h> 31 #include <string.h> 32 33 #define D(...) VERBOSE_PRINT(hw_control,__VA_ARGS__) 34 35 /* define T_ACTIVE to 1 to debug transport communications */ 36 #define T_ACTIVE 0 37 38 #if T_ACTIVE 39 #define T(...) VERBOSE_PRINT(hw_control,__VA_ARGS__) 40 #else 41 #define T(...) ((void)0) 42 #endif 43 44 typedef struct { 45 void* client; 46 AndroidHwControlFuncs client_funcs; 47 QemudService* service; 48 } HwControl; 49 50 /* handle query */ 51 static void hw_control_do_query( HwControl* h, uint8_t* query, int querylen ); 52 53 /* called when a qemud client sends a command */ 54 static void 55 _hw_control_qemud_client_recv( void* opaque, 56 uint8_t* msg, 57 int msglen, 58 QemudClient* client ) 59 { 60 hw_control_do_query(opaque, msg, msglen); 61 } 62 63 /* called when a qemud client connects to the service */ 64 static QemudClient* 65 _hw_control_qemud_connect( void* opaque, 66 QemudService* service, 67 int channel, 68 const char* client_param ) 69 { 70 QemudClient* client; 71 72 client = qemud_client_new( service, channel, client_param, 73 opaque, 74 _hw_control_qemud_client_recv, 75 NULL, NULL, NULL ); 76 77 qemud_client_set_framing(client, 1); 78 return client; 79 } 80 81 82 static uint8_t* 83 if_starts_with( uint8_t* buf, int buflen, const char* prefix ) 84 { 85 int prefixlen = strlen(prefix); 86 87 if (buflen < prefixlen || memcmp(buf, prefix, prefixlen)) 88 return NULL; 89 90 return (uint8_t*)buf + prefixlen; 91 } 92 93 94 static void 95 hw_control_do_query( HwControl* h, 96 uint8_t* query, 97 int querylen ) 98 { 99 uint8_t* q; 100 101 T("%s: query %4d '%.*s'", __FUNCTION__, querylen, querylen, query ); 102 103 q = if_starts_with( query, querylen, "power:light:brightness:" ); 104 if (q != NULL) { 105 if (h->client_funcs.light_brightness && android_hw->hw_lcd_backlight) { 106 char* qq = strchr((const char*)q, ':'); 107 int value; 108 if (qq == NULL) { 109 D("%s: badly formatted", __FUNCTION__ ); 110 return; 111 } 112 *qq++ = 0; 113 value = atoi(qq); 114 h->client_funcs.light_brightness( h->client, (char*)q, value ); 115 } 116 return; 117 } 118 } 119 120 121 static void 122 hw_control_init( HwControl* control, 123 void* client, 124 const AndroidHwControlFuncs* client_funcs ) 125 { 126 control->client = client; 127 control->client_funcs = client_funcs[0]; 128 control->service = qemud_service_register( "hw-control", 0, 129 control, 130 _hw_control_qemud_connect, 131 NULL, NULL); 132 } 133 134 const AndroidHwControlFuncs defaultControls = { 135 NULL, 136 }; 137 138 static HwControl hwstate[1]; 139 140 void 141 android_hw_control_init( void ) 142 { 143 hw_control_init(hwstate, NULL, &defaultControls); 144 D("%s: hw-control qemud handler initialized", __FUNCTION__); 145 } 146 147 void 148 android_hw_control_set( void* opaque, const AndroidHwControlFuncs* funcs ) 149 { 150 hwstate->client = opaque; 151 hwstate->client_funcs = funcs[0]; 152 } 153 154