Home | History | Annotate | Download | only in android
      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
     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*
     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*
     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
     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
    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
    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