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 "android/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 "sysemu/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
44typedef struct {
45    void*                  client;
46    AndroidHwControlFuncs  client_funcs;
47    QemudService*          service;
48} HwControl;
49
50/* handle query */
51static void  hw_control_do_query( HwControl*  h, uint8_t*  query, int  querylen );
52
53/* called when a qemud client sends a command */
54static 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 */
64static 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
82static uint8_t*
83if_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
94static void
95hw_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
121static void
122hw_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
134const AndroidHwControlFuncs  defaultControls = {
135    NULL,
136};
137
138static HwControl   hwstate[1];
139
140void
141android_hw_control_init( void )
142{
143    hw_control_init(hwstate, NULL, &defaultControls);
144    D("%s: hw-control qemud handler initialized", __FUNCTION__);
145}
146
147void
148android_hw_control_set( void*  opaque, const AndroidHwControlFuncs*  funcs )
149{
150    hwstate->client       = opaque;
151    hwstate->client_funcs = funcs[0];
152}
153
154