Reputation: 153
Updated:
Qt Version : 5.11
Platform : Raspberry pi 3
Operating System : Rasbpian
I am connecting my linux Qt BLE app to IOS central device. It works fine for the most part but sometimes it crashes with following error
qt.bluetooth.bluez: void QBluetoothSocketPrivate::_q_readNotify() 29 error: -1 "Resource temporarily unavailable"
Here is the code and underlying scenario.
I have a raspberrypi that is running Qt 5.11 and I have created a BLE low energy peripheral device that connects to IOS app and sends and receives data.
Declarations :
QLowEnergyCharacteristicData ReadCharacteristicData,
WriteCharactersiticData,
ConnectivityData,
TrackerData_Data;
QLowEnergyCharacteristic charas;
QLowEnergyDescriptorData ReadCharacteristicDesc,
WriteCharactersiticDesc,
ConnectivityDesc,
TrackerDesc;
QLowEnergyServiceData serviceData;
QScopedPointer<QLowEnergyController> leController;
QScopedPointer<QLowEnergyService> service;
Service Initialization :`
Here I am initializing bluetooth service
//! [Advertising Data]
advertisingData.setDiscoverability(QLowEnergyAdvertisingData::DiscoverabilityGeneral);
advertisingData.setLocalName("Atlas360Dev");
advertisingData.setServices(QList<QBluetoothUuid>()<<QBluetoothUuid::Atlas);
// For IOS its readonly and for Atlas its write only
ReadCharacteristicData.setUuid(QBluetoothUuid::ReadCharacteristic);
ReadCharacteristicData.setProperties(QLowEnergyCharacteristic::Notify);
ReadCharacteristicDesc.setUuid(QBluetoothUuid::ClientCharacteristicConfiguration);
ReadCharacteristicDesc.setValue(QByteArray(2,0));
ReadCharacteristicData.addDescriptor(ReadCharacteristicDesc);
// For IOS its write only characteristic and for Atlas its read only
WriteCharactersiticData.setUuid(QBluetoothUuid::WriteCharacteristic);
WriteCharactersiticData.setProperties(QLowEnergyCharacteristic::Write |QLowEnergyCharacteristic::Notify);
WriteCharactersiticDesc.setUuid(QBluetoothUuid::AtlasDescriptor);
WriteCharactersiticDesc.setValue(QByteArray::fromHex("Write").toHex());
WriteCharactersiticData.addDescriptor(WriteCharactersiticDesc);
// For IOS its readonly and for Atlas its write only
ConnectivityData.setUuid(QBluetoothUuid::Connectivity);
ConnectivityData.setProperties(QLowEnergyCharacteristic::Notify);
ConnectivityDesc.setUuid(QBluetoothUuid::ClientCharacteristicConfiguration);
ConnectivityDesc.setValue(QByteArray(2, 0));
ConnectivityData.addDescriptor(ConnectivityDesc);
// For IOS its write only characteristic and for Atlas its read only
TrackerData_Data.setUuid(QBluetoothUuid::TrackingData);
TrackerData_Data.setProperties(QLowEnergyCharacteristic::Notify);
TrackerDesc.setUuid(QBluetoothUuid::ClientCharacteristicConfiguration);
TrackerDesc.setValue(QByteArray(2, 0));
TrackerData_Data.addDescriptor(TrackerDesc);
serviceData.setType(QLowEnergyServiceData::ServiceTypePrimary);
serviceData.setUuid(QBluetoothUuid::Atlas);
serviceData.addCharacteristic(ReadCharacteristicData);
serviceData.addCharacteristic(WriteCharactersiticData);
serviceData.addCharacteristic(ConnectivityData);
serviceData.addCharacteristic(TrackerData_Data);
leController.reset(QLowEnergyController::createPeripheral());
// leController->addService(serviceData) will return a pointer to service object
service.reset(leController->addService(serviceData));
leController->startAdvertising(QLowEnergyAdvertisingParameters(), advertisingData,advertisingData);
connect(&heartbeatTimer, &QTimer::timeout,this, &mainprocess::TickProvider);
connect(leController.data(), &QLowEnergyController::disconnected,this,&mainprocess::reconnect);
connect(service.data(),&QLowEnergyService::characteristicChanged,this,&mainprocess::printvalue);
heartbeatTimer.start(30);
///////////////////////////////////////
This sends data to IOS app every 30ms
///////////////////////////////////////
void mainprocess::TickProvider ()
{
if(Tracker.isRunning())
{
// sending Tracker Data
I have ommitted the code
QLowEnergyCharacteristic Charac_1 = service->characteristic(QBluetoothUuid::TrackingData);
service->writeCharacteristic(Charac_1,trackingdata);
}
// Sending Connectivity Status
QByteArray connectivity;
QLowEnergyCharacteristic Charac_2 = service->characteristic(QBluetoothUuid::Connectivity);
service->writeCharacteristic(Charac_2,connectivity);
}
//////////////////////////////////////////////////////////
Here I receive commands from IOS and respond accordingly
/////////////////////////////////////////////////////////
void mainprocess::printvalue(const QLowEnergyCharacteristic &info, const QByteArray &ba){
if (info.uuid()== QBluetoothUuid(QBluetoothUuid::WriteCharacteristic)){
// Username
if(ba.at(0)==0xA1){
}
// Password
if(ba.at(0)==0xA2){
}
// Tour Title
if(ba.at(0)==0xA3){
}
// Section Title
if(ba.at(0)==0xA4){
}
// Distance Interval
if(ba.at(0)==0xA7){
}
// Countdown
if(ba.at(0)==0xA8){
}
// Address
if(ba.at(0)==0xA9){
}
// Address Upload Later
if(ba.at(0)==0xA5){
}
// Mode
if(ba.at(0)==0xAA){
}
}
}
/////////////////////
Reconnect Function
////////////////////
void mainprocess::reconnect()
{
qDebug()<<"Reconnect Called";
//initializeBluetooth();
// connect(leController.data(), &QLowEnergyController::disconnected,this,&mainprocess::reconnect);
service.reset(leController->addService(serviceData));
connect(service.data(),&QLowEnergyService::characteristicChanged,this,&mainprocess::printvalue);
if (service!=nullptr)
leController->startAdvertising(QLowEnergyAdvertisingParameters(),
advertisingData,advertisingData);//, advertisingData);
}
Upvotes: 4
Views: 944
Reputation: 65
This is most likely the same issue as described here: QBluetoothSocketPrivate::_q_readNotify() 14 error According to SteffenH you have to use an individual port for each socket connection to a service. I believe currently you are using only port 1.
Upvotes: 0
Reputation: 4620
The same happens to me, during a BLE scan. It seems that the device is down for some reason (can be investigated through hcitool command - on Linux platform)
You should connect a slot to the following signal:
QBluetoothDeviceDiscoveryAgent::error(QBluetoothDeviceDiscoveryAgent::Error)
and you probably discover that your device is OFF.
In that case, check the following:
QBluetoothLocalDevice::hostMode()
if it returns QBluetoothLocalDevice::HostPoweredOff
, just do :
your_bluetooth_local_device->powerOn();
Anyway: please add a complete example of what you are actually doing, the Qt version used, the platform.
Upvotes: 1