Bluetooth Android RFCOMM / SPP error handling suggestions - android

I am planning a communication protocol to be used between an Android device and a custom sensor that would use a commercial Bluetooth module. I would use the SPP profile that is said to "provide a simple reliable data stream to the user, similar to TCP."
I am not so familiar with the Bluetooth technology and have some questions about designing such a protocol.
First of all it is not clear to me if I have to worry corrupted data being transferred or not. Will the underlying protocoll stack guarantee me that the bytes I read from the InputStream Android gives are the same that the UART receives on the sensor side? Do I have to define my own data packages protected with CRC or stuff or would it be overkill?
It is not clear to me from the Android Bluetooth documentation what happens in my application if the signal is weak and is lost for a while. Do I get IOException at once or the platform provides me some hidden error handling and recovery that would make such short outages invisible to me?
Thanks for any advice.

You need not worry about data corruption over SPP , Bluetooth provides 2 levels of CRC , one at the baseband and then one at the L2CAP level,
Both have retransmission mechanism for any detected corruptions - thus applications will receive only good packets.
About the second question - Yes on the Socket streams that you are connected on you will receive IOExceptions if the underlying Bluetooth connections get disconnected, Android cannot handle automatic restore - typically applications need to detect the reason for disconnection and try re-connect as applicable.
So if you want to continue your data exchange from the point you last successfully received / sent then for it your application should maintain some sort of sequence number and light protocol to achieve a resume.
The other option is to simply start from the beaning of data exchange upon a re-connect (So it depends on your usecase)

Related

Data transfer via bluetooth between paired Android and Raspberry PI

I am working on a project where I need to transfer data between android and raspberry pi via Bluetooth. However, I am new to this and I don't have deep understanding on what happens when two devices are paired. Based on assumption that the two devices of interest are already paired, where would the starting point be for programming for such task? I've been reading on BluetoothSocket, but I am still unsure of where to start. Can anyone help me please?
Thank you so much in advance!
I have been looking into this same issue, here is the reading I found on my end. I was looking to specifically code in python so that's the angle of the first one, the second is C++, but has a really thorough intro.
https://people.csail.mit.edu/albert/bluez-intro/index.html
and this one is really good too, the intro isnt too dense:
http://beej.us/guide/bgnet/output/html/multipage/index.html
The specific parts to look at involve the planning aspect. The intro of the beej programming guide shows specifically what sockets are and how they fit in a network sense. This means streaming sockets and datagram sockets. It also shows which of the sockets are used and which are availible. Chapters 1 through 3 gave me a solid enough reading basis to use the second document to determine a few things.
Chapter 2 of the MIT document goes into specific detail about each of the steps that must occur at a structural level including L2CAP + UDT, RCOMM, and whatever the stream one was. From reading these I was able to determine that the network I wanted to use was an L2CAP. I hope these help point you in the right direction though as far as what network you want to setup and what language you want to program in.
I've been working on the same task little while ago. The point is, that in order to start sending and receiving data you have to establish connection first. There is two side- device which connects (creates socket) and the other receiving connection (bluetooth server socket), giving out connection once connection is complete. After connection is established, you should stop receiving incoming connection or attempting establishing any connections.
From implementation perspective, you should implement few threads for managing all those stages - connection thread, accept thread, communucation thread. There is a great example from Google: https://github.com/googlesamples/android-BluetoothChat . It uses that technic. The only drawback is that it uses Handler (Android feature, allowing thereads to communicate) for informing user about Bluetooth events. I modified it a bit by introducing another thread, receiving status updates and calling methods from callback interface, feel free to use code from project: https://github.com/AlexShutov/LEDLights.

Is there a way to communicate reliably via Bluetooth?

