18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* this file implements the support of the new 'hardware control'
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * qemud communication channel, which is used by libs/hardware on
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * the system image to communicate with the emulator program for
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * emulating the following:
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   - power management
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   - led(s) brightness
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   - vibrator
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   - flashlight
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/hw-control.h"
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "cbuffer.h"
259877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project#include "android/hw-qemud.h"
26470f6bd314acbf5c2c8a408f5f00b5ce55d5eab4Tim Wan#include "android/globals.h"
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/misc.h"
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/debug.h"
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-char.h"
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  D(...)  VERBOSE_PRINT(hw_control,__VA_ARGS__)
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* define T_ACTIVE to 1 to debug transport communications */
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  T_ACTIVE  0
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if T_ACTIVE
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  T(...)  VERBOSE_PRINT(hw_control,__VA_ARGS__)
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  T(...)   ((void)0)
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
459877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    void*                  client;
469877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    AndroidHwControlFuncs  client_funcs;
479877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    QemudService*          service;
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} HwControl;
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
509877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* handle query */
519877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic void  hw_control_do_query( HwControl*  h, uint8_t*  query, int  querylen );
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
539877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* called when a qemud client sends a command */
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
55318e4f294c181df33cf2541763904565b29bcccbDavid 'Digit' Turner_hw_control_qemud_client_recv( void*         opaque,
56318e4f294c181df33cf2541763904565b29bcccbDavid 'Digit' Turner                               uint8_t*      msg,
57318e4f294c181df33cf2541763904565b29bcccbDavid 'Digit' Turner                               int           msglen,
58318e4f294c181df33cf2541763904565b29bcccbDavid 'Digit' Turner                               QemudClient*  client )
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
609877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    hw_control_do_query(opaque, msg, msglen);
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
639877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project/* called when a qemud client connects to the service */
649877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic QemudClient*
654c414820910ba8553cab7ff30188575f972a9896Vladimir Chtchetkine_hw_control_qemud_connect( void*  opaque,
664c414820910ba8553cab7ff30188575f972a9896Vladimir Chtchetkine                           QemudService*  service,
674c414820910ba8553cab7ff30188575f972a9896Vladimir Chtchetkine                           int  channel,
684c414820910ba8553cab7ff30188575f972a9896Vladimir Chtchetkine                           const char* client_param )
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
709877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    QemudClient*  client;
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
724c414820910ba8553cab7ff30188575f972a9896Vladimir Chtchetkine    client = qemud_client_new( service, channel, client_param,
739877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project                               opaque,
749877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project                               _hw_control_qemud_client_recv,
75871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije                               NULL, NULL, NULL );
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
779877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    qemud_client_set_framing(client, 1);
789877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    return client;
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic uint8_t*
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectif_starts_with( uint8_t*  buf, int buflen, const char*  prefix )
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  prefixlen = strlen(prefix);
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (buflen < prefixlen || memcmp(buf, prefix, prefixlen))
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return NULL;
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (uint8_t*)buf + prefixlen;
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecthw_control_do_query( HwControl*  h,
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     uint8_t*    query,
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     int         querylen )
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t*   q;
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1019877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    T("%s: query %4d '%.*s'", __FUNCTION__, querylen, querylen, query );
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    q = if_starts_with( query, querylen, "power:light:brightness:" );
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (q != NULL) {
105470f6bd314acbf5c2c8a408f5f00b5ce55d5eab4Tim Wan        if (h->client_funcs.light_brightness && android_hw->hw_lcd_backlight) {
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            char*  qq = strchr((const char*)q, ':');
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int    value;
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (qq == NULL) {
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                D("%s: badly formatted", __FUNCTION__ );
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return;
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *qq++ = 0;
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            value = atoi(qq);
1149877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project            h->client_funcs.light_brightness( h->client, (char*)q, value );
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1219877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projectstatic void
1229877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Projecthw_control_init( HwControl*                    control,
1239877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project                 void*                         client,
1249877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project                 const AndroidHwControlFuncs*  client_funcs )
1259877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project{
1269877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    control->client       = client;
1279877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    control->client_funcs = client_funcs[0];
1289877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    control->service      = qemud_service_register( "hw-control", 0,
1299877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project                                                    control,
130871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije                                                    _hw_control_qemud_connect,
131871da2aa80687142bec00ef7c1112253c76c32bbOt ten Thije                                                    NULL, NULL);
1329877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project}
1339877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project
134ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turnerconst AndroidHwControlFuncs  defaultControls = {
135ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner    NULL,
136ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner};
137ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner
138ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turnerstatic HwControl   hwstate[1];
139ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
141ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turnerandroid_hw_control_init( void )
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
143ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner    hw_control_init(hwstate, NULL, &defaultControls);
1449877e2e3e3c2df64de306b48f80a4f5d0b028d95The Android Open Source Project    D("%s: hw-control qemud handler initialized", __FUNCTION__);
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
146ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner
147ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turnervoid
148ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turnerandroid_hw_control_set( void*  opaque, const AndroidHwControlFuncs*  funcs )
149ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner{
150ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner    hwstate->client       = opaque;
151ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner    hwstate->client_funcs = funcs[0];
152ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner}
153ca9505992288636908169d0389087b3ca5277d07David 'Digit' Turner
154