Manufacturer Specific Data on BLE - bluetooth

I'm a newbie of BLE programming on android.
In my first apps using BLE on android, I have a big problem.
I got a ScanRecord from Apple Bluetooth Headset using this function.
#Override
public void onScanResult(int callbackType, ScanResult result)
and I got a manufacturer data using Apple corp, ID(0x4C).
after that, I don't know how to decode a manufacturer data.
I want to auxiliary bluetooth headset information such as battery info, direction info etc. but I don't know how to decode the manufacturer data.
I also searched Apple development document(https://developer.apple.com/accessories/Accessory-Design-Guidelines.pdf)
But that guide document didn't help me.
Anyway, anyone who tell me how to resolve this problem?!!?!
Thank you to read my question.

Ok so from your comment it looks like you scanned the device over BLE and want to use one of the services it offers to get information like battery info.
The first thing you will need to do establish a connection to the BLE device.
The scanresult you pasted has a method getDevice you'll need to call
After you get the device you can call its connectGatt method. This will attempt to connect your phone and BLE device.
The connectGatt method from step 2 requires a callback. When the connection is successful or unsuccessful the callback will fire onConnectionStateChanged. If successful it will have the success status. This method will also give you a gatt device we will use in step 4.
If step 3 was successful we can assume your phone is connected. The next thing we want to do is discover services. You do this by using the gatt devices discoverServices method.
When the services are discovered your callback will fire onServicesDiscovered. At this point you can now use services. Depending on the API of the headphones they'll want you to read, or subscribe to a services characteristic and descriptor. Since I don't know the API I can't help you further. But you'll end up needing to use one or more of the following:
setCharacteristicNotification
readCharacteristic
readDescriptor
And the value will return to your callback on. Keep in mind you must wait for the callback for each request before write/reading/subscribing to another characteristic or descriptor.

Related

HM-10 BLE Module - connect to other Devices

first of all: What i am trying to do is only for private interest.
I'd like to connect a AT-09/HM-10 BLE-Module with Firmware 6.01 to another device which provides also a BLE Module, which it is not based on the CC254X-Chip,
I am able to communicate with this Device using my Laptop with integrated Bluetooth, Linux and the bluepy-helper. I am also able to make a connection using the HM10 through a USB-RS232-Module and "Hterm", but after that quite Stuck in my progress.
By "reverse-engineering" the Android-Application for controlling this particular device i found a set of Commands, stored as Strings in Hex-Format. The Java-Application itself sends out the particular Command combined with a CRC16-Modbus-Value in addition with a Request (whatever it is), to a particular Service and Characteristic UUID.
I also have a Wireshark-Protocol pulled from my Android-Phone while the application was connected to the particular device, but i am unable to find the commands extracted from the .apk in this protocol.
This is where i get stuck. After making a connection and sending out the Command+CRC16-Value i get no response at all, so i am thinking that my intentions are wrong. I am also not quite sure how the HM-10-Firmware handles / maps the Service and Char-UUIDs from the destination device.
Are there probably any special AT-Commands which would fit my need?
I am absolutely not into the technical depths of Bluetooth and its communication layer at all. The only thing i know is that the HM-10 connects to a selected BLE-Device and after that it provides a Serial I/O and data flows between the endpoints.
I have no clue how and if it can handle Data flow to certain Service/Char UUIDs from the destination endpoint, althrough it seems to have built-in the GATT , l2cap-Services and so on. Surely it handles all the neccessary communication by itself, but i donĀ“t know where i get access to the "front-end" at all.
Best regards !

ESP32 A2DP Headphones bonding issue

I am fairly new to working with Bluetooth and the ESP32 Bluetooth stack, so forgive me if I don't use the right terminology.
I can get the ESP-IDF Development example "A2DP_Source" working perfect only if I enable the headphones pairing mode first. After it is paired, and the bonding is stored in the Bluetooth, it will reconnect to the headphones without issue, but it then does not notify the app through the call back functions that it has connected. The app then continues to search for a bluetooth device and the audio streams sporadically, or not at all.
I've tried multiple speakers, and headphones, all with the same results.
I can see the bonded device list also and the device is there.
Is there callback function in the bluetooth stack that needs to be initialized to notify the app that the bluetooth connected to a previously paired device instead of just a device in pairing mode?
These are the three callback functions setup currently that run when connected through pairing mode, but don't run when the bluetooth connects in non-pairing mode.
...
/* register GAP callback function */
esp_bt_gap_register_callback(bt_app_gap_cb);
/* initialize AVRCP controller */
esp_avrc_ct_init();
esp_avrc_ct_register_callback(bt_app_rc_ct_cb);
/* initialize A2DP source */
esp_a2d_register_callback(&bt_app_a2d_cb);
esp_a2d_source_register_data_callback(bt_app_a2d_data_cb);
...
Any help or pointers would be appreciated. Thanks.
Did you mean ESP32 A2DP cannot connect a device without the push of a PAIR button?
The example "A2DP_Source" does not seem to connect the bonded device.
It just tries to discover the device with the certain name ("ESP_SPEAKER" in the original code) calling the function esp_bt_gap_start_discovery.
If the device is found, bt_app_gap_cb is called and then the connect to peer will start via esp_a2d_source_connect.
So I suggest fixing the code so as to connect peer instead of calling esp_bt_gap_start_discovery if there is any bonded device.
You can use the function esp_bt_gap_get_bond_device_list and find out the address of the bonded device which is required by esp_a2d_source_connect.
The API reference is available in https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gap_bt.html and https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_a2dp.html.
Working through this problem more, I found that using C++ to call the native C code was the issue. I don't have a strong enough background in coding to understand the "why" it did not work, but once I returned all the code back to "C" it started working without issue. Hope this helps someone else who may make the same mistake.

Reverse engineering Bluetooth LE - device sends weird responses back

I recently aquired a Segway Ninebot ES2 electric scooter. I can connect to the scooter via Bluetooth LE and grab information such as battery status, current mileage, temperature, and so on. This is all done through an application.
On my Android device, I've successfully extraceted the HCI log file, which I imported into Wireshark. I can see all the requests and commands send back and forth between my phone and the scooter. However, the requests and responses are all garbage and I have no idea how to interpret them.
Example of a sent command (info says Sent Write Command, Handle: 0x000e (Nordic UART Service: Nordic UART Tx))
Example of the received value I got right after (info says Rcvd Handle Value Notification, Handle: 0x000b (Nordic UART Service: Nordic UART Rx))
How am I supposed to interpret these responses? If the battery status was 59%, I would expect it to return something like 0x3b (0x3b hex is 59 decimal). But honestly, I have no idea how this works. Maybe they're returning a bunch of data in a data type only their app knows how to interpret? Like JSON for web.
Here's an example from the nRF Connect for Mobile application, where I hit the down arrow on all the characteristics: https://i.imgur.com/hREDomP.jpg (large image)
And probably more important: How do I replicate a request or command in nRF Connect? I've tried sending a byte array that looks like 0x {02410011000d.....} (from the Write Command) in the application, but I have no idea how to read the response.
If someone is still interested, I did the same research for this scooter.
That's standart BLE communacation, device offers BLE "services" and "characteristics". Service can contain one or more characteristics, by which you communicate with device. Each charateristic can allow different types of interaction with it: writing into it, reading from it, subscribing to notifications (so you dont have to to manually read, it kinda pushes data to your app), and more (read here, for example)
Take a look at your wireshark screenshot: you can see Service UUID, Handle UUID (the characteristic), and handle ID. You can communicate with device via uuid or id, depending on your programming language or library (more about uuids).
In this particular scooter there are two characteristics, one allows writing into it, another - allows subscribing to it. Together, they act like RX and TX wires in UART: you write data into one and read from another. So, to begin communication with scooter you must establish connection to it, subscribe for notifications from one ch, and write data to another.
As for protocol: look again at she screenshots, "UART Tx" is the actual payload that was sent to scooter and "UART Rx" was the response. Yes, it's binary data, that only app would understand. Luckily, protocol has been reverse engineered and is well documented. In your example app requests serial number, and it's returned in response - "N2GWX...". In order to request battery percentage you must build another payload according to protocol.
I'm not sure if it's still relevant, but at least for those, who will be interested in the topic.
You can try the following to understand how to interpret response from the device.
An option to consider is to fetch manufacturer's mobile app (apk) either by adb or from sites like apkmirror, etc.
Then apply some reverse-eng tool like JADX.
If you're lucky and the code is somewhat readable, then search for smth that has to do with response (like ResponseParser) and try to find algo that is used to interpret the response.
However, the very first attemp should always be to search on github/google if smb did it already for your device, unless it's very niche.

BLE Pairing from microcontroller

As part of my requirement, we need to have paring connection between microcontroller (Cortox M3) and Mobile or Pc. We are using Alpwise stack for our purpose. My problem is with the controller configurations, not with the mobile, because without paring i am able to work with it.
Where should i the API "BLESMP_InitiatePairing" api. Presently i am calling the api inside GAP_callback function, inside BLEGAP_EVENT_CONNECTED.
Is this a correct location to call at this API, because if i call over here, control goes to BLEEVENT_PAIRING_COMPLETE (returning SMERROR_UNKNOWREASON) then it goes into BLEEVENT_PAIRING_REQUEST then once again it goes into
BLEEVENT_PAIRING_COMPLETE (returning SMERROR_UNKNOWREASON). Whereas when i call "BLESMP_InitiatePairing" api, it returns me with success message
(You listed the core-bluetooth tag, so I'm assuming you want to use iOS.)
I don't know the specific stack you are using. However, if you are developing an LE peripheral and want to connect with an iOS device as central, it is sufficient to reply to a read / write request with an InsufficientAuthentication error code. iOS will then initiate pairing from its side.
More details on this process can be found in the Bluetooth Accessory Design Guidelines for Apple Products Section 3.9.

Sending SMS using Java ME application

I want to a Java ME application that transfers any SMS received to a PC using bluetooth. The PC can then direct the Java ME application via bluetooth to send a response SMS. Is there library available for this architecture or I have to design it myself?
Is this approach correct or a better one exists? I want to use bluetooth as then I will not have dependency on the cable.
You'll need to create this yourself, however you'll find that you can't do what you want with J2ME.
J2ME can't access any old SMS that the handset receives, only ones sent to a specific port upon which the MIDlet is listening. So to get all the other SMSes, create a bluetooth serial/dial-up connection to your handset in the way I've described in this answer.
Create a PC client which repeatedly issues AT+CGML commands (as described in the AT command set document linked to in the answer above), to see when an SMS has been received. Use AT+CGMR to read and parse the message text. Then use AT+CGMS to sent a response. This can all be done over bluetooth.
It's better to use the serial connection to send a response, because a MIDlet cannot usually be triggered to open based on incoming bluetooth data.
Hope this helps.
You may have already achieved your task, anyway for the reference I think it is much better if you try using Gammu . I'm using it for the same task (Send / receive SMS through PC ) with a simple bat file I have written, works like a charm.
Anyway you don't need any J2me program for this.
Wammu takes care of making the connection to phone and sending AT commands.

Resources