• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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