更新しました:
Qt バージョン: 5.11
プラットフォーム:ラズベリーパイ3
オペレーティングシステム: Rasbpian
Linux Qt BLE アプリを IOS セントラル デバイスに接続しています。ほとんどの場合は問題なく動作しますが、次のエラーでクラッシュすることがあります
qt.bluetooth.bluez: void QBluetoothSocketPrivate::_q_readNotify() 29 エラー: -1 「リソースが一時的に利用できません」
コードと基本的なシナリオは次のとおりです。
Qt 5.11 を実行している raspberrypi があり、IOS アプリに接続してデータを送受信する BLE 低エネルギー周辺デバイスを作成しました。
宣言:
QLowEnergyCharacteristicData ReadCharacteristicData,
WriteCharactersiticData,
ConnectivityData,
TrackerData_Data;
QLowEnergyCharacteristic charas;
QLowEnergyDescriptorData ReadCharacteristicDesc,
WriteCharactersiticDesc,
ConnectivityDesc,
TrackerDesc;
QLowEnergyServiceData serviceData;
QScopedPointer<QLowEnergyController> leController;
QScopedPointer<QLowEnergyService> service;
サービスの初期化:`
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);
}