Android BLE Numeric Comparison Pairing Implementation - android

How do we implement Numeric Comparison for Android?
I've done alot of research and I know I need to set the IOCapability to KeyboardDisplay.
And if the other BLE device's own IOCapability makes it match the matrix result of Numeric Comparison, it will pair with Numeric Comparison.
But I cannot find any example code online.
We are supposed to somehow use BluetoothConfigManager to set the IO Capabilities right?
I.E. Use setIoCapability(int capability) and IO_CAPABILITY_KBDISP
See here: https://developer.android.com/reference/com/google/android/things/bluetooth/BluetoothConfigManager
Thanks.

You are right that usually the IO capabilities of both devices determine if the pairing pop up should appear, however, this is not the case for Android. On Android, this is usually handled by the device hardware so unfortunatey there is no way to guarantee that you can get the pairing dialog to pop up. Howoever, there are hacks that you can use that have worked for other people in the past. Have a look at the links below:-
CreateBond doesn't always show PIN dialog
Making Android BLE work - bonding

Pairing in Android is handled by the system. The system sets the IO Capabilities. For normal smart phones you usually have both a display and a keyboard, so these will be used. Any recent Android version also supports LE Secure Connections (LESC), where numeric comparison was introduced.
As you say, as long as the remote device has a display and yes/no input as IO Capability and supports LESC, the numeric comparison will be used.
If this does not seem to be the case, check the hci log or use an air sniffer to inspect the Pairing Request and Pairing Response messages to see which capabilities each device announces.

I was able to finally get the Numeric Comparison paring to finally work!
I was using the Nordic BLE library, and using createBond() prompts the Android OS to take care of the entire Numeric Comparison process (see picture below).
I think this is a great step for documenting this, because I searched everywhere on the internet for example code/ implementation for this and could not find anything. This is maybe the first.
If you are not using Nordic BLE library, I think the normal library functions related to creating bonds will do the same thing.

Related

Simulate USB/Bluetooth HID device locally in order to inject events?

Is it possible to simulate a USB or Bluetooth device connected to Android?
I would like to make an app which is able to simulate an HID device locally. What I mean by this is: the app should make Android believe that an USB/Bluetooth HID device is connected. This would allow my app to inject touch events globally, I hope. Is there anyway to simulate a (virtual) device? Note that I don't really care about the device, I just want to use the built-in support for HID input.
I know a lot of people already asked about touch event injections but this approach seems to be a little bit different. I do not want to use this for testing purpose, so InstrumentationTestCase and the like won't help.
Rooting the device might be an option, although I can also imagine to ask my endusers to install a specifically signed app manually (according to https://stackoverflow.com/a/16737083/2923406 and https://stackoverflow.com/a/22902808/2923406 this works, but it would be device specific).
I am aware of:
Simulate a mouse input on android - This guy seems to do it in his own app, although his questions wasn't answered ;)
http://www.pocketmagic.net/2013/01/programmatically-injecting-events-on-android-part-2/#.U58SqfldVHV - Needs Root. Did anyone succeeded in using this? Also, the solution seems very device-specific again.
Bluetooth + simulating mouse - That's not what I want. The phone itself should not be an HID device, but use the (virtually created) one itself. Same for this:
https://stackoverflow.com/a/8174973/2923406
Note that I do not want to turn my phone into an HID device of any kind.
Simulating is a broad term. When I created my Bluetooth app I "simulated" a Bluetooth connection in two ways.
Way 1: Use a serial port UART converter and hook it up to a Bluetooth module transmitter.
Then you can use a terminal program like CoolTerm, to send your data.
Like so. In this case I coded in a string to send on successful connection with the device however you can make a infinite loop for testing purposes effectively not requiring your phone to be turned into a HID device.
Way 2 (not easy): Use your computers bluetooth in a server/client relashionship model.
This is harder to do. What you can do is convert your pc/mac into a server and the Android phone into a client or vice-versa. For this you will need to write external code which will need to be compiled separately on a jvm(java virtual machine). The procedure to do this can be found here. If you are using a Linux machine you have to separately download the Bluez module. I have not tried this on any other operating sytem other than Ubuntu, and it was a pain to get functional.
Hopefully that helped.
Yes, it's quite easy using the AOA2 protocol check this & this links for details ( you'll need to switch your device to the Accessory mode )
This may be possible (or at least be easier) using the Robolectric library, which simulates a full Android device locally. Although it is intended primarily for testing, the fact that it simulates a whole device locally - including Bluetooth and USB - means adding to it may be an easier approach.
In other words, you may be able to modify the classes it uses to simulate these abilities locally (i.e. in the IDE itself without an emulator or device) in order to simulate them on the device itself. After all, it does provide full simulations of these functions. You could simply change these Bluetooth and USB simulating classes to load onto the device itself rather than onto the local Robolectric test "device."
This is just an idea though - I can't confirm this will work - it just might be a good place for you to start.

Converting iOS External Accessory Framework code to Android

