Send data using over bluetooth using different protocols - bluetooth

I have an app that communicates with a bluetooth device, and I'm trying to replace that app with some code.
I tried using C# InTheHand nuget, Microsoft's Bluetooth LE Explorer, python's sockets and others to send data and see what happens.
But there's something I still don't understand - in each way using different libraries I saw in wireshark a different protocol: ATT, RFCOMM, L2CAP...
When I sniffed my bluetooth traffic from my phone using the app mentioned before, I saw mostly HCI_CMD protocol traffic.
How can I choose the protocol I want to send? Is there a simple package for that? something to read?
Do I need to build the packet myself? including headers and such?
Thank you!
Update:
Using Microsoft's Bluetooth LE Explorer I was able to send a packet that lit up my lamp, starting with 02010e10000c00040012(data)
Using bleak I was able to send a packet starting with 02010e10000c00040052(data)
the difference makes the lamp not ligh up and I'm not sure if I can change it via bleak as it's not part of the data I send

I think what you are showing is that bleak does a write without response while MS BLE Explorer does a write_with_response.
Looking at the Bleak documentation for write_gatt_char that seems to be consistent as response is False by default
write_gatt_char Parameters:
char_specifier (BleakGATTCharacteristic, int, str or UUID). The characteristic to write to, specified by either integer handle, UUID
or directly by the BleakGATTCharacteristic object representing it.
data (bytes or bytearray) – The data to send.
response (bool) – If write-with-response operation should be done. Defaults to False.
I would expect the following to have the desired effect:
await client.write_gatt_char(LIGHT_CHARACTERISTIC, b"\x55\xaa\x03\x08\x02\xff\x00\xff\xf5", True)

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 !

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.

bluez endpoints not working for an audio source

I am trying to play audio from Raspbian to a bluetooth speaker using A2DP.
From looking at test/simple-endpoint in the bluez source, it appears that running it without arguments should register an endpoint with the A2DP_SOURCE_UUID of 0000110A-0000-1000-8000-00805F9B34FB. However, I don't see any of the endpoint's callback methods being called (SelectConfiguration/SetConfiguration) when using bluetoothctl to connect to a bluetooth speaker. I tried with two different types of bluetooth speakers.
If I instead run simple-endpoint in "sbcsink" mode, and then connect my phone to it, I do see the endpoint's methods called (SelectConfiguration/SetConfiguration). So endpoints appear to be working for the A2DP sink uuid, but not the source one.
I'm able to find a org.bluez.MediaTransport1 corresponding to the bluetooth speaker by iterating through dbus managed objects:
import dbus
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object('org.bluez', '/'), 'org.freedesktop.DBus.ObjectManager')
for path, ifaces in manager.GetManagedObjects().items():
transport = ifaces.get('org.bluez.MediaTransport1')
if transport is None:
continue
transport_obj = dbus.Interface(bus.get_object('org.bluez', path), 'org.bluez.MediaTransport1')
(fd, read_mtu, write_mtu) = transport_obj.Acquire('w')
taken_fd = fd.take()
print(path, fd, taken_fd, read_mtu, write_mtu)
I'm able to write to the transport's file descriptor taken_fd, but I can't control the audio configuration like I think I would if the transport had been acquired via a org.bluez.MediaEndpoint1. Also this seems kinda hacky, I'm not sure this transport is meant for me to access in this way. I would expect to get access to the transport via MediaEndpoint1's SetConfiguration.
I observed this behavior with bluez 5.43 on Rasbian Stretch. I also tried updating to the latest bluez 5.50 and saw the same behavior.
What is the expected way to use bluez as an audio source?
I figured out the problem by running bluetoothd in debug mode, and found that SetConfiguration/SetConfiguration was being called on a previously registered endpoint with a path of /A2DP/SBC/Source/1. Searching online for this path led me to discover that it was associated with bluealsa, which was registering the endpoint on system startup, and then was receiving the media endpoint callbacks instead of my endpoint. After killing bluealsa, my audio source endpoint was then able to receive the media endpoint callbacks as expected.

Unable to read Azure IoT hub MQTT subscription message data

I have successfully connected my ESP8266 Arduino project to the Azure IoT hub by following the steps outlined here:
https://azure.microsoft.com/en-gb/documentation/articles/iot-hub-mqtt-support/
The MQTT library that I am using is the following library:
https://github.com/Imroy/pubsubclient
Using the code I have been able to publish events to azure. The problem starts when trying to read the messages that are passed to the device.
Here is the code:
http://pastebin.com/7AVLQfFh
When I sue the Azure Device Explorer to send a message to the device the I get the following results:
As you can see the payload length is the same as the number of characters in the message but the characters are not the same. And also if I vary the string sent then the vales in the result are the same.
As a sanity check I have tried the code against a different MQTT service (Adafruit IO) and the results are as to be expected (here the message is 'ON' or 'OFF'):
The Azure MQTT service must be doing something different when it sends the messages to the device, what I needs to know is what it does differently.
Just a couple of hours ago I managed to get the messages flowing from Azure IoT hub to my ESP8266 using the original PubSubClient - link here. You are using the fork of that library that has been made more object oriented and probably has more enhancements.. but if you aren't very hooked on using the newer version I'd recommend getting the original one and trying it out.
I have my code on github if you need some reference: link
One important mention: the PubSubClient.h needs changing the #defineMQTT_MAX_PACKET_SIZE 128 to #defineMQTT_MAX_PACKET_SIZE 256 or more if you work with big packets
Also, I haven't tried to send any messages so I don't know how that'll work.
Update: I've also written a short blog post on how to set it up: link
According to this documentation page, property_bag is RFC2396 encoded.
RFC 2396-encoded(<PropertyName1>)=RFC 2396-encoded(<PropertyValue1>)&RFC 2396-encoded(<PropertyName2>)=RFC 2396-encoded(<PropertyValue2>)…
But isn't ABCD the same in plain text vs URI encoded you ask... Well, yes.
Install stunnel (https://www.stunnel.org/index.html), open a TLS 1.2 connection to IoT Hub on 8883/TCP and then point MQTT.fx or Paho to it and sniff the traffic with Wireshark, see what you get.
I was able to read all messages in plain ASCII text while talking to IoT Hub over REST, so whatever this is i think it's MQTT specific.
If you haven't done so already you should open an issue on their GitHub. They seem to be quite responsive: https://github.com/Azure/azure-iot-sdks/issues

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