MQTToverBLE Demo is incapable of shutting down and restarting correctly

I placed a loop at the demo runner. As soon as it shuts down it starts right back up again.

Expect: is that the BLE and separately MQTToverBLE portion will shut down cleanly, and be able to reinit on a new BLE network connection.

Happens: is that while BLE portion remains connectable, the MQTT portion is broken and non-responsive entirely. After intentionally causing the demo to end, or a timeout, the loop starts, demoRunner starts over, the BLE GATT still works on next connection, but it seems that the semaphore for the network is never triggered a second time. YES, BLE works and the GATT callbacks are fine, but there seems to be a very unclear tie in to the Network and the Service.

Check for yourself: iot_demo_freertos.c LINE 273. (202007 tag / release branch) This semaphore is received/given only the the first run through. Connect, timeout (30S for MQTT to quit), then set a break point on LINE 277 and reconnect. You won’t trigger on that reconnect because the network or some layer doesn’t seem to know you are there.

To get effect: Either connect and wait for MQTT’s establishConnection to timeout, or write a “1” on UUID A9D7…30000. This is the proxy’s “GO” signal, it’ll fail because there is no proxy there, but it’s faster than waiting. The software SHOULD be able to recover from this as well.

Similar topic… I would strongly recommend separating BLE and MQTToverBLE !! I need BLE all the time, I need BLEoverMQTT only when the phone has conenction. Right now they are basically the same service as BLE won’t even enumerate it’s characteristics properly without calling MQTT’s _establishConnection(…). You have a system that could easily separate the definition of ble services/characterisitcs and their callbacks. Maybe just define the BLE service entirely separate from “business logic” side?

Thanks for providing the feedback.

Taking a look at the demo runner code, this looks to be a bug to me that the demoConnectedNetwork is not set to AWSIOT_NETWORK_TYPE_NONE upon disconnecting from all network after demo completes here.

The 30 seconds timeout was provided here because we wait for pairing to be complete to know ble connection is established, for which the timeout was 30 seconds. We will look into this part if the timeout can be avoided and this being handled in network layer.

With new demos and folder structure in our master branch the separation is more clear:

There is a BLE GATT server demo which provides an example of GATT server and talks to a GATT client with the corresponding GATT service client part implemented.
There is also other demo like mqtt_ble which depends on MQTT library and transport interface for BLE. This requires a custom GATT service implemented between device and our companion mobile SDK. More details are in README file provided.

Please let us know if you have further questions.

Ravi,

Appreciated. So looking at master, all the code seems to change with the upcoming CoreMQTT / LTS stuff being put in place. Thanks for finding the issue anyhow.

It looks like it’s going to be a big tear up on the next reference implementation release, but the code does look a lot better. I’ll see if I can get a minute to crawl through the BLE vs MQTT sections. It would be nice if your group could keep in mind that some of us will be using the BLE and custom services “offline” and only mqtt when in an “online” mode. EDIT: I see now that the MQTT characteristics will be included even if the MQTToverBLE processes aren’t running, that’s great, but I’m going to be looking for a clean way to be “offline” (ble only), and “online” (mqtt over ble) and turning that on and off.

I have high hopes for the LTS stuff, hope to see BLE added in sooner than later. You guys are going in the right direction.

EDIT: Well look at that! Exactly what I was hoping you would get. A list of the ble services that is compiled and initialized all at once! PERFECT. I’m very serious, the code quality has gone WAY up since the July release.

BTStatus_t _startGATTServices()
{
    BTStatus_t ret = eBTStatusSuccess;
    bool status = true;

    #if ( IOT_BLE_ENABLE_DEVICE_INFO_SERVICE == 1 )
        status = IotBleDeviceInfo_Init();
    #endif

    #if ( IOT_BLE_ENABLE_DATA_TRANSFER_SERVICE == 1 )
        if( status == true )
        {
            status = IotBleDataTransfer_Init();
        }
    #endif

    if( status == false )
    {
        ret = eBTStatusFail;
    }

    #if ( IOT_BLE_ADD_CUSTOM_SERVICES == 1 )
        IotBle_AddCustomServicesCb();
    #endif

    return ret;
}

EDIT2: For what it’s worth… With that snippet above, it’s a tiny bit weird that you aren’t getting a status return from void IotBle_AddCustomServicesCb() although you do from the basetype_t vGattDemoSvcHook() that it directly calls. Seems like you could get the return to this _startGATTServices() if you wanted to.

These are good feedback.

All the GATT services can be turned on or off by setting the appropriate config in iot_ble_config.h For example the MQTT uses the data transfer GATT service and it can be turned off if its completely offline mode by setting #define IOT_BLE_ENABLE_DATA_TRANSFER_SERVICE (0) . We will update the documentation to be more clear on that.

IotBle_AddCustomServicesCb can have a return value which can be propagated to the BLE where all gatt services are initialized. We will fix this in upcoming versions.