diff options
author | Jan Mulder <jlmulder@xs4all.nl> | 2017-07-03 19:24:39 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2017-07-04 23:46:07 +0900 |
commit | 6fe0388b966fe3a6d811f63a299896279864d8e7 (patch) | |
tree | 29ea4fc55149786aabefc95956ffafc5b8d4c561 /core | |
parent | 40d85b5d633568a76c570d01d0ca00463e060c23 (diff) | |
download | subsurface-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>
Diffstat (limited to 'core')
-rw-r--r-- | core/qt-ble.cpp | 84 | ||||
-rw-r--r-- | core/qt-ble.h | 15 |
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 + }; }; |