mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
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>
This commit is contained in:
parent
40d85b5d63
commit
6fe0388b96
2 changed files with 89 additions and 10 deletions
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <QtBluetooth/QBluetoothAddress>
|
#include <QtBluetooth/QBluetoothAddress>
|
||||||
#include <QLowEnergyController>
|
#include <QLowEnergyController>
|
||||||
|
#include <QLowEnergyService>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
|
|
@ -23,6 +24,8 @@
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
static int device_is_hw(dc_user_device_t *device);
|
||||||
|
|
||||||
void waitFor(int ms) {
|
void waitFor(int ms) {
|
||||||
Q_ASSERT(QCoreApplication::instance());
|
Q_ASSERT(QCoreApplication::instance());
|
||||||
Q_ASSERT(QThread::currentThread());
|
Q_ASSERT(QThread::currentThread());
|
||||||
|
|
@ -106,6 +109,11 @@ static int device_is_shearwater(dc_user_device_t *device)
|
||||||
return !strcmp(device->vendor, "Shearwater");
|
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)
|
dc_status_t BLEObject::write(const void *data, size_t size, size_t *actual)
|
||||||
{
|
{
|
||||||
Q_UNUSED(actual) // that seems like it might cause problems
|
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;
|
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)
|
dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *devaddr)
|
||||||
{
|
{
|
||||||
Q_UNUSED(context)
|
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()) {
|
if (!list.isEmpty()) {
|
||||||
const QLowEnergyCharacteristic &c = list.constLast();
|
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;
|
qDebug() << "Descriptor list with" << l.length() << "elements";
|
||||||
foreach(d, l)
|
|
||||||
qDebug() << "Descriptor:" << d.name() << "uuid:" << d.uuid().toString();
|
|
||||||
|
|
||||||
|
QLowEnergyDescriptor d;
|
||||||
|
foreach(d, l)
|
||||||
|
qDebug() << "Descriptor:" << d.name() << "uuid:" << d.uuid().toString();
|
||||||
|
|
||||||
if (!l.isEmpty()) {
|
if (!l.isEmpty()) {
|
||||||
d = l.first();
|
d = l.first();
|
||||||
qDebug() << "now writing \"0x0100\" to the first descriptor";
|
qDebug() << "now writing \"0x0100\" to the first descriptor";
|
||||||
|
|
||||||
ble->preferredService()->writeDescriptor(d, QByteArray::fromHex("0100"));
|
ble->preferredService()->writeDescriptor(d, QByteArray::fromHex("0100"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,11 @@
|
||||||
#include <QLowEnergyController>
|
#include <QLowEnergyController>
|
||||||
#include <QEventLoop>
|
#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
|
class BLEObject : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -25,14 +30,22 @@ public slots:
|
||||||
void serviceStateChanged(QLowEnergyService::ServiceState s);
|
void serviceStateChanged(QLowEnergyService::ServiceState s);
|
||||||
void characteristcStateChanged(const QLowEnergyCharacteristic &c, const QByteArray &value);
|
void characteristcStateChanged(const QLowEnergyCharacteristic &c, const QByteArray &value);
|
||||||
void writeCompleted(const QLowEnergyDescriptor &d, const QByteArray &value);
|
void writeCompleted(const QLowEnergyDescriptor &d, const QByteArray &value);
|
||||||
|
int setupHwTerminalIo(QList<QLowEnergyCharacteristic>);
|
||||||
private:
|
private:
|
||||||
QVector<QLowEnergyService *> services;
|
QVector<QLowEnergyService *> services;
|
||||||
|
|
||||||
QLowEnergyController *controller = nullptr;
|
QLowEnergyController *controller = nullptr;
|
||||||
QList<QByteArray> receivedPackets;
|
QList<QByteArray> receivedPackets;
|
||||||
QEventLoop waitForPacket;
|
QEventLoop waitForPacket;
|
||||||
|
bool isCharacteristicWritten;
|
||||||
dc_user_device_t *device;
|
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
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue