iAP Bluetooth data stream is slow for 20 seconds after app enters foreground

We have a custom accessory using iAP over Bluetooth classic (BR/EDR), and have recently noticed an unexpected wireless performance issue that wasn't there before. We haven't changed the firmware, and the nature of the bug strongly suggests it isn't anything on our end. The problem occurs in two different apps with very different codebases; one is our production app, which a large, complex Swift app for iPads. The second is a barebones test app that simply exercises the accessory to measure throughput. These apps have been in use for well over a year, and the test app has had no changes to speak of in that time. Neither app experienced this issue before (at the latest) iOS 15.

Basically, as soon as a toggle switch in the test app is enabled, the ExternalAccessory data stream is opened and a single command is sent to the accessory which instructs it to begin streaming data at roughly 7500 bytes/second. Normally, this throughput rate is easily achieved. However, when the problem occurs, the actual throughput varies wildly, averaging about 60-70% of the target rate. But the problem only occurs for 20 seconds after the app enters the foreground, and then the data stream stabilizes at full throughput. Nothing changes in the app or on the accessory during this time.

I have run dozens of tests, and the problem and timing are always the same:

  • The app exhibits poor Bluetooth throughput for 20 seconds after entering the foreground.
  • Freshly running the app or switching to the running app from a different app both trigger the problem.
  • Waiting to open the iAP connection for 20 seconds after foregrounding the app results in expected (good) throughput the whole time.
  • Disconnecting and reconnecting the accessory does not trigger the problem.

I'm not sure what else to test. I expect the same results could be seen with any Bluetooth iAP accessory pushing that much data right after its associated app enters the foreground.

Note, we have a different hardware variant in development which uses Bluetooth Low Energy and CoreBluetooth, and it has no such problem. It works perfectly all the time with the exact same testing app and data stream, just pushed over GATT instead of iAP.

Has anyone encountered similar symptoms with iOS 15.x or anything else?

Accepted Reply

I finally figured out the problem, and it turned out to be something simple and obvious (as usual):

Both apps used for testing were simultaneously running a Bluetooth LE scan the entire time. The solution is to stop scanning while the iAP data stream needs full throughput.

In retrospect, this is obvious. While I haven't found any documentation confirming this, my suspicion is that iOS gives more radio time to an ongoing BLE scan for a short time (20 seconds) after an app enters the foreground, logically assuming that it is scanning for a good reason and will want to be notified as soon as possible when any matching devices are found. Then, if the scan continues for more than 20 seconds, iOS throttles it back so the radio can be allocated more heavily to other things. This suspicion matches what I saw while investigating with Apple's ATS tool, as the HCI packet capture revealed a flurry of LE Scan Parameter modifications right around the time the iAP throughput returned to normal.

This explanation fits with all of the evidence we have, and the fix works, so I'm pretty sure it's the right answer. Crisis averted!

Replies

I finally figured out the problem, and it turned out to be something simple and obvious (as usual):

Both apps used for testing were simultaneously running a Bluetooth LE scan the entire time. The solution is to stop scanning while the iAP data stream needs full throughput.

In retrospect, this is obvious. While I haven't found any documentation confirming this, my suspicion is that iOS gives more radio time to an ongoing BLE scan for a short time (20 seconds) after an app enters the foreground, logically assuming that it is scanning for a good reason and will want to be notified as soon as possible when any matching devices are found. Then, if the scan continues for more than 20 seconds, iOS throttles it back so the radio can be allocated more heavily to other things. This suspicion matches what I saw while investigating with Apple's ATS tool, as the HCI packet capture revealed a flurry of LE Scan Parameter modifications right around the time the iAP throughput returned to normal.

This explanation fits with all of the evidence we have, and the fix works, so I'm pretty sure it's the right answer. Crisis averted!