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?
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.