diff options
author | Vincent Huang <vincent.huang@tw.synaptics.com> | 2018-09-05 16:20:36 +0800 |
---|---|---|
committer | Andrew Duggan <aduggan@synaptics.com> | 2018-09-06 21:21:37 -0700 |
commit | 876b06ba6e99b86a307e5fa322084ebcc8718587 (patch) | |
tree | 6fc743c55d4d21f18a4aef8ca3586c9336ffa488 | |
parent | 459d02fc2c6d706cd15eb56528cb5278b6b403ff (diff) | |
download | rmi4utils-876b06ba6e99b86a307e5fa322084ebcc8718587.tar.gz |
Workaround to check event maximum value
-rw-r--r-- | rmi4update/rmi4update.cpp | 8 | ||||
-rw-r--r-- | rmidevice/hiddevice.cpp | 89 | ||||
-rw-r--r-- | rmidevice/hiddevice.h | 1 | ||||
-rw-r--r-- | rmidevice/rmidevice.h | 1 |
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; } |