If a Bluetooth server has a notifying characteristic and the remote client writes to the descriptor of this characteristic the value DISABLE_NOTIFICATION_VALUE , then how must the server cope with this descriptor write request?
Must the server software refrain from calling any GattServer.notifyCharacteristicChanged() , or will the Bluetooth stack prevent sending notifications to the client after GattServer.notifyCharacteristicChanged() has been called by the server software?
The server should only send a notification over the air if the corresponding notification bit in the descriptor is 1. Whether the application software is the one that should do this check or the bluetooth stack does this for you is implementation-specific. I guess most bluetooth stacks do not do this for you.
If you wonder about Android, I can't see clear documentation whether this is done or not, so you'd better do it yourself.
Related
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 !
I'm working on a project that requires BLE Serial Profile.
I have successfully implemented it, but now I'm wondering what happens when server is sending data to the client, and client wants to send data back (while server is still sending). Is this handled on the low level with a queue or something similar?
Is there any risk that messages will get lost?
Thanks for any help.
Bluetooth provides the effect of full duplex transmission through the use of time division duplex (TDD). In principle transmission and reception do not happen at the same time. So in your case there is no risk of collision (loss) of data packets.
As you can see "Central" and "Peripheral" have a window of 625us during which they transmit.
For further details you can read "Timeslot" chapter of the base band specification in Core Bluetooth specification.
https://www.bluetooth.com/specifications/specs/core-specification-5-3/
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.
Currently we are setting up a Bluetooth LE device specification and we are running against the following:
The client doesn't want to pair the device via the settings menu. There is a mobile app which should connect to the peripheral.
Now the following, this is the problem:
When connecting, how do we secure our characteristics? We were thinking about prefixing a write request, but what about read requests?
We don't want everybody to see the not so sensitive data. Since it's not sensitive we don't need high security but we still need to secure it some way just in case.
Does anybody know how to do this? How to secure a characteristic?
Thanks in advance,
You could implement a challenge-response system on connection - when you connect to the peripheral you read a value from a characteristic which is randomised by the peripheral. This value has to be hashed in some way using a shared-secret and then written back to the characteristic. The peripheral then verifies the hashed value. If it matches then it populates the other characteristics and accepts write requests.
Once the central disconnects from the peripheral it ignores write requests and zeros its read characteristics until the next connection/hash handshake.
You must add Security Mode 1 Level 3 to your Services. Then, all the Service's characteristics will be protected.
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.