aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rmi4update/rmi4update.cpp8
-rw-r--r--rmidevice/hiddevice.cpp89
-rw-r--r--rmidevice/hiddevice.h1
-rw-r--r--rmidevice/rmidevice.h1
4 files changed, 94 insertions, 5 deletions
diff --git a/rmi4update/rmi4update.cpp b/rmi4update/rmi4update.cpp
index 0b2bd0d..7bb4f4b 100644
--- a/rmi4update/rmi4update.cpp
+++ b/rmi4update/rmi4update.cpp
@@ -23,7 +23,8 @@
#include <string.h>
#include <stdlib.h>
#include <errno.h>
-
+#include <fcntl.h>
+#include <linux/input.h>
#include "rmi4update.h"
#define RMI_F34_QUERY_SIZE 7
@@ -242,7 +243,12 @@ int RMI4Update::UpdateFirmware(bool force, bool performLockdown)
reset:
m_device.Reset();
+rebind:
m_device.RebindDriver();
+ if(!m_device.CheckABSEvent())
+ {
+ goto rebind;
+ }
return rc;
}
diff --git a/rmidevice/hiddevice.cpp b/rmidevice/hiddevice.cpp
index af05feb..855dd25 100644
--- a/rmidevice/hiddevice.cpp
+++ b/rmidevice/hiddevice.cpp
@@ -622,7 +622,89 @@ bool WriteDeviceNameToFile(const char * file, const char * str)
return close(fd) == 0 && size == static_cast<ssize_t>(strlen(str));
}
+static const char * const absval[6] = { "Value", "Min ", "Max ", "Fuzz ", "Flat ", "Resolution "};
+#define KEY_MAX 0x2ff
+#define EV_MAX 0x1f
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define OFF(x) ((x)%BITS_PER_LONG)
+#define BIT(x) (1UL<<OFF(x))
+#define LONG(x) ((x)/BITS_PER_LONG)
+#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1)
+#define DEV_INPUT_EVENT "/dev/input"
+#define EVENT_DEV_NAME "event"
+/**
+ * Filter for the AutoDevProbe scandir on /dev/input.
+ *
+ * @param dir The current directory entry provided by scandir.
+ *
+ * @return Non-zero if the given directory entry starts with "event", or zero
+ * otherwise.
+ */
+static int is_event_device(const struct dirent *dir) {
+ return strncmp(EVENT_DEV_NAME, dir->d_name, 5) == 0;
+}
+bool HIDDevice::CheckABSEvent()
+{
+ int fd=-1;
+ unsigned int type;
+ int abs[6] = {0};
+ int k;
+ struct dirent **namelist;
+ int i, ndev, devnum, match;
+ char *filename;
+ int max_device = 0;
+ char input_event_name[PATH_MAX];
+ unsigned long bit[EV_MAX][NBITS(KEY_MAX)];
+
+
+ ndev = scandir(DEV_INPUT_EVENT, &namelist, is_event_device, versionsort);
+ if (ndev <= 0)
+ return false;
+ for (i = 0; i < ndev; i++)
+ {
+ char fname[64];
+ int fd = -1;
+ char name[256] = "???";
+
+ snprintf(fname, sizeof(fname),
+ "%s/%s", DEV_INPUT_EVENT, namelist[i]->d_name);
+ fd = open(fname, O_RDONLY);
+ if (fd < 0)
+ continue;
+ ioctl(fd, EVIOCGNAME(sizeof(name)), name);
+ //fprintf(stderr, "%s: %s\n", fname, name);
+ close(fd);
+
+ if(strstr(name, m_transportDeviceName.c_str()+4))
+ {
+ snprintf(input_event_name, sizeof(fname), "%s", fname);
+ }
+ free(namelist[i]);
+ }
+
+ if ((fd = open(input_event_name, O_RDONLY)) < 0) {
+ if (errno == EACCES && getuid() != 0)
+ fprintf(stderr, "No access right \n");
+ }
+ memset(bit, 0, sizeof(bit));
+ ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]);
+ for (type = 0; type < EV_MAX; type++) {
+ if (test_bit(type, bit[0]) && type == EV_ABS) {
+ ioctl(fd, EVIOCGBIT(type, KEY_MAX), bit[type]);
+ if (test_bit(ABS_X, bit[type])) {
+ ioctl(fd, EVIOCGABS(ABS_X), abs);
+ if(abs[2] == 0) //maximum
+ {
+ Sleep(1000);
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
void HIDDevice::RebindDriver()
{
int bus = m_info.bustype;
@@ -635,7 +717,6 @@ void HIDDevice::RebindDriver()
int notifyFd;
int wd;
int rc;
-
Close();
notifyFd = inotify_init();
@@ -663,16 +744,16 @@ void HIDDevice::RebindDriver()
}
}
-
+
bindFile = m_driverPath + "bind";
unbindFile = m_driverPath + "unbind";
-
+ Sleep(500);
if (!WriteDeviceNameToFile(unbindFile.c_str(), m_transportDeviceName.c_str())) {
fprintf(stderr, "Failed to unbind HID device %s: %s\n",
m_transportDeviceName.c_str(), strerror(errno));
return;
}
-
+ Sleep(500);
if (!WriteDeviceNameToFile(bindFile.c_str(), m_transportDeviceName.c_str())) {
fprintf(stderr, "Failed to bind HID device %s: %s\n",
m_transportDeviceName.c_str(), strerror(errno));
diff --git a/rmidevice/hiddevice.h b/rmidevice/hiddevice.h
index d5dfec1..b947f62 100644
--- a/rmidevice/hiddevice.h
+++ b/rmidevice/hiddevice.h
@@ -60,6 +60,7 @@ public:
virtual void PrintDeviceInfo();
virtual bool FindDevice(enum RMIDeviceType type = RMI_DEVICE_TYPE_ANY);
+ virtual bool CheckABSEvent();
private:
int m_fd;
diff --git a/rmidevice/rmidevice.h b/rmidevice/rmidevice.h
index bd91eeb..9bfe849 100644
--- a/rmidevice/rmidevice.h
+++ b/rmidevice/rmidevice.h
@@ -54,6 +54,7 @@ public:
virtual void Close();
virtual void Cancel() { m_bCancel = true; }
virtual void RebindDriver() = 0;
+ virtual bool CheckABSEvent() = 0;
unsigned long GetFirmwareID() { return m_buildID; }
unsigned long GetConfigID() { return m_configID; }