3

I’m working on a simple wrapper around CoreBluetooth to send any data to any device. During developing I encountered a lot of bugs in framework, they were very annoying and to make my wrapper stable I had to shorten some of functionality for reliability.

For now I’m working on sending data from peripheral.

Ok, so I have following case:

  • Client asks for value of dynamic characteristic
  • I get a callback on server-side - peripheral:didReceiveReadRequest:.

Note : I need to respond to this CBATTRequest in this method - I can’t store it elsewhere and respond to it asynchronously. (Im just putting some chunk @“PrepareToReceiveValue” that will be ignored on central side. All sending is done in queue.)

  • For providing data for various devices I constructed a queue with BTMessage's in it. (So for readRequest I create message and add it to sending queue. If chunk sending failed - I will get a callback from peripheral manager about readyToUpdateSubscribers and will ask queue to resend failed chunk)
  • So when I’m requesting immediately a lot of dynamic characteristic values and sending data from peripheral to central concurrently sometimes it just freezes sending progress and leads to disconnection.

After several testing I found out that it was all about transmit queue: If transmit queue is full and you will receive read request - it just won’t respond to it.

So I have potential unstable system state:

  1. Peripheral is sending data to some central.
  2. In my sending method updateValue:forCharac… returns NO because transmit queue is full.
  3. At this moment central requests dynamic value for characteristic and peripheral:didReceiveReadRequest: invocation will be added to current runloop.
  4. After returning from sending method it will dequeue peripheral:didReceiveReadRequest: method and responding to this request will have no effect (transmit queue is full).
  5. So in this case respondToRequest: is ignored like I didn’t invoked it at all.
  6. CoreBluetooth will not be able to send/receive any data until I will respond to request. That was the reason for freezing any sending/receiving progress with concomitant disconnection.
  7. As I mentioned before - I must respond to request in appropriate method - otherwise it will also have no effect. (Im saying it because I’ve tried to put those request in array if queue is full and respond to them when it will have some space but with no luck).

Im waiting for your proposals/suggestions how to resolve this problem, any help would be appreciated.

  • I already sent you a note on the Apple mailing list that seems to have missed your attention. Do you use notifications or indications? If a read request is not responded for some time doesn't it simply time out? – allprog Feb 03 '14 at 08:17
  • Yes I saw your feedback, thanks for it :) I've opened a bug on apple's bugreport system and waiting for their response. 'Do you use notifications or indications?' I'm using indications, I need to be sure that chunk is delivered. 'If a read request is not responded for some time doesn't it simply time out?' When I didn't respond on read request - it will lead to central disconnection from peripheral. – Yurii Romanchenko Feb 03 '14 at 08:39
  • Ok, with indications, this is not going to work as long as the stack is misbehaving. You should implement a scheme similar to how you would handle making UDP reliable. Would be good to know if there is any way to make a read request simply time out rather than result in disconnection. – allprog Feb 03 '14 at 08:51
  • Hmmm, interesting idea. I will try to reimplement my transmission via notifications – Yurii Romanchenko Feb 03 '14 at 09:33
  • As a very fast test, just try what happens if the peripheral does not respond to the read request when notifications are used. If disconnection happens, then everything is probably in-vain and the CB stack must be corrected first. (It must be corrected anyway if your observations are justified.) – allprog Feb 03 '14 at 09:40
  • This is unfortunate. You should update your bug report to emphasize that this is a serious bug. I wonder why we haven't heard about this issue yet. Can you share the code you submitted along the bug? If you haven't then you should to it as it's going to be the next thing they are going to request. :) – allprog Feb 03 '14 at 10:35
  • No I haven't submitted code. Do you know how long they will review it until I get response? – Yurii Romanchenko Feb 03 '14 at 11:03
  • Did Apple ever respond or did you find a solution? – Paul Slocum May 14 '15 at 04:27
  • They released new iOS and asked me to reproduce that issue, however till that time I've already changed my architecture - I've decided to cut off didReceiveReadRequest: feature, because I don't need it anymore. – Yurii Romanchenko May 14 '15 at 10:20

0 Answers0