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
_hw_control_qemud_client_recv(void * opaque,uint8_t * msg,int msglen,QemudClient * client)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*
_hw_control_qemud_connect(void * opaque,QemudService * service,int channel)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*
if_starts_with(uint8_t * buf,int buflen,const char * prefix)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
hw_control_do_query(HwControl * h,uint8_t * query,int querylen)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
hw_control_init(HwControl * control,void * client,const AndroidHwControlFuncs * client_funcs)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
android_hw_control_init(void * opaque,const AndroidHwControlFuncs * funcs)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