Bluetooth "out of band" (OOB) pairing on Android?

12,821

Solution 1

I have my issue 95% solved but I have hit a small road block. First I'll update this post with a more concrete answer to the original question and post my question at the end.

To recap, my task is to use out of band (oob) pairing to securely pair an android tablet using Honeycomb 3.2 to a beagle board through USB. I can't post specific code, but I'll give you all the steps needed to get this done.

On the beagle board, I have the bluez 4.96 stack installed with the dbusoob plugin installed. To confirm this is set up correctly install 2 Bluetooth dongles on the beagle board and run the OOB Test Code found in in the bluez archive in the test folder. This is a python script. The script should successfully pair the 2 Bluetooth dongles, if not bluez is probably not setup correctly.

To get USB communications with a tablet working you need to install mtpfs and mtp-tools. These are used to mount your tablet. They way I solved getting OOB information between the 2 devices were to mount the tablet on the beagle board. Once mounted the tablet and beagle board can write out a file with the information needed.

On the android side OOB is not supported in the public API so things get tricky. I believe this is because Honeycomb 3.2 does not have a bluez stack that officially supports OOB bonding, but Google has some kind of implementation coded in. I believe this because if you look at gingerbread source code for the Bluetooth Adapter and Bluetooth Device classes you can see OOB methods available but not exposed through the documented API.

These methods are still public so you can call them through reflection. Using reflection you can also get all of the method signatures in a class. This is how I figured out what methods I had available to me.

Beware though that many are not documented and it's not obvious what some do. The important ones to make note of are the readOutOfBandData() in the adapter class and setDeviceOutOfandData() in the device class.

Another gotcha you might run into is when you write your oob data to a file on the tablet to be read by the beagle board. Since android uses mtp you must index your file after it is written to the internal sdcard storage. To solve this you need to make use of the MediaScannerConnection class and the scanFile() method.

Hopefully the above helps anybody else with this same issue.

Now on to my question. I have my android application working great and my beagle board code is the testOOB example updated to have one end read OOB information from a file. Now the issue I see is when executed everybody sees each other great, but on the tablet I still get a message asking if I want to pair with device xyz. There are no keys or numbers. It just asks "Pair with Device XYZ" or something along those lines.

If I press "pair" it's all paired from the tablets point of view, BUT the python script returns that the paring failed. The python script on the beagle board is calling the actual method to do the bonding between the devices. Even when I have the android initiate the createBond call I see the same outcome. I can guarantee that I have set the required OOB data on both ends before trying to pair in both cases so that doesn't seem to be it.

So my issues that I'm hoping somebody can help me with are:

1) Why do I even get a message on android if the OOB data is exchanged properly? Is there another call I'm missing and on which end?

2) Why does the beagle board python script return paring failed even thought I press "pair" popup displayed on the tablet. The tablet and blues monitor both show the devices as paired. Some again I'm leaning towards the idea that I am missing something.

Thanks to anybody that can help :)

EDIT:

To add more information here is the logcat output:

D/UIBluetooth( 4363): !!!!!! Start Bond !!!!!!
D/BluetoothService( 1703): Setting out of band data for: 00:02:76:24:C2:8F:[-37, -1, 65, -42, -121, -75, -60, -4, -47, -86, -88, 14, 64, 83, 16, 96]:[-112, 34, 121, -97, 15, -54, -83, -
93, 104, -83, -124, -25, 89, 114, 66, 62]
D/BluetoothBondState( 1703): 00:02:76:24:C2:8F bond state 10 -> 11 (0)
D/UIBluetooth( 4363): createOobBond Successful
V/BluetoothEventManager( 2174): Received android.bluetooth.device.action.BOND_STATE_CHANGED
D/BluetoothEventLoop( 1703): Property Changed: Devices : 1
D/BluetoothEventLoop( 1703): Device property changed: 00:02:76:24:C2:8F property: Connected value: true
I/BluetoothEventLoop.cpp( 1703): agent_event_filter: Received method org.bluez.Agent:RequestOobData
I/BluetoothEventLoop.cpp( 1703): agent_event_filter: Received method org.bluez.Agent:RequestOobData

