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
_hw_control_qemud_client_recv(void * opaque,uint8_t * msg,int msglen,QemudClient * client)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*
_hw_control_qemud_connect(void * opaque,QemudService * service,int channel,const char * client_param)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*
if_starts_with(uint8_t * buf,int buflen,const char * prefix)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
hw_control_do_query(HwControl * h,uint8_t * query,int querylen)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
hw_control_init(HwControl * control,void * client,const AndroidHwControlFuncs * client_funcs)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
android_hw_control_init(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
android_hw_control_set(void * opaque,const AndroidHwControlFuncs * funcs)148 android_hw_control_set( void* opaque, const AndroidHwControlFuncs* funcs )
149 {
150 hwstate->client = opaque;
151 hwstate->client_funcs = funcs[0];
152 }
153
154