We were given a bluetooth device that we were asked to connect both iOS and Android devices to a particular custom peripheral.
The demo app seems to bring up a list of devices, asking which to use, then brings up a list of protocols, which includes one defined in the info.plist under "Supported external accessory protocols" as com.(company).bt.
I looked all over and found nothing about this process being standard with Bluetooth, and the entire workflow appears to be different on Android. I've tried using the bluetooth sample app to connect to this device but the red connected LED never lights up, and depending on the UUID given, I either receive 1 byte or 7. The sample code I was given doesn't even touch the InputStream unless the stream has reached 16 bytes (Which of course, never happens)
Is there some sort of guide on how to connect to this device? Based on what I read from the code, a message isn't even sent until the user presses a button, but the LED is lit long before this is even an option in iOS.
Edit: I finally found something from clicking around - it seems that the plist entry has to do with mfi (Which I guess the documentation is only available to those in the program?) With that said, does that mean this device will only work with iOS devices?
As you mentioned connection in Android and iOS is done differently.
The protocol defined in info.plist should be the protocol you are meant to use with the particular Bluetooth chip you have.
There is a guide explaining how to connect in iOS, you should probably also check which Bluetooth version it is. If it is lower than Bluetooth 4.0 (BLE- Bluetooth Low Energy) or not. I assume it isn't BLE since you mentioned it is MFI...
1)If it is BLE use Core Bluetooth
2)Otherwise have a look at the following link: Introduction to Stream Programming Guide for Cocoa.
It is a bit hard to understand what you mean about the red LED because we don't know what device you are using. Considering you are receiving some bytes from the device it means that the communication was established. You can start debugging and perhaps understand better the code by changing it to "touch" the InputStream even if 1 byte is received...
Hope this helps.
Cheers!
EDIT: Just read the title again, I am not sure what you mean by saying you want to convert the code to Android? You only described your attempt to connect in iOS.
A quick Google search would give you the following links for Android guide:
1) Bluetooth (not BLE)
2) BLE

How to sniff Bluetooth traffic in Android?

I would like to know if there are any apps/api tools to track all the bluetooth connections happening in android? I tried using hcidump via BusyBox, but the trace is truncated, it does not display all the data I need.
I am trying to receive data from blood pressure monitor in android using Bluetooth HDP profile. However, the connection works at the beginning, and then stops. Therefore, I would like to use some packet sniffer to see the low level bluetooth connection for better debugging.
I found out that traces from hcidump tools are not truncated, and I think this is a perfect solution. However, I have to copy the trace from android to the pc evry time (e.g. sending by e-mail) and therefore it is a cumbersome work. Would be great if there was a tool to get access to the terminal emulator of android. Btw, BusyBox provides also some other very useful tools from Linux.
There are two options for this currently, the first is to use a software-defined radio that supports the ISM band (at least 2.4 to 2.485 GHz). This will allow you to grab any radio signals within the bluetooth range and will be especially useful if you're trying to identify interfering signals.
The downside is that you'll be receiving totally raw waveforms which you then need to demodulate using something like the gr-bluetooth stack.
The other option is a specialized device like the Ubertooth.

Get Wi-Fi protocol (802.11a/b/g/n) programmatically

Through WifiManager, my Android app can get a lot of details about Wi-Fi. However I fail to get protocol type like a/b/g/n. I have a client requirement to do that.
Does anyone know how to achieve that? (I don't have the option to use adb). It is to be done programmatically. I strongly believe that device and router have already negotiated protocol before they can connect. So that information is there with device. Question is, how do we get it?
You can partially deduce the protocol from the link speed
WifiManager.getConnectionInfo().getLinkSpeed()
By Wikipedia 802.11 protocols speed table you can tell if it is 802.11b, 802.11n or 802.11ag.
802.11n and 802.11ac full link speed tables
Link speeds of protocols 802.11a and 802.11g are the same, you can distinguish between them by the used frequency (5GHz or 2.4GHz) in the scan results.
Note that protocol can change during the connection, client and access point do negotiate protocols and speeds but they agree on a list and not on one specific speed.
I don't think there is a way to distinguish between 802.11n and 802.11ac in their overlapping speeds.
I don't believe this is possible to get in a clean manner. The protocols - a, b, g, n, etc - are actually human abstractions of the MAC and physical layer in networks. These are defined as their recognizable letters if they meet certain hardware specifications, both for the device and the network device.
After doing some digging, it seems that Windows phones are able to display this information. When digging into the manner of determining the protocol on Windows, I came across the desktop explanation as well as the Visual C++ implementation via enums. It seems that even the official Windows documentation relies on vendor-provided data and enumerated values, which would lead me to believe that they need to determine hardware specifications beyond what is likely exposed in the Android API.
If you want to determine the protocol yourself, you'll need to understand the link speed as well as the frequency, modulation, and bandwidth.
TL;DR
Likely not possible unless you are working with a rooted phone and can access the hardware specs directly.

Android Read USB Gamepad

I'm trying to read buttons pressed on a twin USB gamepad in android.
I tried all the methods available in USB package of android including bulkTransfer, controlTransfer, requestWait. but all of them always returns the same thing while pressing the buttons. I even can't get the real name of the device.
I installed USB\BT JoyCenter and it detects the key pressed and also show the name of the gamepad connected. I really can't figure out how to read the gamepad and android documentation doesn't fully cover how to do this.
I found out where the problem is. Actually I print out the byte array directly. I think java print byte memory location instead of it's content. I used a bytes to hex converter and it works fine now.
The first thing you might want to do is plug the device into a linux box and type lsusb. You need to find out what USB Classes are supported by the USB device. Post your answer here for others to see.
Then you need to determine if Android actually supports this class directly. If it does then things should be relatively easy (so read the manual). If not, you may need to use libusb or similar to do the actual low-level interactions. This would not be an easy path, but if the USB class is supported by libusb you can get there.
Once you know the class you are working with, you may find from the standard docos that you need to turn something "on" before it will start sending the data that you are interested in.

Categories

Resources