I'm currently creating an Android App where it collects data through bluetooth and draw a real time graph but it seems like after short while there is packet loss and graph comes out weird. I've been searching for a while how to recover the loss but seems like there is no way.... only TCP/IP or UDP has.... Since I need all the data, I can't ignore the packets that doesn't have starting bit or end bit. Is there anyway to prevent the loss or recover the loss completely?
Thanks
Use of RFComm on Android already has built in packet order and reliability like TCP. You should try running tests to see if the Android device is too far away, receiving accurate information, has a bad Bluetooth module, or if the sensor is at fault.
Related
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.
I have developed an Android app that connects to a CC2540 BLE peripheral.
When I do a Characteristic write of type no response (WRITE_TYPE_NO_RESPONSE), I still get the callback onCharacteristicWrite at the app level. Is this behavior correct?
I understand there is probably a low level acknowledgement that occurs between the Android device and the peripheral.
But the reason I am asking is because this is causing an issue where I can only send a write once I have received this callback, which is slowing things down in the app.
Any light on this behavior would be appreciated it.
Thanks,
I did run into the same problem when I was trying to do some performance testing and found that when I used the WRITE_TYPE_DEFAULT specifically I stopped getting a response. There might be a bug with the android constants that is causing inverse behavior, but I am not quite not sure.
you can only make 1 transfer at a time on the low level so you need a callback to tell when the stack is ready to send another command.
If you try to send several after each other without waiting for the air-interface to be ready you can seriously crash the BLE stack! This was happening a lot on earlier iOS CoreBluetooth.
If one app crashes the BLE Stack then the phone need a reset or Bluetooth must be turned off and on again to reset the stack.
The callback just tells you that the stack has send a request over the air-interface, not that it was acknowledged by the recipient. For that you would use the other api which will make the BLE Stack re-transmit several times (depending on how the connection parameters has been negotiated).
It's stated clearly in the BLE specification that only 1 transfer can be made at a time.
If you just bang the API with write requ
I'm working on an Android application which sends/receives a high volume of UDP traffic to a Windows endpoint over a WLAN (and no, I can't use TCP).
The problem is that when I ramp up the traffic, I begin to see HUGE delays between when I call sendto (the app is written with the NDK) and when I see the packet arrive at the Windows endpoint. In the neighborhood of 10 seconds! The same thing happens in reverse too: I see huge delays between the packet being sent by the Windows endpoint and being picked up by recvfrom().
Changing SO_SNDBUF has no effect, so I don't think it's an issue with the application-level buffering control.
I've verified that the problem exists on a variety of Android devices, so I don't think it's an issue with the hardware/wireless drivers
Using a sniffer and correlating the timestamps, I confirmed that the delay is occurring between calling sendto() and the packet being sent from the Android device, so the buffering isn't happening in the AP or Windows endpoint
So at this point I'm all but out of ideas. The facts would lead me to believe that the buffering is happening on the Android OS layer, but 10 seconds of 10Mbps traffic? That seems too high to be feasible for an OS where memory footprint is such a huge concern.
Also, if the issue is that I'm sending data too fast and overwhelming the OS, then I would expect sendto() to return ENOMEM or ENOBUFS... But there are no indications that anything is wrong on the Android application level.
So my question is: what's causing this delay? And is there a way to mitigate it, or do I need to alter my application to have longer timeouts or some way of detecting this condition before it gets bad?
You are sending too much.. how much are you sending? 10Mbps is definitely way too high. Bear in mind:
Every UDP datagram you send has an additional 28 byte header (UDP + IP over IPv4)
Connection link speeds are theoretical maximum limits that you will never be able to achieve
The Phone OS could be limiting you, Phone OS's need to conserve battery and try to minimise socket comms to do so.
OR
You say your CPU is at 20%, how many cores do you have - you could be maxing out the core that is doing the sending, i.e. processing speed is the bottleneck.
For people with the same problem:
Try reusing the DatagramSocket. That solved it for me.
I've seen reports of very similar behavior on the linux-rt list lately, which may be related.
http://comments.gmane.org/gmane.linux.rt.user/10163
For a several months I was haunted with spurious jitter, detected on
UDP messages - multicast UDP messages where received on originating
node without any delay, but on other nodes a delay in range of 10s of
milliseconds was detected. Simply, it looked like a message was stuck
in kernel before finally getting transmitted.
Finally, thanks to LTTng tool, I was able to locate the problem down to
this peace of code in net/sched/sch_generic.c:
There appears to be a locking issue on transmit that causes the tx stall.
Ok, so here's my problem. I have an android app transmitting UDP packets to a PC (a java program which listens for the packets), based on user interactions with the android device. To keep things simple, let's say this is happening - the user taps the screen of the phone, and it sends a UDP packet with the coordinates of the point where the user tapped. The listener program receives and reads this packet, and outputs the string received, using System.out.println().
Now, what's happening is that the program works perfectly for the first few packets. Then it stops working, as in, the listener program on the desktop does not display any output. Now, the issue is probably with the transmission, as I have a text label on the app (for testing purpose) that displays what is being transmitted, so the transmission packet is definitely being built properly. But I have no idea on how to understand if this is a problem with sending the data (on the android device side), or receiving (on the desktop side). How can I find out what's wrong and solve this issue?
I have mostly worked with TCP transmission and all the UDP i have done are mostly Copy-Paste [:-)] or with APIs
For TCP, after transmission, I throw a debug message, which helps me to know that the transmission occurred properly. But in this case, your write will have to be blocking.
Also, you could use a Packet Tracer on your listener terminal to determine whether it is receiving the packets properly. The one I love is WireShark (I think its a fork of Ethereal). Its really easy to use. You tell it which interface to listen on and give a filter and it will list out the packets as and when they come.
However, if you are using Windows 7, you will need admin privileges.
Are you using native code or Java classes? I have tried both, and with the NDK (i.e. sockets written as C functions being called from Java) I have seen erratic behavior on the server side, mostly due to threading issues. Using the Java Socket class I have not had issues however. Moreover, if your Android app is the client, that should not be the problem. I would also use Wireshark to check whether the packets are reaching the PC.
I am building an app that converts text messages to speech and sends them to the destination. At the other end, the speech is converted back to text messages.
I imagine it may be easy with Twilio but I don't want to use internet connection. A simple call should be enough to transmit the data.
Any idea on how I should proceed with this?
I don't think this is really possible to do, your tasks would be pretty heavy ...
TTS- that's no problem android has a library for that TTS and recording it
Make a phone call and monitor state Make phone call monitor state
Send your synthesized message - can't quite find a way to do this, seems problematic sending recorded messages over phone network it has been suggested that you could play the recording over the speaker and the microphone might pick that up, seems like a good way to introduce even more errors into the system though
On the other end something must answer - Answering a phone call
Record incoming call - this seems to be highly problematic on a non-rooted phone Recording incoming calls? or Recording incoming calls
Take the recording and do reliable STT without the benefit of a server back end, also highly problematic since the translation errors even on high end server apps are sometimes quite comical
So without a rooted phone with a custom rom I don't think all of this is possible even if you could overcome the poor quality of a double translation TTS -> STT
Twillo seems to be about making calls over the net vs. the phones digital network not about sending text (in essence) over a phone connection
Seems like a whole lot of extra work just to avoid an internet connection charge (of about 2 seconds and few bytes!)