Bluetooth, Reflection, and “Legacy” NFC

Today, we just got a swath of Nexus S phones to support our research class’s exploration of uses for NFC technology.   Unfortunately for me, I recently bought a Motorola Atrix which doesn’t have any tag reading or writing capability.  It’s only sort of unfortunate though, because the device is amazing.  It has a great screen and is wicked fast.  But, I digress, the important thing is that I’m able to use that brand new device for social interactions triggered by a physical context.  Luckily for us, Ben showed us how to do this if at least one of the two parties has active NFC technology.  Basically, you put a smart label on the “dumb” phone and then run a small piece of software on it that lets the “smart” phone contact it over bluetooth (or the internet) to complete the interaction.

Google added support for “insecure” RFCOMM sockets in the 2.3 version of Android, however, my phone is currently stuck at 2.2 of the OS thanks to a locked boot loader.  This leads to an obnoxious UI foible when performing the first bump operation between phones.  Because the Froyo software doesn’t include a public interface for Bluetooth without PIN-based pairing, the initial NFC tag triggered chat between the devices causes notifications to popup that ask for validation of the Bluetooth pairing key.  I set out to solve this problem in a way that will work for devices regardless of OS version and not require root or custom OS images.

The core parts of the Bluetooth connection initiation APIs are contained in the classes BluetoothAdapter and  BluetoothDevice buried inside the core Android frameworks.  A quick inspection of the source for those classes in Gingerbread shows that the insecure RFCOMM creation API calls are mostly thin wrappers around constructors for the BluetoothServerSocket and BluetoothSocket classes.  These constructors have package visibility, so you can’t call them from outside java code directly.  Looking at the 2.2 sources reveals that the signatures of the constructors match with the Gingerbread, so if I can just call those constructors with modified parameters then I can have “insecure” Bluetooth on my Atrix phone.

Java has some great reflection APIs, so it is possible to get handles to all of the internal methods and fields required to re-implement the pairing-free RFCOMM interface.  There are two tricks to doing this.  First, you have to call the Declared variants of functions that fetch handles to class members.  These variants will allow you to get access to private and package visible members.  Second, you have to call setAccessible(true) on the method and field handles that you retrieve so that you are allowed to violate the protections that the visibility modifiers imply.  If you do those two things, the only remaining challenge is wrapping everything with the correct exception handling.  Invocation of reflected methods introduces the possibility for a wide range of exceptions and it wraps exceptions triggered from within the invoked calls inside TargetInvocationException.  Solving these issues just mean a bit of code bloat.

With those bits and pieces in mind, I produced a utility class that allows for non-Gingerbread devices to use the pairing-free Bluetooth (InsecureBluetooth.java).  To test it out, I modified the BluetoothChat sample in the Android v8 SDK to use the class (BluetoothChatService.java … the only file I changed).  I was able to establish a session between the Atrix and the Nexus S without incurring the wrath of the pairing user interface.  Soon this will be integrated into our easy NFC packages available on github.

When you set up an insecure connection, it actually does create a pairing between the two devices.  The assumption is that you are checking the identity of the other device out-of-band.  For two devices connecting over NFC, you physically validated they wanted to connect.  This workaround lets you make software which lets you achieve the Gingerbread level of UI smoothness for pairing if your higher level system handles identity checks on its own.  For many of the projects we are working on, the higher level identity check is there, so its safe to use this to establish pairings.  If for some reason the higher level check fails, the right thing to do is to un-pair the devices.

Mar30

10 Responses to “Bluetooth, Reflection, and “Legacy” NFC”

  1. Can two <2.3 devices pair using you insecure API's without asking the user for a pin OR does at least one of the devices need to be running 2.3?

  2. tjpurtell Says:
    April 18, 2011 at 1:13 pm

    Yes, that should work just fine. The insecure bluetooth utility code includes methods for listening for socket connections as well as establishing them.

  3. Thanks for posting. I’m attempting to connect an unusual device to the Droid. No success yet, but I’ll have another go tomorrow. This was a good start.

  4. thank you so much. I have been scratching my head about this for awhile.

  5. Hi,
    first of all, thanks for this very interesting article.
    I’m lookin for a way to make two droid phones being able to communicate over bluetooth without any user intervention.
    I tried to use your InsecureBluetooth file, but even if I use this to create a ServerSocket and a ClientSocket, there’s still a prompt on both client and server phone asking to confirm the pairing.
    Is this the behaviour ?
    Is there any way to achieve this without any user intervention ?

    Many Thanks again for your work,
    with my Regards,
    Antoine

  6. Hauke Walden Says:
    March 1, 2012 at 4:36 am

    I have the same problem that Antoine has described – I keep getting dialogs that ask me to confirm a PIN. BTW, this happens also when I’m using the createInsecureXXX methods from API Level 10 and up – does anybody know why this would happen at all?

  7. oh , bluetooth it is a old stuff

  8. Thank you so much for this article and your code. I have been sitting at this roadblock for a few days because of v2.2 limitations being forced upon my project. Was able to get code in my project and working in less then 1 minute.

    Bravo!

  9. TJ, thanks for writing this very useful code! Is InsecureBluetooth.java available under a free license (GPL-compatible)?

  10. I viѕit daily a few blogѕ аnd blogs tо
    read articles or rеviews, howeveг this ωeb site provides qualitу baѕeԁ writing.

Leave a Reply