aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorGravatar Jan Mulder <jlmulder@xs4all.nl>2017-07-05 18:37:21 +0200
committerGravatar Jan Mulder <jlmulder@xs4all.nl>2017-07-11 13:17:00 +0200
commitb7057c414fc43bb81fc0d01bc07f32d18bce8ab0 (patch)
tree820eb498d61c6e315d68e52f8e909a9ac227d72f /core
parentd233725519ca08d1d0e25c63550c44963dc2c093 (diff)
downloadsubsurface-b7057c414fc43bb81fc0d01bc07f32d18bce8ab0.tar.gz
OSTC over BLE: take care of credits
Handle credits. Do not just ask for maximum credits all the time as this will stop the download. Also do not let the credits go back to 0 (while this might work, this is not tested). Getting back the 0 credits stops the download, and even when it can be restarted, it is less efficient (and not needed). Notice also that it takes some time before a grant request is honoured. During testing I saw reception of up to 25 packets between request and grant. So a lower bound for the request of 32 packets seems resonable. One aspect the Telit/Stollmann TIO puzzeled me. Sections 4.1 and 4.2 both talk about credits, but my hyphothesis is that there are two credits counters in play. One for traffic either way. This commit only deals with credits granted by Subsurface to the OSTC to send data. Credits granted by the OSTC to allow Subsurface to send new commands is NOT part of this commit, and is seemingly not needed in our scenario. As we only send new commands to the OSTC when a previous one is finished (per HW's interface spec), the OSTC does not run out of credits to receive commands. Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
Diffstat (limited to 'core')
-rw-r--r--core/qt-ble.cpp66
-rw-r--r--core/qt-ble.h2
2 files changed, 43 insertions, 25 deletions
diff --git a/core/qt-ble.cpp b/core/qt-ble.cpp
index 0ce52bc02..7afdf484b 100644
--- a/core/qt-ble.cpp
+++ b/core/qt-ble.cpp
@@ -30,6 +30,9 @@ static int debugCounter;
#define IS_EON_STEEL(_d) same_string((_d)->product, "EON Steel")
#define IS_G2(_d) same_string((_d)->product, "G2")
+#define MAXIMAL_HW_CREDIT 255
+#define MINIMAL_HW_CREDIT 32
+
extern "C" {
void waitFor(int ms) {
@@ -65,21 +68,24 @@ void BLEObject::characteristcStateChanged(const QLowEnergyCharacteristic &c, con
{
if (IS_HW(device)) {
if (c.uuid() == hwAllCharacteristics[HW_OSTC_BLE_DATA_TX]) {
+ hw_credit--;
receivedPackets.append(value);
+ if (hw_credit == MINIMAL_HW_CREDIT)
+ setHwCredit(MAXIMAL_HW_CREDIT - hw_credit);
} else {
qDebug() << "ignore packet from" << c.uuid() << value.toHex();
}
} else {
receivedPackets.append(value);
}
- //qDebug() << ".. incoming packet count" << receivedPackets.length();
}
void BLEObject::characteristicWritten(const QLowEnergyCharacteristic &c, const QByteArray &value)
{
if (IS_HW(device)) {
if (c.uuid() == hwAllCharacteristics[HW_OSTC_BLE_CREDITS_RX]) {
- qDebug() << "HW_OSTC_BLE_CREDITS_RX confirmed" << c.uuid() << value.toHex();
+ bool ok;
+ hw_credit += value.toHex().toInt(&ok, 16);
isCharacteristicWritten = true;
}
} else {
@@ -90,8 +96,6 @@ void BLEObject::characteristicWritten(const QLowEnergyCharacteristic &c, const Q
void BLEObject::writeCompleted(const QLowEnergyDescriptor &d, const QByteArray &value)
{
- Q_UNUSED(value)
-
qDebug() << "BLE write completed on" << d.name() << d.value();
}
@@ -188,7 +192,7 @@ dc_status_t BLEObject::read(void *data, size_t size, size_t *actual)
int offset = 0;
while (!receivedPackets.isEmpty()) {
/*
- * Yes, to while loops with same condition seems strange. The inner one
+ * Yes, two while loops with same condition seems strange. The inner one
* does the real work, but it prevents the QtEventloop to do its thing.
* As the incoming packets arrive based on signals and slots, that
* stuff is not handeled during the inner loop. So, add a short waitFor
@@ -220,6 +224,36 @@ we_are_done:
return DC_STATUS_SUCCESS;
}
+dc_status_t BLEObject::setHwCredit(unsigned int c)
+{
+ /* 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.
+ *
+ * Futher notice that this function has the implicit effect of processing the
+ * event loop (due to waiting for the confirmation of the credit request).
+ * So, as characteristcStateChanged will be triggered, while receiving
+ * data from the OSTC, these are processed too.
+ */
+
+ QList<QLowEnergyCharacteristic> list = preferredService()->characteristics();
+ isCharacteristicWritten = false;
+ preferredService()->writeCharacteristic(list[HW_OSTC_BLE_CREDITS_RX],
+ QByteArray(1, c),
+ QLowEnergyService::WriteWithResponse);
+
+ /* And wait for the answer*/
+ int msec = BLE_TIMEOUT;
+ while (msec > 0 && !isCharacteristicWritten) {
+ waitFor(100);
+ msec -= 100;
+ };
+ if (!isCharacteristicWritten)
+ return DC_STATUS_TIMEOUT;
+ return DC_STATUS_SUCCESS;
+}
+
dc_status_t 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
@@ -252,26 +286,8 @@ dc_status_t BLEObject::setupHwTerminalIo(QList<QLowEnergyCharacteristic> allC)
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 = BLE_TIMEOUT;
- while (msec > 0 && !isCharacteristicWritten) {
- waitFor(100);
- msec -= 100;
- };
- if (!isCharacteristicWritten)
- return DC_STATUS_TIMEOUT;
-
- return DC_STATUS_SUCCESS;
+ /* The Terminal I/O client transmits initial UART credits to the server (see 6.5). */
+ return setHwCredit(MAXIMAL_HW_CREDIT);
}
dc_status_t qt_ble_open(dc_custom_io_t *io, dc_context_t *context, const char *devaddr)
diff --git a/core/qt-ble.h b/core/qt-ble.h
index 7368b71cd..ad5dfda2b 100644
--- a/core/qt-ble.h
+++ b/core/qt-ble.h
@@ -32,6 +32,7 @@ public slots:
void characteristicWritten(const QLowEnergyCharacteristic &c, const QByteArray &value);
void writeCompleted(const QLowEnergyDescriptor &d, const QByteArray &value);
dc_status_t setupHwTerminalIo(QList<QLowEnergyCharacteristic>);
+ dc_status_t setHwCredit(unsigned int c);
private:
QVector<QLowEnergyService *> services;
@@ -39,6 +40,7 @@ private:
QList<QByteArray> receivedPackets;
bool isCharacteristicWritten;
dc_user_device_t *device;
+ unsigned int hw_credit = 0;
QList<QUuid> hwAllCharacteristics = {
"{00000001-0000-1000-8000-008025000000}", // HW_OSTC_BLE_DATA_RX