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