Hi,
attached is a patch to use uevent to get kernel notifications for
'usb-cable-changed' in QtExtended on recent kernels (>=2.6.28).
On 'older' kernels (<2.6.28), this information was comming in trough
/dev/input/event4 but this is no longer working (there is a ticket for
this at https://docs.openmoko.org/trac/ticket/2254 ).
With this patch my FR switches correctly from battery power savings scheme
to online pwoer scheme, and usb networking goes up/down as expected.
Same mechanism could be used to re-implement an event based neobattery.
This patch should not break 2.6.24 compatibility.
Cheers,
Filip.
>From 367a7ec014442b47be615ccbde8dc7441bfb466c Mon Sep 17 00:00:00 2001
From: Filip Onkelinx <fi...@dev.linux4.be>
Date: Tue, 31 Mar 2009 22:28:22 +0200
Subject: [PATCH] using uevent to get kernel notifications for usb cable changed
Signed-off-by: Filip Onkelinx <fi...@dev.linux4.be>
---
devices/neo/server/neohardware.cpp | 79 ++
devices/neo/server/neohardware.h | 6 +-
2 files changed, 85 insertions(+), 1 deletions(-)
diff --git a/devices/neo/server/neohardware.cpp
b/devices/neo/server/neohardware.cpp
index e259094..fca61bc 100644
--- a/devices/neo/server/neohardware.cpp
+++ b/devices/neo/server/neohardware.cpp
@@ -44,6 +44,16 @@
#include <linux/input.h>
#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/un.h>
+#include <sys/socket.h>
+#include <linux/types.h>
+#include <linux/netlink.h>
+#include <QTcpSocket>
+#include <QtDebug>
QTOPIA_TASK(NeoHardware, NeoHardware);
@@ -52,10 +62,31 @@ NeoHardware::NeoHardware()
vsoUsbCable("/Hardware/UsbGadget"),
vsoNeoHardware("/Hardware/Neo")
{
+ struct sockaddr_nl snl;
adaptor = new QtopiaIpcAdaptor("QPE/NeoHardware");
qLog(Hardware) << "neohardware";
+ memset(&snl, 0x00, sizeof(struct sockaddr_nl));
+ snl.nl_family = AF_NETLINK;
+ snl.nl_pid = getpid();
+ snl.nl_groups = 1;
+ snl.nl_groups = 0x1;
+
+ int hotplug_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
+ if (hotplug_sock == -1) {
+ qLog(Hardware) << "error getting uevent socket: "<< strerror(errno);
+ }else{
+ if ( bind(hotplug_sock, (struct sockaddr *) &snl, sizeof(struct
sockaddr_nl)) < 0) {
+ qLog(Hardware) << "uevent bind failed: "<< strerror(errno);
+ hotplug_sock = -1;
+ }else{
+ ueventSocket = new QTcpSocket(this);
+ ueventSocket->setSocketDescriptor(hotplug_sock);
+ connect(ueventSocket, SIGNAL(readyRead()), this, SLOT(uevent()));
+ }
+ }
+
cableConnected(getCableStatus());
vsoPortableHandsfree.setAttribute("Present", false);
@@ -77,6 +108,54 @@ NeoHardware::~NeoHardware()
{
}
+char *NeoHardware::findAttribute(char *buf, int len, const char *token)
+{
+int pos=0;
+
+ while (pos<len)
+ {
+ if(strncmp(&buf[pos],token,strlen(token))==0)
+ return(&buf[pos+strlen(token)]);
+ pos=pos+strlen(&buf[pos])+1;
+ }
+ return(buf);
+}
+
+void NeoHardware::uevent()
+{
+#define UEVENT_BUFFER_SIZE 1024
+char buffer[UEVENT_BUFFER_SIZE];
+char *value;
+
+ int bytesAvail = ueventSocket->bytesAvailable();
+ int readCount = UEVENT_BUFFER_SIZE;
+ if (bytesAvail < readCount)
+ readCount = bytesAvail;
+ ueventSocket->read(&buffer[0],readCount);
+ if(strcmp(buffer,"change@/class/power_supply/usb")==0)
+ {
+ value=findAttribute(buffer,readCount,"POWER_SUPPLY_ONLINE=");
+ qDebug()<<"usb change event; online='"<<value<<"'";
+ cableConnected(atoi(value));
+ }else if(strcmp(buffer,"change@/class/power_supply/ac")==0)
+ {
+ value=findAttribute(buffer,readCount,"POWER_SUPPLY_ONLINE=");
+ qDebug()<<"ac change event; online="<<value;
+ }else if(strcmp(buffer,"change@/class/power_supply/adapter")==0)
+ {
+ value=findAttribute(buffer,readCount,"POWER_SUPPLY_ONLINE=");
+ qDebug()<<"power_supply change event; online="<<value;
+ }else if(strcmp(buffer,"change@/class/power_supply/battery")==0)
+ {
+ value=findAttribute(buffer,readCount,"POWER_SUPPLY_CAPACITY=");
+ qDebug()<<"battery change event charge%="<<value<<"%";
+ }else if(strcmp(buffer,"change@/class/switch/headset")==0)
+ {
+ value=findAttribute(buffer,readCount,"SWITCH_STATE=");
+ qDebug()<<"headset change event, switch_state="<<value;
+ }
+}
+
void NeoHardware::findHardwareVersion()
{
QFile cpuinfo( "/proc/cpuinfo");
diff --git a/devices/neo/server/neohardware.h b/devices/neo/server/neohardware.h
index f52b232..0d70f72 100644
--- a/devices/neo/server/neohardware.h
+++ b/devices/neo/server/neohardware.h
@@ -24,6 +24,7 @@
#include <QObject>
#include <QProcess>
+#include <QTcpSocket>
#include <qvaluespace.h>
#include <linux/input.h>
@@ -48,15 +49,18 @@ private:
QValueSpaceObject vsoUsbCable;
QValueSpaceObject vsoNeoHardware;
QtopiaIpcAdaptor *adaptor;
+ QTcpSocket *ueventSocket;
void findHardwareVersion();
QtopiaIpcAdaptor *audioMgr;
-
+ char *findAttribute(char *buf, int len, const char *token);
+
private slots:
void headphonesInserted(bool);
void cableConnected(bool);
void shutdownRequested();
bool getCableStatus();
+ void uevent();
};
--
1.4.4.4
_______________________________________________
Openmoko community mailing list
community@lists.openmoko.org
http://lists.openmoko.org/mailman/listinfo/community