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