summaryrefslogtreecommitdiffstats
path: root/src/plugins/sensors/blackberry/bbsensorbackend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/sensors/blackberry/bbsensorbackend.cpp')
-rw-r--r--src/plugins/sensors/blackberry/bbsensorbackend.cpp175
1 files changed, 175 insertions, 0 deletions
diff --git a/src/plugins/sensors/blackberry/bbsensorbackend.cpp b/src/plugins/sensors/blackberry/bbsensorbackend.cpp
new file mode 100644
index 00000000..e659ee87
--- /dev/null
+++ b/src/plugins/sensors/blackberry/bbsensorbackend.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Research In Motion
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtSensors module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bbsensorbackend.h"
+
+#include <QtCore/QDebug>
+#include <fcntl.h>
+
+static const int microSecondsPerSecond = 1000 * 1000;
+
+static int microSecondsToHertz(uint microSeconds)
+{
+ return microSecondsPerSecond / microSeconds;
+}
+
+static uint hertzToMicroSeconds(int hertz)
+{
+ return microSecondsPerSecond / hertz;
+}
+
+BbSensorBackendBase::BbSensorBackendBase(const QString &devicePath, sensor_type_e sensorType,
+ QSensor *sensor)
+ : QSensorBackend(sensor), m_deviceFile(devicePath), m_sensorType(sensorType)
+{
+}
+
+QFile &BbSensorBackendBase::deviceFile()
+{
+ return m_deviceFile;
+}
+
+sensor_type_e BbSensorBackendBase::sensorType() const
+{
+ return m_sensorType;
+}
+
+void BbSensorBackendBase::initSensorInfo()
+{
+ if (!m_deviceFile.open(QFile::ReadOnly)) {
+ qDebug() << "initSensorInfo(): Failed to open" << m_deviceFile.fileName()
+ << ":" << m_deviceFile.errorString();
+ } else {
+ sensor_devctl_info_u deviceInfo;
+ const int result = devctl(m_deviceFile.handle(), DCMD_SENSOR_INFO, &deviceInfo,
+ sizeof(deviceInfo), NULL);
+ if (result != EOK) {
+ perror(QString::fromLatin1("Querying sensor info for %1 failed")
+ .arg(m_deviceFile.fileName()).toLocal8Bit());
+ } else {
+ if (addDefaultRange()) {
+ addOutputRange(convertValue(deviceInfo.rx.info.range_min),
+ convertValue(deviceInfo.rx.info.range_max),
+ convertValue(deviceInfo.rx.info.resolution));
+ }
+
+ // Min and max intentionally swapped here, as the minimum delay is the maximum rate
+ addDataRate(microSecondsToHertz(deviceInfo.rx.info.delay_max),
+ microSecondsToHertz(deviceInfo.rx.info.delay_min));
+ }
+ additionalDeviceInit();
+ m_deviceFile.close();
+ }
+}
+
+void BbSensorBackendBase::additionalDeviceInit()
+{
+}
+
+bool BbSensorBackendBase::addDefaultRange()
+{
+ return true;
+}
+
+qreal BbSensorBackendBase::convertValue(float bbValue)
+{
+ return bbValue;
+}
+
+void BbSensorBackendBase::start()
+{
+ if (!m_deviceFile.open(QFile::ReadOnly | QFile::Unbuffered)) {
+ qDebug() << "Starting sensor" << m_deviceFile.fileName()
+ << "failed:" << m_deviceFile.errorString();
+ sensorError(m_deviceFile.error());
+ return;
+ }
+
+ const int rateInHertz = sensor()->dataRate();
+ if (rateInHertz != 0) {
+ const uint rateInMicroseconds = hertzToMicroSeconds(rateInHertz);
+ sensor_devctl_rate_u deviceRate;
+ deviceRate.tx.rate = rateInMicroseconds;
+ const int result = devctl(m_deviceFile.handle(), DCMD_SENSOR_RATE, &deviceRate,
+ sizeof(deviceRate), NULL);
+ if (result != EOK) {
+ perror(QString::fromLatin1("Setting sensor rate for %1 failed")
+ .arg(m_deviceFile.fileName()).toLocal8Bit());
+ }
+ }
+
+ // Explicitly switch to non-blocking mode, otherwise read() will wait until new sensor
+ // data is available, and we have no way to check if there is more data or not (bytesAvailable()
+ // does not work for unbuffered mode)
+ const int oldFlags = fcntl(m_deviceFile.handle(), F_GETFL);
+ if (fcntl(m_deviceFile.handle(), F_SETFL, oldFlags | O_NONBLOCK) == -1) {
+ perror(QString::fromLatin1("Starting sensor %1 failed, fcntl() returned -1")
+ .arg(m_deviceFile.fileName()).toLocal8Bit());
+ sensorError(errno);
+ stop();
+ return;
+ }
+
+ m_socketNotifier.reset(new QSocketNotifier(m_deviceFile.handle(), QSocketNotifier::Read));
+ connect(m_socketNotifier.data(), SIGNAL(activated(int)), this, SLOT(dataAvailable()));
+}
+
+void BbSensorBackendBase::stop()
+{
+ m_socketNotifier.reset();
+ m_deviceFile.close();
+}
+
+void BbSensorBackendBase::dataAvailable()
+{
+ Q_FOREVER {
+ sensor_event_t event;
+ const qint64 numBytes = m_deviceFile.read(reinterpret_cast<char *>(&event),
+ sizeof(sensor_event_t));
+ if (numBytes == -1) {
+ break;
+ } else if (numBytes == sizeof(sensor_event_t)) {
+ processEvent(event);
+ } else {
+ qDebug() << "Reading sensor event data for" << m_deviceFile.fileName()
+ << "failed (unexpected data size):" << m_deviceFile.errorString();
+ }
+ }
+}