0

I'm currently using qt for a project. I want to advertise the result of an asynchronous calculation via bluetooth advertisement.

I'm setting up an advertisier like in a BluetoothAdvertisingClass like this

void BLEServer::startAdvertising(QString string){
    advertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral);
    advertisingData.setIncludePowerLevel(true);
    advertisingData.setLocalName("Server");
    advertisingData.setServices(QList<QBluetoothUuid>() << QBluetoothUuid::HeartRate);
    advertisingData.setManufacturerData(manufacturereID,buildDataPackage(string));

    QLowEnergyCharacteristicData charData;
    charData.setUuid(QBluetoothUuid::HeartRateMeasurement);
    charData.setValue(QByteArray(2, 0));
    charData.setProperties(QLowEnergyCharacteristic::Notify);
    const QLowEnergyDescriptorData clientConfig(QBluetoothUuid::ClientCharacteristicConfiguration,
                                                QByteArray(2, 0));
    charData.addDescriptor(clientConfig);

    QLowEnergyServiceData serviceData;
    serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
    serviceData.setUuid(QBluetoothUuid::HeartRate);
    serviceData.addCharacteristic(charData);

    leController = QSharedPointer<QLowEnergyController>(QLowEnergyController::createPeripheral());
    QScopedPointer<QLowEnergyService> service(leController->addService(serviceData));
    advertisingParameters  = QLowEnergyAdvertisingParameters();
    advertisingParameters.setMode(QLowEnergyAdvertisingParameters::AdvNonConnInd);

    leController->startAdvertising(advertisingParameters, advertisingData, advertisingData);

}

I have the variable leControler, advertisngData and manufatcurer id defind as following in the BLESErver.h file

QSharedPointer<QLowEnergyController> leController;
QLowEnergyAdvertisingData advertisingData;
int manufacturereID = 1775;

and the function to build the dataPackage as ByteArray is definde as this

QByteArray BLEHServer::buildDataPackage(QString string){
    QByteArray stringArray = string.toLocal8Bit();
    return stringArray;
}

The problem is that i want to change the advertised value rather frequently and i'm not really sure how to do that correctly or if that was even intend by advertising.

Currently i'm just starting an new advertiser and stoping the old one, but i guess thats not how it is intended. It looks like this:

void BLEServer::changeAdvertisingData(QString string){
    try {

        //Stopping Advertising and creating a new Controller
        leController->stopAdvertising();
        leController = QSharedPointer<QLowEnergyController>(QLowEnergyController::createPeripheral());
        //Create new Advertising Data and swapping it with the old ones
        QLowEnergyAdvertisingData newAdvertisingData;
        newAdvertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral);
        newAdvertisingData.setIncludePowerLevel(true);
        newAdvertisingData.setLocalName("Anki");
        newAdvertisingData.setServices(QList<QBluetoothUuid>() << QBluetoothUuid::HeartRate);
        newAdvertisingData.setManufacturerData(manufacturereID,buildDataPackage(string));
        advertisingData.swap(newAdvertisingData);

        //Start to advertise new Data
        leController->startAdvertising(advertisingParameters, advertisingData, advertisingData);
    } catch (QException e){
        throw(e);
    }
}

This stopping and restarting leads to touble when i do this rather frequently what sometimes could happen.

Is there a bettter way to do it?

Renji
  • 310
  • 3
  • 13

1 Answers1

1

Instead of starting/stopping the advertisement, you should save a reference to the QBluetoothService object (in your code it's the heart-rate service), and update the data of the service-class. The advertisements will automatically pick up the new values when the next advertisement package is due.

Alternatively, if you are programming sender and receiver, you can use the setRawData() function to set arbitrary 31-byte data for the packets.

markus-nm
  • 805
  • 5
  • 8
  • Thank you markus, i tried that before but it didn't work, altho the way i tested is was with a phone bluetooth app, which maybe didn't update right. I'll try it as soon as i can and inform of this helped me or not – Renji Dec 21 '18 at 18:56
  • The way you mentioned either does not seem to work or i might be doing it wrong. When editing the service i can only change the value of the service but in my case i need to change the value of the advertisingData. If i'm doing it wrong would you care to give a more precise example @markus-nm? – Renji Jan 10 '19 at 15:10
  • Use "Bluetooth Low Energy Heart Rate Server Example" to see how heart beat data is updated. https://doc.qt.io/qt-5/qtbluetooth-heartrate-server-example.html – Ed of the Mountain Jun 09 '20 at 13:09