QLowEnergyController disconnectFromDevice not working
-
Hi All,
I am implementing a Qt app on Windows 10 to communicate with an embedded system over BLE (peripheral device), using the Qt Bluetooth Low Energy API. My app is central role. I am using Qt 5.15.2 MinGW 64-bit. I can successfully discover my embedded peripheral device, connect to it, discover services and details (characteristics and properties) and can send and receive data to/from the device successfully via its characteristics. The only problem is it seems that disconnecting from the peripheral device via the QLowEnergyController::disconnectFromDevice() API does not work. I enable notifications for the peripheral device's Tx characteristic to be notified when data is received. Before attempting to disconnect from the device, I disable the notifications (and wait for its notification via QLowEnergyService::descriptorWritten). The peripheral device has a debug port and I can see the notification being disabled successfully. However, calling disconnectFromDevice() after that does not seem to have any effect. In this state I cannot connect to the device again. However, if I close the App, the connection to the device is broken (I can see this via the device debug port) and then I can make a new connection to the device when running the App again. Below are some code snippets. I would greatly appreciate it if someone can shed some light on this problem and maybe suggest on how to fix it. Thank you very much in advance. Regards.// Service details had been discovered. connect( periphService, &QLowEnergyService::characteristicChanged, this, &btDevice::charateristicChanged ); connect( periphService, &QLowEnergyService::descriptorWritten, this, &btDevice::descriptorWritten ); // Enable notifications for Tx characteristic if ( ch.isValid() ) { // Valid Tx characteristic QLowEnergyDescriptor desc = ch.descriptor( QBluetoothUuid::ClientCharacteristicConfiguration ); if ( desc.isValid() ) { if ( ch.properties() & QLowEnergyCharacteristic::Notify ) { // Enable notifications periphService->writeDescriptor( desc, QByteArray::fromHex( "0100" ) ); } } } //... // Data transferred between app (central) and peripheral. About to disconnect... //.. // Public method to disconnect after data transfer done. void btDevice::disconnectFromDevice() { if ( leController->state() != QLowEnergyController::UnconnectedState ) { // Disable notifications. The actual disconnect is done when the // descriptorWritten slot is invoked. periphService->writeDescriptor( desc, QByteArray::fromHex( "0000" ) ); } } void btDevice::descriptorWritten( const QLowEnergyDescriptor & desc, const QByteArray & value ) { if ( desc == descTxCharacteristic ) { QString valueStr = QString( value.toHex() ); if ( valueStr == "0000" ) { // Notifications disabled. On the peripheral device // debug port I can see this was successful. Now disconnect. // This disconnect does not seem to have any effect on the // peripheral device. leController->disconnectFromDevice(); QString stateStr = QVariant::fromValue( leController->state() ).toString(); qDebug() << "LE Controller State:" << stateStr; // The debug output from the above 2 lines show: // LE Controller State: "UnconnectedState" } } }
-
Hi All,
I am implementing a Qt app on Windows 10 to communicate with an embedded system over BLE (peripheral device), using the Qt Bluetooth Low Energy API. My app is central role. I am using Qt 5.15.2 MinGW 64-bit. I can successfully discover my embedded peripheral device, connect to it, discover services and details (characteristics and properties) and can send and receive data to/from the device successfully via its characteristics. The only problem is it seems that disconnecting from the peripheral device via the QLowEnergyController::disconnectFromDevice() API does not work. I enable notifications for the peripheral device's Tx characteristic to be notified when data is received. Before attempting to disconnect from the device, I disable the notifications (and wait for its notification via QLowEnergyService::descriptorWritten). The peripheral device has a debug port and I can see the notification being disabled successfully. However, calling disconnectFromDevice() after that does not seem to have any effect. In this state I cannot connect to the device again. However, if I close the App, the connection to the device is broken (I can see this via the device debug port) and then I can make a new connection to the device when running the App again. Below are some code snippets. I would greatly appreciate it if someone can shed some light on this problem and maybe suggest on how to fix it. Thank you very much in advance. Regards.// Service details had been discovered. connect( periphService, &QLowEnergyService::characteristicChanged, this, &btDevice::charateristicChanged ); connect( periphService, &QLowEnergyService::descriptorWritten, this, &btDevice::descriptorWritten ); // Enable notifications for Tx characteristic if ( ch.isValid() ) { // Valid Tx characteristic QLowEnergyDescriptor desc = ch.descriptor( QBluetoothUuid::ClientCharacteristicConfiguration ); if ( desc.isValid() ) { if ( ch.properties() & QLowEnergyCharacteristic::Notify ) { // Enable notifications periphService->writeDescriptor( desc, QByteArray::fromHex( "0100" ) ); } } } //... // Data transferred between app (central) and peripheral. About to disconnect... //.. // Public method to disconnect after data transfer done. void btDevice::disconnectFromDevice() { if ( leController->state() != QLowEnergyController::UnconnectedState ) { // Disable notifications. The actual disconnect is done when the // descriptorWritten slot is invoked. periphService->writeDescriptor( desc, QByteArray::fromHex( "0000" ) ); } } void btDevice::descriptorWritten( const QLowEnergyDescriptor & desc, const QByteArray & value ) { if ( desc == descTxCharacteristic ) { QString valueStr = QString( value.toHex() ); if ( valueStr == "0000" ) { // Notifications disabled. On the peripheral device // debug port I can see this was successful. Now disconnect. // This disconnect does not seem to have any effect on the // peripheral device. leController->disconnectFromDevice(); QString stateStr = QVariant::fromValue( leController->state() ).toString(); qDebug() << "LE Controller State:" << stateStr; // The debug output from the above 2 lines show: // LE Controller State: "UnconnectedState" } } }