The last two line seems to be triggering the popup on Android to either Pair/Cancel with the Device in questions. I would like Android to know to just auto bond and not even ask. I could be missing a call or doing something out of order for all I know. The last thing I do in my code is to create the bond which seems to be the obvious place to do it....

Thanks for any suggestions!

Solution 2

There are no public APIs yet on androind to allow for OOB pairing. It is possible nnly if you can or are willing to modify the underlying BlueZ stack to expose the OOB paring hooks to the applicaiton. (Non trivial task)

What OOB mechanism are you plannin on using ? NFC ?

Share:
12,821

Related videos on Youtube

Brian
Author by

Brian

Updated on June 04, 2022

Comments

  • Brian
    Brian almost 2 years

    I've been searching the internet and haven't seen anything in the way of how to exactly implement OOB pairing. I was hoping somebody here could point me to some example code to help me out. The chat example in the Android developers site didn't really dive into this type of pairing at all.

    Basically, I have an Android tablet that I want to securely pair with a device, written in C++, that has no built in display/IO mechanism. The tablet to be paired will act as the GUI/IO interface and I'll send message back and fourth over Bluetooth. Thus I want to securely pair the tablet with each device through the OOB paring scheme.

    I understand the concept of OOB but I'm having difficulty finding the proper methods to call when looking on the android.developers.com site for my android client code. Also when looking at the bluez stuff I can't find much to go on for my C++ written server.

    The basic use case is the user will connect the tablet to the device via a USB connection. The USB connection will facilitate the passing of keys/mac addresses for each device and then using that information pair Bluetooth with each other.

    I can figure out the USB part but once I have the keys and necessary information on the client and server I can't seem to track down the correct methods to call for both ends to successfully and securely pair.

    I already have a client/server talking via an insecure connection so really the only part I'm having trouble with is the actually pairing on both ends. As once I'm paired I can used a secureRFComm to do all of my future messaging.

  • Brian
    Brian over 12 years
    Thanks for the response Dennis. The way I envision the handshake happening is the user will connect the tablet to the device via a USB connection. The USB connection will facilitate the passing of keys/mac addresses for each device. Having the MAC address of each device I should be able to pair bluetooth with each other pragmatically set with the correct keys. This seemed to be what OOB pairing is all about. This is a custom job and not a app planned for the android market. So, if this is not the correct way to handle this type of pairing then I'm open to design suggestions.
  • Brian
    Brian over 12 years
    I search the android documentation some more and found some methods listed as @hide that seem useful. One such method is "createBondOutofBand". Is this something I can call through reflection or is there sill BlueZ stack changes needed? I am also still unsure on how to handle this on the server which is the non-android. By handle I mean methods I need to call into BlueZ that would let the server pair OOB. Thanks for any help!
  • Hasturkun
    Hasturkun over 12 years
    @Brian: OOB pairing requires a Hash and Randomizer value from each of the Bluetooth HCIs (you can also do unidirectional authentication if only one side can send data, but this isn't the case here). I assume you'd get your values from the android side using readOutOfBandData, but I don't develop for android, so can't verify anything.
  • Brian
    Brian over 12 years
    @Hasturkun Thanks for the reply. I think I have some direction on the android side, but now I'm wondering about the c++/linux side using BlueZ. I haven't been able to find any references to BlueZ c++ code using OOB paring. The reference you gave me is talking about java specifically. Does this same call live in c++? I haven't been able to find much in the way of documentation for linux/c++ oob paring so any references you can provide would be great, especially if there were some examples or a list of useful methods I need to call. Thanks again.
  • Hasturkun
    Hasturkun over 12 years
    @Brian: For BlueZ, you need to use the dbusoob plugin, use the org.bluez.OutOfBand D-Bus interface, check this test code for example usage (in python)
  • a sandwhich
    a sandwhich almost 11 years
    Would you be able to post your source somewhere? I have been working on something very similar to this but I haven't gotten very far.
  • ymerdrengene
    ymerdrengene over 6 years
    Hello, did you come up with a solution to this problem? I think many people are struggling with this.