Difference between revisions of "Hidd"
Line 297: | Line 297: | ||
You'll see its socket get registered and then some printf's when getcallback and init get called. | You'll see its socket get registered and then some printf's when getcallback and init get called. | ||
− | Next steps will be to | + | Next steps will be to fix to figure out gPluginPrvInfo since we probably need to put more things in it, and then to actually communicate with hidd. :) |
Revision as of 21:46, 25 November 2010
Intro
This is a research page on hidd -- how to examine what it does, how it works, etc.
Files
Hidd is started from upstart (/etc/event.d/hidd) with a -f option to load a given configuration file. On the emulator, this is /etc/hidd/HidPluginsVbox.xml. On a pre, this is /etc/hidd/HidPlugins.xml. There's also something called casper there, not sure what that is as of yet
Architecture
Hidd seems to use a modular plugin-style architecture where each plugin is a shared library.
Default files are:
libhid.so libhidavrcp.so libhidlight.so libhidqemukeypad.so libhidtouchpanel.so libhidaccelerometer.so libhidkeypad.so libhidproximity.so libhidqemutouchpanel.so
Plugin definition in config file
<source lang=xml>
<plugin> <name>HidKeypad</name> <eventsDeferIdle>true</eventsDeferIdle> <eventSocketAddress>/var/tmp/hidd/KeypadEventSocket</eventSocketAddress> <cmdSocketAddress>/var/tmp/hidd/KeypadCmdSocket</cmdSocketAddress> <path>/usr/lib/libhidkeypad.so</path> </plugin>
</source>
Starting the daemon
A lot of debug information can be obtained by starting the daemon like so (on a pre, on an emulator add Vbox before .xml)
/usr/bin/hidd -vvv -f /etc/hidd/HidPlugins.xml
Example trace
/usr/bin/hidd -vvv -f /etc/hidd/HidPlugins-keypadonly.xml
Verbosity level set to 7
root@castle:/etc/hidd# hidd -vvvv -f /etc/hidd/HidPlugins-test.xml
Verbosity level set to 7
Plugin: 0
Name: HidKeypad Path: /usr/lib/libhidkeypad.so Event Socket Address: /var/tmp/hidd/KeypadEventSocket Cmd Socket Address: /var/tmp/hidd/KeypadCmdSocket
_SetupPluginTransport:
Socket created successfully
_SetupPluginTransport:
--> Event socket address: /var/tmp/hidd/KeypadEventSocket
_SetupPluginTransport:
--> Command socket address: /var/tmp/hidd/KeypadCmdSocket
Init:
HidKeypad: init function called!
HidKeypadIpc.c:104 : GetSwitchStates: Bad file descriptor ReportEvent:
kInputEvent received 1 events, fd: 7
_ReportStandardEvent:
Event: 0.0, type=EV_SYN, code=8, value=0
HidPluginStartReaderThread:
HidKeypad: starting reader thread
main:
Setting up power management...
ReportEvent:
kInputEvent received 2 events, fd: 7
_ReportStandardEvent:
Event: 85906.791100, type=EV_KEY, code=19, value=1
_ReportStandardEvent:
Event: 85906.791130, type=EV_SYN, code=0, value=0
ReportEvent:
kInputEvent received 2 events, fd: 7
_ReportStandardEvent:
Event: 85906.999809, type=EV_KEY, code=19, value=0
_ReportStandardEvent:
Event: 85906.999840, type=EV_SYN, code=0, value=0
Listening to Hidd event
The libSDL patch provided by Palm provides good examples of listening to events via hidd. Based upon this I created a simple example program to listen to the HidKeypad events and print them to stdout. Listening directly to HidKeypad events we can observe all the keys including power button, volume keys and center gesture-area button. I built using WIDK. WARNING: After running this program, I cannot get the screen to come back on after sleeping via a key press. It only turns back on after reconnecting USB cable
hidTest.c
#include <stdio.h> #include <linux/input.h> #include "HidLib.h" //#include "hid/IncsPublic/HidLib.h" #define XML_FILE "/etc/hidd/HidPlugins.xml" static HidPluginSettings_t* pSettings = NULL; static int numPlugins = 0; int HidEventInit(void) { PmErr retVal = kPmErrorUnknown; if (pSettings == NULL) { retVal = HidAllocPluginSettings(XML_FILE, &pSettings, &numPlugins); if (kPmErrorNone != retVal) { pSettings = NULL; return -1; } } return 0; } void HidEventDeInit(void) { if (NULL != pSettings) { HidFreePluginSettings(&pSettings, numPlugins); pSettings = NULL; } } void *HidEventOpen(int Device) { PmErr retVal = kPmErrorUnknown; HidHandle_t* pHandle = NULL; if (pSettings == NULL) { // Ensure plugin settings are initialized. if (HidEventInit() != 0) { return NULL; } } static const char* PluginName[] = { HID_KEYPAD, HID_ACCELEROMETER, HID_TOUCHPANEL }; retVal = HidInitPluginTransport(PluginName[Device], pSettings, numPlugins, &pHandle); if (kPmErrorNone != retVal) { HidFreePluginSettings(&pSettings, numPlugins); pSettings = NULL; return NULL; } return pHandle; } void HidEventClose(void *Handle) { if (NULL != Handle) { HidDestroyPluginTransport((HidHandle_t**)&Handle); } } int HidEventGetFd(void *Handle) { return HidHandleGetFd((HidHandle_t*)Handle); } int HidEventRead(void *Handle, struct input_event* Events, int MaxEvents) { return HidHandleReadInputEvent((HidHandle_t*)Handle, (InputEvent_t*)Events, MaxEvents); } int main() { void *pHandle; struct input_event myevent; int ret = 0; pHandle = HidEventOpen(0); while (1) { ret = HidEventRead(pHandle, &myevent, 1); printf("return %d, type %d, code %d, value %d\n", ret, myevent.type, myevent.code, myevent.value); // q for quit if (myevent.code == 16) { HidEventDeInit(); HidEventClose(pHandle); break; } } return 0; }
HidLib.h
typedef int HidPluginSettings_t; typedef int HidHandle_t; typedef int PmErr; typedef struct input_event InputEvent_t; #define kPmErrorNone 0 #define kPmErrorUnknown -1 #define HID_KEYPAD "HidKeypad" #define HID_ACCELEROMETER "HidAccelerometer" #define HID_TOUCHPANEL "HidTouchpanel"
Makefile
CC = arm-none-linux-gnueabi-gcc CFLAGS = -g -O2 -I/usr/local/include LIBS = -Wl,-rpath,/usr/local/lib -L/usr/local/lib -lhid DEMOS = hidTest $(DEMOS): $(CC) -o $@ $@.c $(CFLAGS) $(LIBS) clean: rm -f $(DEMOS)
Silly hidd plugin
#include <stdio.h> typedef struct PluginTable_t { int (*GetEventCallBack)() ; int (*Init)() ; int (*Exit)() ; int (*Suspend)() ; int (*Resume)() ; int (*Poll)() ; } PluginTable_t; extern PluginTable_t PluginTable; void *gPluginPrvInfo[21]; int GetEventCallBack(void *a1) { printf( "Silly GetEventCallBack()\n" ) ; gPluginPrvInfo[0] = a1; return 0; } int Init(a1) { printf( "Silly Init\n" ) ; return HidPluginGenericInit(a1, gPluginPrvInfo); } int Exit() { printf( "Silly Exit\n" ) ; return HidPluginGenericExit(gPluginPrvInfo); } int Suspend() { printf( "Silly Suspend\n" ) ; return HidPluginGenericSuspend(gPluginPrvInfo); } int Resume() { printf( "Silly Resume\n" ) ; return HidPluginGenericResume(gPluginPrvInfo); } int Poll() { printf( "Silly Poll\n" ) ; return HidPluginGenericGetEvents(gPluginPrvInfo); } PluginTable_t PluginTable = { *GetEventCallBack, *Init, *Exit, *Suspend, *Resume, *Poll } ;
You'll see its socket get registered and then some printf's when getcallback and init get called. Next steps will be to fix to figure out gPluginPrvInfo since we probably need to put more things in it, and then to actually communicate with hidd. :)