Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt Bluetooth reconnection problem



  • Hello,
    I am developing a bluetooth service with two characteristics: one to let other devices read a list of MAC address and the other to write a command for the program.
    Everything is working fine, the only problem is that when I disconnect from the main service and then I reconnect to it, I can see the two services but I can't read or write.
    This is the code:

    static const QLatin1String serviceUuid("11223344-5566-7788-99aa-bbccddeeff00");
        static const QLatin1String readListUuid("11223344-5566-7788-99aa-bbccddeeff11");
        static const QLatin1String writeListUuid("11223344-5566-7788-99aa-bbccddeeff12");
    
        // [Advertising Data]
            QLowEnergyAdvertisingData advertisingData;
            advertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral);
            advertisingData.setIncludePowerLevel(true);
            advertisingData.setLocalName("BOX");
            advertisingData.setServices(QList<QBluetoothUuid>() << QBluetoothUuid(serviceUuid));
    
        // [Service Data]
            QLowEnergyCharacteristicData readList,writeList;
    
            readList.setUuid(QBluetoothUuid(readListUuid));
            readList.setProperties(QLowEnergyCharacteristic::Read);
    
            writeList.setUuid(QBluetoothUuid(writeListUuid));
            writeList.setProperties(QLowEnergyCharacteristic::Write);
    
            const QLowEnergyDescriptorData clientConfig(QBluetoothUuid::CharacteristicUserDescription,QByteArray(2, 0));
            readList.addDescriptor(clientConfig);
            writeList.addDescriptor(clientConfig);
    
            QLowEnergyServiceData serviceData;
            serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
            serviceData.setUuid(QBluetoothUuid(serviceUuid));
            serviceData.addCharacteristic(readList);
            serviceData.addCharacteristic(writeList);
    
    
        // [Start Advertising]
    
            leController.reset(QLowEnergyController::createPeripheral());
            service_list.reset(leController->addService(serviceData));
            leController->startAdvertising(QLowEnergyAdvertisingParameters(), advertisingData,advertisingData);
    
    
    
        qCDebug(BLELog) << " Start BLE backend [...] ";
    
        ConnectionHandler connectionHandler;
        DeviceHandler m_deviceHandler;
    
    
        // TODO! Restore debug options.
        GenericDeviceIf::start(debugMode, protocolDebug);
    
        // Initialize reachable state to unreachable.
        DataModel::getInstance()->setDeviceCategoryReachable(_category, false);
    
        _endpoints = DataModel::getInstance() ->getEndpointsListByCategory(dataBaseClasses::ENDPOINT_CATEGORY_BLE);
    
        m_deviceHandler.setDevice(nullptr);
        qDeleteAll(devices);
        devices.clear();
    
        emit devicesChanged();
    
        qCDebug(BLELog) << "Scanning for devices...";
    
        discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
    
        emit scanningChanged();
    
        // [Retrieving the list of devices]
    
            QLowEnergyCharacteristic characteristic = service_list->characteristic(QBluetoothUuid(readListUuid));
            QString sep = "\n";
            for (const auto &e: _endpoints){
                L.append(QString(e->getName()).toUtf8());
                L.append(QString("\t").toUtf8());
                L.append(QString(e->getMapping()).toUtf8());
                L.append(QString(sep.toUtf8()));
            }
            L.resize(L.size()-1);
    
            if (L.isEmpty())
                qCDebug(BLELog) << "No endpoints loaded in the list";
            else
                service_list -> writeCharacteristic(characteristic, L) ;
    
    
       // [Reconnect to the service when it disconnects]
            auto reconnect = [this , serviceData, advertisingData]()
            {
                service_list.reset(leController->addService(serviceData));
                if (!service_list.isNull()) {
                    leController->startAdvertising(QLowEnergyAdvertisingParameters(), advertisingData, advertisingData);
                }
            };
    
            auto getCommand = [this, serviceData, advertisingData]()
            {
                command = service_list->characteristic(QBluetoothUuid(writeListUuid)).value();
                qCDebug(BLELog) << command;
            };
    
            QObject::connect(leController.data(), &QLowEnergyController::disconnected, reconnect);
            QObject::connect(service_list.get() , &QLowEnergyService::characteristicChanged, getCommand);
    

    In the header file service_list and leController are defined as follow:

    QScopedPointer<QLowEnergyController> leController;
    QScopedPointer<QLowEnergyService> service_list;
    

    I based my code following the heart rate server example.


Log in to reply