Bluetooth Data Exchange Between Android Phones Without Pairing
What if two Noomers in the same restaurant, concert, or bar could discover one another and connect over a shared interest, favorite food, or activity? What if even without an internet connection, they could chat and support one another relatively anonymously without sacrificing the security of their device.
During Noom’s Winter 2015 Hackathon I decided to explore these questions. I wanted to find a way for our users to talk to each other without pairing or Internet access by using Bluetooth.
I’ve written a full paper on this topic, which you can find here, but here’s an overview of how it works:
Bluetooth devices are identified using MAC IDs, and device names. However, they also offer a list of supported services using UUID numbers. Devices use the Bluetooth Service Discovery Protocol (SDP) to scan for nearby devices and discover what services they offer.
I ended up storing information as fake Bluetooth services, by encoding binary data in the UUID strings representing available services. This approach does not pair the devices.
To distinguish our services from others, I used the last 4 characters / 2 bytes as “C0DE”. There are also two parts of the UUID that are always set to “4” and “8” (UUID version number and reserved data). This will leave us with 104 bits or 13 bytes per service UUID to use with data. It would be trivial to extend this to support multiple UUIDs with different messages in them.
Example of our UUID strings appears below:
Detection and extraction of data is done using a regular expression:
To encode data, we would pad it with zeros, and convert to binary, then encode inside a UUID:
Once we have the data we want to encode, it’ is trivial to actually register the service as follows:
To locate services on other devices, the following steps would be needed:
- Scan the surrounding area for Bluetooth devices and watch out for new devices (as per Android guide here).
- Once you found a device, you would call the fetchUuidsWithSdp method.
- Watch for ACTION_UUID intent and collect list of UUIDs.
- Loop through the list of UUIDs and extract the data via regular expressions.