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
43typedef struct {
44    void*                  client;
45    AndroidHwControlFuncs  client_funcs;
46    QemudService*          service;
47} HwControl;
48
49/* handle query */
50static void  hw_control_do_query( HwControl*  h, uint8_t*  query, int  querylen );
51
52/* called when a qemud client sends a command */
53static void
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 */
63static QemudClient*
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
78static uint8_t*
79if_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
90static void
91hw_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
117static void
118hw_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
129void
130android_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