Hi everyone,

I have been developing an app for android first and iOS.
Let says that my app is working as desired. But it's not stable. I'll explain.

I do have 1 service. 4 characteristics, 1 characteristic I enable notification.

On android 5, I have to disable and enable the bluetooth peripheral to make my app find my device. But with this trick, my app works 100% (as expected)
On android 6, disabling enabling the bluetooth isn't enough. I need to unpair manually the device to get notification working.
On iOS, I have to disable manualy the bluetooth to get notification working. (as I can't disable bluetooth by Qt)

I'm aware this isn't good to disable enable bluetooth, but this is the only way I found to get it working.

Also I did find a post where it says that i have to disable notification to get a proper disconnection.
That's what I do, but when I check if notification is valid line 53 on the code below, it says "false". but if I test if the service I have stored contains notification. I have a "true".
I found this a bit wired.

Thanks


I did post some of my code.
Let me know if you want more.

Qt Code:
  1. bool JTBLEObject::connectToDevice()
  2. {
  3. bool ret = false;
  4.  
  5. if(controller){
  6. delete controller;
  7. }
  8.  
  9. controller = new QLowEnergyController(*info,this);
  10.  
  11. if(controller)
  12. {
  13. connect(controller, SIGNAL(connected()),
  14. this, SLOT(deviceConnected()));
  15. connect(controller, SIGNAL(error(QLowEnergyController::Error)),
  16. this, SLOT(errorReceived(QLowEnergyController::Error)));
  17. connect(controller, SIGNAL(disconnected()),
  18. this, SLOT(deviceDisconnected()));
  19. connect(controller, SIGNAL(serviceDiscovered(QBluetoothUuid)),
  20. this, SLOT(addLowEnergyService(QBluetoothUuid)));
  21. connect(controller, SIGNAL(discoveryFinished()),
  22. this, SLOT(serviceScanDone()));
  23.  
  24. toTimer.setInterval(CONTROLLER_CONNECT_TO);
  25. toTimer.start();
  26. controller->connectToDevice();
  27. set_status(Connecting);
  28. ret = true;
  29. }
  30. return ret;
  31. }
  32.  
  33.  
  34. void JTBLEObject::deviceConnected()
  35. {
  36. toTimer.start();
  37. discoverServiceTimer.start();
  38. controller->discoverServices();
  39. set_status(ServDiscovering);
  40.  
  41. }
  42.  
  43.  
  44. void JTBLEObject::deviceDisconnected(){
  45.  
  46.  
  47. // Status could be in "Detected" as a micro connection can happen. So remove only if the status is "Connected"
  48. if(get_status() == Connected){
  49.  
  50. set_running(false);
  51. set_expanded(false);
  52.  
  53. qDebug() << "notification.isValid()" << notification.isValid();
  54.  
  55. if(serviceList.value(QBluetoothUuid(QString(THERAPY_SERVICE_UUID)))){
  56. QLowEnergyService* m_service = serviceList.value(QBluetoothUuid(QString(THERAPY_SERVICE_UUID)));
  57. qDebug() << "service contains" << m_service->contains(notification);
  58. qDebug() << "service error" << m_service->error();
  59. m_service->writeDescriptor(notification, QByteArray::fromHex("0000"));
  60.  
  61.  
  62. }
  63.  
  64. batteryReadTimer.stop();
  65.  
  66. set_status(Removing);
  67.  
  68. emit bleControllerEvent();
  69. }
  70.  
  71. }
  72.  
  73.  
  74. void JTBLEObject::connectToService(QLowEnergyService* service)
  75. {
  76. discoverServiceTimer.stop();
  77.  
  78. if(service->state() == QLowEnergyService::DiscoveryRequired)
  79. {
  80. connect(service, SIGNAL(stateChanged(QLowEnergyService::ServiceState)),
  81. this, SLOT(serviceDetailsDiscovered(QLowEnergyService::ServiceState)));
  82.  
  83. connect(service, SIGNAL(characteristicRead(const QLowEnergyCharacteristic&, const QByteArray&)),
  84. this, SLOT(readCharacteristicsFromBLE(const QLowEnergyCharacteristic&, const QByteArray&)));
  85.  
  86. connect(service, SIGNAL(characteristicChanged(const QLowEnergyCharacteristic&, const QByteArray&)),
  87. this, SLOT(readCharacteristicsFromBLE(const QLowEnergyCharacteristic&, const QByteArray&)));
  88.  
  89. service->discoverDetails();
  90.  
  91. set_status(CharDiscovering);
  92. }
  93.  
  94. }
  95.  
  96.  
  97.  
  98. void JTBLEObject::readCharacteristicsFromBLE(const QLowEnergyCharacteristic& carac, const QByteArray& data)
  99. {
  100. if(carac.uuid() == QBluetoothUuid(QString(PROGRAM_MSB_UUID))){
  101. .
  102. .
  103. .
  104. }
  105. else if(carac.uuid() == QBluetoothUuid(QString(THERAPY_PROGRAM_LSB_UUID)))
  106. {
  107. char tempData[16];
  108. int max = data.size() > 16 ? 16 : data.size();
  109. for(int i=0; i < max; i++)
  110. {
  111. tempData[i] = data.at(i);
  112. }
  113.  
  114. set_timeValue(((quint8)tempData[1]) << 8 | ((quint8)tempData[2]));
  115. set_running((tempData[3] & 0x01) == 0x01);
  116.  
  117. if(!notification.isValid()){
  118. notification = carac.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration);
  119. if (notification.isValid())
  120. {
  121. QLowEnergyService *service = qobject_cast<QLowEnergyService *>(sender());
  122. service->writeDescriptor(notification, QByteArray::fromHex("0100"));
  123. qDebug() << "Enable Notification on Status - OK";
  124. }
  125. }
  126. }
  127. else if(carac.uuid() == QBluetoothUuid::BatteryLevel)
  128. {
  129. this->set_batteryValue(data.at(0) & 0x7F);
  130. this->set_batteryCharging((data.at(0) & 0x80) == 0x80);
  131. }
  132.  
  133. batteryReadTimer.start();
  134.  
  135. }
To copy to clipboard, switch view to plain text mode