Background; how does ABTraceTogether work?

It's a Bluetooth Low Energy (BLE) app. BLE has two participants, a "central" and a "peripheral".

A central device scans for things, connects to them, and reads and writes data to them.
A peripheral device advertises the services it provides, then allows things to read and write to them.

Services are well-known codes (UUIDs) that identify their purpose, and both sides know to look for.

Services have "characteristics" that contain data, or can receive data.
Example: you have a heart rate monitor, and Strava on your phone when you bike.

Strava acts like a central app. It scans for peripherals that have a "heart rate" service, and then reads the "heart rate" characteristic to record your heart rate while you ride.
ABTraceTogether acts as a central and a peripheral.

The central part of it looks for other ABTraceTogether apps. When it finds them, the central reads the peripheral's tracking ID (stores it), and then the central writes its own tracking ID to the peripheral.
The peripheral part of it advertises that it is ABTraceTogether. When something connects and reads, it provides it's own tracking ID. And when something writes to it, it stores the other device's tracking ID.
Now, that's how it works. Coming soon; the bugs... but first, a testing tool.

I wrote an node.js macOS application that acts like ABTraceTogether. This allowed me to run through the central & peripheral workflows with iPhones and Androids. https://github.com/mfenniak/abtracetogether-nodejs
abtracetogether-node is not intended for end-users. You'll have to be able to read, understand, and tweak the JS code to get what is going on. I'm releasing it so that my testing can be reproduced by other developers.
OK, bug #1. You all know it - background iOS. Skip the next couple tweets if you don't want the technical details; but two iPhones, with the app in the background, can't discover each other. iOS doesn't permit it.
(bug #1 cont'd) iOS doesn't permit it because of two power-saving features. (a) when scanning for peripherals as a central, & in the background, the device only uses "passive" scans -- it doesn't send out a scan request, it just waits to hear an advertisement from a peripheral.
(bug #1 cont'd) power saving (b) when advertising as a peripheral in the background, a proprietary hash/bitmap of service UUIDs is advertised. This allows hundreds of services to be advertised in one packet, reducing the power usage.

https://developer.apple.com/documentation/corebluetooth/cbperipheralmanager/1393252-startadvertising
(bug #1 cont'd) This causes two background iPhones to never see each other. If either fact were different -- if the iPhone did an active scan, it would decode the proprietary format -- or if the iPhone advertised according to the standard, it would recognize the other phone.
(bug #1 cont'd) Use abtracetogether-node in Central mode, and bring an iPhone nearby. You'll see nothing. Bring ABTraceTogether into fgnd, and you'll start seeing trace data. You will continue to see data until the iPhone rotates its Bluetooth address; then it can't rediscover.
Bug #2: Guess who else doesn't recognize the proprietary format of the iPhone advertisement? You guessed it; Android phones.

An iPhone can find and discover an Android while both are in the background, but not vice-versa.
(bug #2 cont'd) Because the tracing system both reads & writes when the iPhone finds the Android, this bug doesn't severely affect tracing, actually... assuming there were no other bugs. But there are!
Bug #3. The Android version of ABTraceTogether sometimes just forgets its current Temporary ID. When acting as a central, it stops writing. When acting as a peripheral, you read from it and get no identifier. You're invisible!
(bug #3 cont'd) This bug seems to happen shortly after the Android app is in the foreground. I think what is happening is that the TempID is supposed to last 15 minutes and then the app moves onto the next ID, but it doesn't move on.
(bug #3 cont'd) So it recognizes that it's current ID is invalid in a method called bmValid, and then it stops returning it for reads, and it stops performing writes.

There could be two bugs here; one reading, one writing, but I think they have a common cause in the TempID data.
(bug #3 cont'd) The impact of this bug is that Android phones are virtually invisible to ABTraceTogether. The new TempIDs do get picked up when you restart the app or bring it to the foreground.
(bug #3 cont'd) Use abtracetogether-node in Central mode, and bring an Android nearby. The message "characteristic returned no data" means that it reached out to a device that didn't return tracking data. I get this after ~10 minutes of having an Android nearby, the app in bkgnd.
(bug #3 cont'd) OR, use abtracetogether-node in Peripheral mode and bring an Android nearby, in the foreground. Then put app in the background. The Android will read & write to the peripheral for a short while, and then stop.
Alright, we're getting there... bug #4. It's similar to bug #3, but has a different impact. The iPhone apps send out the same TempID over and over again, despite the fact that they're supposed to rotate every 15 minutes.
(bug #4 cont'd) Use abtracetogether-node in either Central or Peripheral mode, run an iPhone in the foreground, and then let it go into the background. You'll get the same TempID being sent out for hours. I don't think it ever rotates.
(bug #4 cont'd) The impact of this bug isn't on effectiveness; it's on privacy. The reason the TempID is rotated is so that you can't develop an app to track everyone coming and going around you by bluetooth. (By the way, my neighbor uses ABTraceTogether.)
So what's the impact of all these bugs?

The only reliable ABTraceTogether interaction is that an iPhone will push it's tracing data to an Android.

Bug #1 blocks iOS/iOS. Bug #2 blocks Android from finding iOS. Bug #3 blocks Android from being traceable.
And bug #4 makes it kinda unsafe.

Any caveats to these findings? Yes.

- I'm testing with a couple different Android devices, but there's no guarantee that this generalizes to all devices.
- Ditto the iPhone findings.
- I'm interpreting and trying to understand the data from my testing tool. I could be getting things wrong at times. (I actually thought the tool was broken at first; until I started getting iPhone data. 🤣)
- I haven't (yet?) added COVID Alert's services to my testing tool. I don't know that it works any better, technically. The Ontario usage data is pretty promising, though.
You can follow @mfenniak.
Tip: mention @twtextapp on a Twitter thread with the keyword “unroll” to get a link to it.

Latest Threads Unrolled:

By continuing to use the site, you are consenting to the use of cookies as explained in our Cookie Policy to improve your experience.