I have to exchange data between two bluetooth devices, one of them will be an Android device. For simplicity's sake you can assume the other device will be a generic linux device running bluez producing data similar to the data a fitness tracker would produce.
The scenario seems a straightforward use case for Bluetooth Low Energy. The problem i am currently running into comes from the fact that communication has to be reliable (reliable in the way TCP is reliable). This means:
no losses
no corruption of data
order needs to be preserved
no duplicates
no phantom packets
While losses are prevented at link layer level, the order for instance seems not to be explicitly preserved when working with Low Energy (using indications would probably achieve this).
Not having done a lot of work with Bluetooth I am currently overwhelmed quite a bit with the amount of options while at the same time no option seems to fit the bill nicely.
Is there a "best-practice" for setting up reliable communication between two bluetooth devices? A Bluetooth Low Energy solution would be preferable, but is not mandatory.
Once your Bluetooth connection is setup its reliable. So you don't have to be worried about data loss or corruption.
So the things you're worried about can be easily handled in your side. You'll get proper connection and disconnection callback while setting up a BroadcastReceiver for your BluetoothAdapter.
In case of any disconnection you may have to restart the procedure for connection again and once its established properly you may resend the data.
I don't know about your purpose yet, but one thing I need to mention here is, I would not recommend Bluetooth communication if you're holding the connection for long time. Some devices disconnects the connection automatically after some time if there's no continuos transmission.
Android has Bluetooth support, but it only allow to send ot receive data from stream. There is a very good sample project from Google: https://github.com/googlesamples/android-BluetoothChat . The only drawback of this sample is that it use Handler to nitify about Bluetooth events. I changed it a bit so it use another Thread and from it calls methods of interface you set, take a look at project: https://github.com/AlexShutov/LEDLights . This is ordinary Bluetooth, not BLE, hope it will help
Android's BLE stack is as good as the link layer specification. So you can use "write without response" in one direction and notifications for the other direction. Just make sure your peripheral side does not drop incoming writes.
BLE uses 24-bit CRC. for the amount of data transmitted using BLE the CRC is quite robust and the possibility of corruption is very low ( note that TCP CRC is 16bit and the Ethernet CRC is 32bit, please see http://www.evanjones.ca/tcp-and-ethernet-checksums-fail.html).
The ordering issues in wired network is a result of routing packets through different routes to the same destination ( plese see If TCP is connection oriented why do packets follow different paths?) . This is partially due to the use of sliding window acknowledgement protocol, which allows a number of packets to be transmitted before being acknowledged.In BLE there is no routing and the acknowledgement scheme is a variation of stop and wait ARQ scheme(2-bit lazy acknowledgement), this means that it is not possible to send a new packet without being acknowledged. These two factors makes the possibility of having an out of order transmission highly unlikely.

BLE: Why are Write Commands slower than Notifications?

In the context of BLE (Bluetooth Low Energy), Write Commands can be used to write from a Client to the Server, and Notifications to write from the Server to the Client. In my setup, the Client is a Central device (Android phone), and the Server is a Peripheral (dev board).
After performing several data throughput tests with multiple phones, I noticed that the throughput varies greatly with the phone, which is expected because a great deal of the BLE lower layers implementation is up to the manufacturer to figure out. But what caught my attention was that Write Command always achieve a much lower throughput that Notifications, independently from the phone. Why is that?
They should have the same throughput. Multiple write commands and notifications can be sent during one connection event. They are treated the same.
You could use an air sniffer to see if you find any problems.
How long the connection event should be open can be suggested when the connection is created and with connection parameter updates. Sadly, Android's BLE stack hard codes this to the default value, which means no recommendation. That will in practice mean you are limited to 3 or 4 packets per connection event.

How to send message between two Android devices via bluetooth or BLE?

Is it possible to send messages bi-directionally between two Android devices via bluetooth or bluetooth low energy? You can assume that each Android device has the same Android app running. If so, could you please share how this might be possible? Thanks!
Yes it can be possible, but is not so easy. First you need to read documentation
Android bluetooth
and later try find some example which will resemble your needs.
Example : bluetooth chat
Comment : I did communication android with special hardware (I think FTDI Chip), but with Xamarin .NET. Some things will be the same. Mostly it is done so that the UI, creating communication and data transfer are in a separate Thread. In reading thread you have endless cycle in which the reading bytes from the input stream and save it into temp buffer (impeding receipt and you will not lose bytes). Later moves to MainBufferu and work with them.
UPDATE
You have to read the documentation and explore example. I can not describe everything here. I can roughly describe the lifecycle of how I dealt with itself:
When you have paired the device (you get BluetoothDevice) start ConnectThread which opens RfcommSocket and try Connect on it. If it is OK, than start ConnectedThread where you have endless cycle of reading data from InputStream. In cycle You put your data into a temp buffer and once in a while moved data into MainBuffer where do you take them for processing. If you want send data via Bluetooth, you will just write to the OutputStream in ConnectedThread.

Can a bluetooth or wifi stream (spp) ever miss bytes or have corrupted ones?

Something is troubling me for years.
I work with a lot of bluetooth and lately wifi streams (spp). Those streams always connect to specific devices and communication happens via simple byte commands.
Some of the devices (their microcontrollers) i program myself and there i have to always check if the signal on the wire is what i expect, send and check for crcs.
Somehow i want to do the same on my smartphone because i access my streams with "readByte" and read byte by byte and i am always wondering if it is actually possible that
a) one byte from a message can be missing
b) messages arrive mixed or "out of sequence"
I have no idea how much the underlying hardware does. Does it check every message with crc and requests the message again if it was corrupted ? Or does it blindly pass every byte through to my "readByte" method ?
If the device sends message a and then b, is it possible that the receiver receives b before a and passes my code b before a or even mix up the bytes like a zipper and give me a[0] then b[0] then a[1] and so on.
How much trust in those streams should i have ? Some clarification would be appreciated
I think you can sleep well. WiFi and Bluetooth based on packet switch network, each packet comes with crc, and physical layer has built-in congestion and link quality control - so, aside from ultra rare firmware bugs, it is actually more reliable than wired serial connection.
In other words - error correction occurs at lower level than you are using..
Answer to question about packet arrival order: point to point protocols aren't affected by this problem. Packet reordering occurs when they travel by different routes, thus no problem when there are no other routes.
You will get same bytes in same order if you are using byte oriented streams over those protocols, because they are designed with this goal in mind. Packet access, on the other hand, is not, but Android doesn't provide you means to use it.
I feel like If you ever learnt about Computer Network OSI Model, you will understand what I am talking about better.
First, TCP/IP has nothing in common with Bluetooth. TCP is a transport level protocol whereas Bluetooth would be a lower level protocol. Thus you could use TCP or UDP on top of Bluetooth just as you use TCP and UDP on top of Ethernet.
Second, When data transferred through bluetooth devices, TCP protocol would be used. The TCP use congestion recovery algorithms to ensure data is transferred exactly. Modern implementations of TCP include four intertwined algorithms for flow control: slow start, congestion avoidance, fast retransmit, and fast recovery. So, If you want to know more about this, you may search the internet. Because they would rather be more theoretical than programmatic.
Well of data corruption i don't have any good idea.
But "mix up the bytes like a zipper and give me a[0] then b[0] then a[1] " should not happen.
I built app that parses nmea messages form external bluetooth gps. I don't check anything and some how my app works stable.

Categories

Resources