summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Jan Mulder <jlmulder@xs4all.nl>2017-07-03 19:24:39 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2017-07-04 23:46:07 +0900
commit6fe0388b966fe3a6d811f63a299896279864d8e7 (patch)
tree29ea4fc55149786aabefc95956ffafc5b8d4c561
parent40d85b5d633568a76c570d01d0ca00463e060c23 (diff)
downloadsubsurface-6fe0388b966fe3a6d811f63a299896279864d8e7.tar.gz
OSTC over BLE: initialize Terminal I/O client
This initalizes the Terminal I/O client as described in paragraph 3 of http://www.telit.com/fileadmin/user_upload/products/Downloads/sr-rf/BlueMod/TIO_Implementation_Guide_r04.pdf This is for all Heinrichs Weikamp computers, that use referenced BT/BLE hardware module from Telit Wireless Solutions (Formerly Stollmann E+V GmbH). The 16 bit UUID 0xFEFB (or a derived 128 bit UUID starting with 0x0000FEFB is a clear indication that the OSTC is equipped with this BT/BLE hardware. Furthermore, most devices equipped with this BT/BLE hardware have BT addresses starting with 00:80:25:... Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
-rw-r--r--core/qt-ble.cpp84
-rw-r--r--core/qt-ble.h15
2 files changed, 89 insertions, 10 deletions
diff --git a/core/qt-ble.cpp b/core/qt-ble.cpp
index 5cf7f1f5d..197c2ddca 100644
--- a/core/qt-ble.cpp
+++ b/core/qt-ble.cpp
@@ -3,6 +3,7 @@
#include <QtBluetooth/QBluetoothAddress>
#include <QLowEnergyController>
+#include <QLowEnergyService>
#include <QCoreApplication>
#include <QElapsedTimer>
#include <QEventLoop>
@@ -23,6 +24,8 @@
extern "C" {
+static int device_is_hw(dc_user_device_t *device);
+
void waitFor(int ms) {
Q_ASSERT(QCoreApplication::instance());
Q_ASSERT(QThread::currentThread());
@@ -106,6 +109,11 @@ static int device_is_shearwater(dc_user_device_t *device)
return !strcmp(device->vendor, "Shearwater");
}
+static int device_is_hw(dc_user_device_t *device)
+{
+ return !strcmp(device->vendor, "Heinrichs Weikamp");
+}
+
dc_status_t BLEObject::write(const void *data, size_t size, size_t *actual)
{
Q_UNUSED(actual) // that seems like it might cause problems
@@ -163,6 +171,60 @@ dc_status_t BLEObject::read(void *data, size_t size, size_t *actual)
return DC_STATUS_SUCCESS;
}
+int BLEObject::setupHwTerminalIo(QList<QLowEnergyCharacteristic> allC)
+{ /* This initalizes the Terminal I/O client as described in
+ * http://www.telit.com/fileadmin/user_upload/products/Downloads/sr-rf/BlueMod/TIO_Implementation_Guide_r04.pdf
+ * Referenced section numbers below are from that document.
+ *
+ * This is for all HW computers, that use referenced BT/BLE hardware module from Telit
+ * (formerly Stollmann). The 16 bit UUID 0xFEFB (or a derived 128 bit UUID starting with
+ * 0x0000FEFB is a clear indication that the OSTC is equipped with this BT/BLE hardware.
+ */
+
+ if (allC.length() != 4) {
+ qDebug() << "This should not happen. HW/OSTC BT/BLE device without 4 Characteristics";
+ return DC_STATUS_IO;
+ }
+
+ /* The Terminal I/O client subscribes to indications of the UART credits TX
+ * characteristic (see 6.4).
+ *
+ * Notice that indications are subscribed to by writing 0x0200 to its descriptor. This
+ * can be understood by looking for Client Characteristic Configuration, Assigned
+ * Number: 0x2902. Enabling/Disabeling is setting the proper bit, and they
+ * differ for indications and notifications.
+ */
+ QLowEnergyDescriptor d = allC[HW_OSTC_BLE_CREDITS_TX].descriptors().first();
+ preferredService()->writeDescriptor(d, QByteArray::fromHex("0200"));
+
+ /* The Terminal I/O client subscribes to notifications of the UART data TX
+ * characteristic (see 6.2).
+ */
+ d = allC[HW_OSTC_BLE_DATA_TX].descriptors().first();
+ preferredService()->writeDescriptor(d, QByteArray::fromHex("0100"));
+
+ /* The Terminal I/O client transmits initial UART credits to the server (see 6.5).
+ *
+ * Notice that we have to write to the characteristic here, and not to its
+ * descriptor as for the enabeling of notifications or indications.
+ */
+ isCharacteristicWritten = false;
+ preferredService()->writeCharacteristic(allC[HW_OSTC_BLE_CREDITS_RX],
+ QByteArray(1, 255),
+ QLowEnergyService::WriteWithResponse);
+
+ /* And give to OSTC some time to get initialized */
+ int msec = 5000;
+ while (msec > 0 && !isCharacteristicWritten) {
+ waitFor(100);
+ msec -= 100;
+ };
+ if (!isCharacteristicWritten)
+ return DC_STATUS_TIMEOUT;
+
+ return DC_STATUS_SUCCESS;
+}
+
dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *devaddr)
{
Q_UNUSED(context)
@@ -256,20 +318,24 @@ dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *d
if (!list.isEmpty()) {
const QLowEnergyCharacteristic &c = list.constLast();
- QList<QLowEnergyDescriptor> l = c.descriptors();
- qDebug() << "Descriptor list with" << l.length() << "elements";
+ if (device_is_hw(io->user_device)) {
+ ble->setupHwTerminalIo(list);
+ } else {
+ QList<QLowEnergyDescriptor> l = c.descriptors();
- QLowEnergyDescriptor d;
- foreach(d, l)
- qDebug() << "Descriptor:" << d.name() << "uuid:" << d.uuid().toString();
+ qDebug() << "Descriptor list with" << l.length() << "elements";
+ QLowEnergyDescriptor d;
+ foreach(d, l)
+ qDebug() << "Descriptor:" << d.name() << "uuid:" << d.uuid().toString();
- if (!l.isEmpty()) {
- d = l.first();
- qDebug() << "now writing \"0x0100\" to the first descriptor";
+ if (!l.isEmpty()) {
+ d = l.first();
+ qDebug() << "now writing \"0x0100\" to the first descriptor";
- ble->preferredService()->writeDescriptor(d, QByteArray::fromHex("0100"));
+ ble->preferredService()->writeDescriptor(d, QByteArray::fromHex("0100"));
+ }
}
}
diff --git a/core/qt-ble.h b/core/qt-ble.h
index 247f7d64c..34c726bb2 100644
--- a/core/qt-ble.h
+++ b/core/qt-ble.h
@@ -6,6 +6,11 @@
#include <QLowEnergyController>
#include <QEventLoop>
+#define HW_OSTC_BLE_DATA_RX 0
+#define HW_OSTC_BLE_DATA_TX 1
+#define HW_OSTC_BLE_CREDITS_RX 2
+#define HW_OSTC_BLE_CREDITS_TX 3
+
class BLEObject : public QObject
{
Q_OBJECT
@@ -25,14 +30,22 @@ public slots:
void serviceStateChanged(QLowEnergyService::ServiceState s);
void characteristcStateChanged(const QLowEnergyCharacteristic &c, const QByteArray &value);
void writeCompleted(const QLowEnergyDescriptor &d, const QByteArray &value);
-
+ int setupHwTerminalIo(QList<QLowEnergyCharacteristic>);
private:
QVector<QLowEnergyService *> services;
QLowEnergyController *controller = nullptr;
QList<QByteArray> receivedPackets;
QEventLoop waitForPacket;
+ bool isCharacteristicWritten;
dc_user_device_t *device;
+
+ QList<QUuid> hwAllCharacteristics = {
+ "{00000001-0000-1000-8000-008025000000}", // HW_OSTC_BLE_DATA_RX
+ "{00000002-0000-1000-8000-008025000000}", // HW_OSTC_BLE_DATA_TX
+ "{00000003-0000-1000-8000-008025000000}", // HW_OSTC_BLE_CREDITS_RX
+ "{00000004-0000-1000-8000-008025000000}" // HW_OSTC_BLE_CREDITS_TX
+ };
};