/
inputdevadaptor.cpp
203 lines (172 loc) · 6.33 KB
/
inputdevadaptor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/**
@file inputdevadaptor.cpp
@brief Base class for input layer device adaptors
<p>
Copyright (C) 2009-2010 Nokia Corporation
@author Timo Rongas <ext-timo.2.rongas@nokia.com>
@author Ustun Ergenoglu <ext-ustun.ergenoglu@nokia.com>
@author Matias Muhonen <ext-matias.muhonen@nokia.com>
@author Antti Virtanen <antti.i.virtanen@nokia.com>
@author Lihan Guo <ext-lihan.4.guo@nokia.com>
@author Shenghua <ext-shenghua.1.liu@nokia.com>
@author Antti Virtanen <antti.i.virtanen@nokia.com>
This file is part of Sensord.
Sensord is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License
version 2.1 as published by the Free Software Foundation.
Sensord is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with Sensord. If not, see <http://www.gnu.org/licenses/>.
</p>
*/
#include "inputdevadaptor.h"
#include "config.h"
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <QFile>
#include <QDir>
#include <QString>
InputDevAdaptor::InputDevAdaptor(const QString& id, int maxDeviceCount) :
SysfsAdaptor(id, SysfsAdaptor::SelectMode, false),
deviceCount_(0),
maxDeviceCount_(maxDeviceCount),
cachedInterval_(0)
{
memset(evlist_, 0x0, sizeof(input_event)*64);
}
InputDevAdaptor::~InputDevAdaptor()
{
}
int InputDevAdaptor::getInputDevices(const QString& typeName)
{
qDebug() << Q_FUNC_INFO << typeName;
QString deviceSysPathString = SensorFrameworkConfig::configuration()->value("global/device_sys_path").toString();
QString devicePollFilePath = SensorFrameworkConfig::configuration()->value("global/device_poll_file_path").toString();
int deviceNumber = 0;
deviceString_ = typeName;
// Check if this device name is defined in configuration
QString deviceName = SensorFrameworkConfig::configuration()->value<QString>(typeName + "/device", "");
// Do not perform strict checks for the input device
if (deviceName.size() && checkInputDevice(deviceName, typeName, false)) {
addPath(deviceName, deviceCount_);
++deviceCount_;
} else if(deviceSysPathString.contains("%1")) {
const int MAX_EVENT_DEV = 16;
qDebug() << deviceNumber << deviceCount_ << maxDeviceCount_;
// No configuration for this device, try find the device from the device system path
while (deviceNumber < MAX_EVENT_DEV && deviceCount_ < maxDeviceCount_) {
deviceName = deviceSysPathString.arg(deviceNumber);
qDebug() << Q_FUNC_INFO << deviceName;
if (checkInputDevice(deviceName, typeName)) {
addPath(deviceName, deviceCount_);
++deviceCount_;
break;
}
++deviceNumber;
}
}
QString pollConfigKey = QString(typeName + "/poll_file");
if (SensorFrameworkConfig::configuration()->exists(pollConfigKey)) {
usedDevicePollFilePath_ = SensorFrameworkConfig::configuration()->value<QString>(pollConfigKey, "");
} else {
usedDevicePollFilePath_ = devicePollFilePath.arg(deviceNumber);
}
qDebug() << Q_FUNC_INFO << usedDevicePollFilePath_;
if (deviceCount_ == 0) {
sensordLogW() << "Cannot find any device for: " << typeName;
setValid(false);
} else {
QByteArray byteArray = readFromFile(usedDevicePollFilePath_.toLatin1());
cachedInterval_ = byteArray.size() > 0 ? byteArray.toInt() : 0;
}
return deviceCount_;
}
int InputDevAdaptor::getEvents(int fd)
{
int bytes = read(fd, evlist_, sizeof(struct input_event)*64);
if (bytes == -1) {
sensordLogW() << "Error occured: " << strerror(errno);
return 0;
}
if (bytes % sizeof(struct input_event)) {
sensordLogW() << "Short read or stray bytes.";
return 0;
}
return bytes/sizeof(struct input_event);
}
void InputDevAdaptor::processSample(int pathId, int fd)
{
int numEvents = getEvents(fd);
for (int i = 0; i < numEvents; ++i) {
switch (evlist_[i].type) {
case EV_SYN:
interpretSync(pathId, &(evlist_[i]));
break;
default:
interpretEvent(pathId, &(evlist_[i]));
break;
}
}
}
bool InputDevAdaptor::checkInputDevice(const QString& path, const QString& matchString, bool strictChecks) const
{
char deviceName[256] = {0,};
bool check = true;
qDebug() << Q_FUNC_INFO << path << matchString << strictChecks;
int fd = open(path.toLocal8Bit().constData(), O_RDONLY);
if (fd == -1) {
return false;
}
if (strictChecks) {
int result = ioctl(fd, EVIOCGNAME(sizeof(deviceName)), deviceName);
qDebug() << Q_FUNC_INFO << "open result:" << result << deviceName;
if (result == -1) {
sensordLogW() << "Could not read devicename for " << path;
check = false;
} else {
if (QString(deviceName).contains(matchString, Qt::CaseInsensitive)) {
sensordLogT() << "\"" << matchString << "\"" << " matched in device name: " << deviceName;
check = true;
} else {
check = false;
}
}
}
close(fd);
return check;
}
unsigned int InputDevAdaptor::interval() const
{
return cachedInterval_;
}
bool InputDevAdaptor::setInterval(const unsigned int value, const int sessionId)
{
Q_UNUSED(sessionId);
sensordLogD() << "Setting poll interval for " << deviceString_ << " to " << value;
QByteArray frequencyString(QString("%1\n").arg(value).toLocal8Bit());
if(writeToFile(usedDevicePollFilePath_.toLocal8Bit(), frequencyString))
{
cachedInterval_ = value;
return true;
}
return false;
}
void InputDevAdaptor::init()
{
qDebug() << Q_FUNC_INFO << name();
if (!getInputDevices(SensorFrameworkConfig::configuration()->value<QString>(name() + "/input_match", name()))) {
sensordLogW() << "Input device not found.";
SysfsAdaptor::init();
}
}
int InputDevAdaptor::getDeviceCount() const
{
return deviceCount_;
}