Bluetooth SPP mysterious bufferoverflow, Android / BlueGiga WT12, potential flow control issue? - java

The situation:
I'm developing an android app for some hardware that has a BlueGiga WT12 bluetooth modem. The hardware device sends 56 byte packets at around 240hz. I'm testing on a Samsung S5 and S8. A fully functional app has already been created for IOS and PC so we know the hardware device works.
I use a separate thread to read in the data and then dispatch it to the main thread.
Issue:
The issue I'm having is when I send the command to the device telling it to start streaming, it starts to stream but very shortly after I start receiving packets at a very slow rate 10-60hz.
After some examination I realized that the device was experiencing a bufferoverflow.
After talking to our hardware guy he said the only real thing that could cause that is something on the phone side not reading fast enough, resulting in the hardware device not wanting to send more packets because it thinks the phone can't receive anymore and then the buffer overflows on the hardware device.
The WT12 has flow control enabled so maybe this is an issue with Android not giving a clear-to-send signal to the WT12. But to my knowledge we don't have access to all of the flow control stuff.
What I've tried:
My first line of attack was to simply remove any code that I thought was slowing down the reads but that seemed to have no effect.
I also tried basically every bluetooth serial terminal app I could get my hands on, all with the same result.
So then I questioned if it was some weird problem relating to the hardware device but after using pc based (bluetooth) serial terminals I had no issues at all on the pc.
The hardware device can also operate over USB as opposed to bluetooth so I tried reading the data from it exactly the same as I had with the bluetooth connection but over USB. Using the USB serial connection I had no issues at all.
My thoughts:
So this leads me to believe the problem must be with the bluetooth modem on the phone side. I was thinking maybe it was a flow control issue as we have flow control enabled on the WT12. Maybe android isn't sending a clear to receive signal?
The problem is to my knowledge the flow control is implemented in the bluetooth stack and we as developers have no control over it if I'm not mistaken?
Other then flow control I don't really have much idea what could be causing the hardware device to not want to send me data.

I've just now been experiencing the same issues with flow control. Then I see that in case of RN4678 BT module, that it's best to disable the flow in the MCU FW and pull the cts pin low on the module. That worked for us.

Related

Controlling a device hardware via device admin or root

I need to have control over some admin features of android device.
Is it possible to acquire control over hardware not specified in android.app.admin.DevicePolicyManager like disabling access to microphone?
Also it will be good to find ability to track network connections or attempts to use network adapters by apps.
Maybe some command for root console or other way exist - how I can search for?
As far as i know there is no way to block any other hardware except camera with device manager. I believe that if your app takes control of microphone it will be unavailable to other apps, but i am not sure. Note that from android 8.0 no app is allowed to take control of microphone while in background.
About tracking network activity you could open vpn to monitor all packets that are sent and received.
Please keep in mind that i am not familiar with root methods so you should do some more research on this.

Android/Smack: Keep XMPP connection alive in sleep mode

I have an Android application that has a chat client as one of its features. The chat client uses XMPP based on the Smack library for Android and running Openfire as XMPP server in the background. The connection is established using BOSH The whole XMPP connection handling is implemented as a service to run and listen in the background for incoming messages even if not activity of the app is in the foreground. So far, everything works perfectly fine.
The only problem seems to be the sleep mode. In the emulator (when set to "Stay Awake") or with the phone in use, the XMPP connections is holding and the app can send and receive messages. However, once the phone goes into sleep mode, the XMPP connection breaks down -- I can see it in the Admin Console of the Openfire server that the user is offline. Intuitively, I want to receive messages all the time like, e.g., WhatsApp.
Of course, I've searched online including Stackoverflow, but I couldn't get a definitive answer. Often the use case seems to be that a task has to be performed periodically, say, once every hour. But this doesn't seem to fir in case of a chat client. Since I assume this is a common use case -- after all, there a so many chat apps or apps with chat features out there -- these are my question:
How to I have to change / extend the app that I can receive chat message while the phone is sleeping?
I've stumbled upon WakeLock. Is this the way to go or are these not suitable for my use case?
Since Lollipop, there's also the JobScheduler API which itself uses WakeLock. Any better?
How does, for example, WhatsApp handles this case?
On a side note: I have problems with the sleep mode using the emulator for debugging. When I switch off "Stay Awake" in the emulator, the screen goes black after 1+ min and the XMPP connection breaks. But I somehow have no idea how to wake up / switch the emulator back on once it went black. Android Studio actually tells me at some point that the device or something is gone, and I have to restart the emulator again.
The exact way to resolve this issue is by using push notification.
It is the natural behavior of XMPP connection to get disconnected after the specified idle interval i.e when the device goes to sleep.
Coming to the case of WhatsApp, it also uses the same XMPP and maintains a server which acts as a wrapper class on the messages exchanged. This server checks the message status whether it is delivered or not. If not delivered, it sends a push notification, now at the device end in the push service when a message is received, it checks if the connection is active and is authenticated or not.
If not authenticated, it re-establishes the connection. In this way, the most chat apps manage this timeout exception.
Hope this helps :)
You don't need push notifications, you don't need WakeLocks. Instead simply
Whitelist your app from doze mode
Use a sticky (START_STICKY) background service
Use Smack's ServerPingWithAlarmManager
Act on CONNECTIVY_CHANGED intents send by Android, and use XMPPTCPConnection's instantShutdown() in that case.

Analyzing serial communication that may not be fully RS-232 compliant?

I have an old java program that is communicating with an embedded device manufactured in 2000. The program communicates with this device using the standard Windows serial stack (from what I can tell, when I capture data using PORTMON in windows I see requests like IRP_MJ_WRITE and IOCTL_SERIAL_SET_RTS).
The device however, connects to a serial port on the computer using a Serial-to-Stereo Plug connector, similar to this. I believe this means the device itself is only capable of sending signals using two pins.
How can I analyze raw communication between the two devices in an attempt to reverse engineer the protocol? I am on Windows, but am capable of moving to OS X or *unix. I know at some point I am going to have to write something to deal with the specifics of how the device communicates, but what do you guys recommend for gathering information?
The stereo jack is just a cheap way to implement a minimal RS-232-based connection. That shouldn't affect monitoring.
Portmon should display the data you need to investigate the protocol. The IRP_MJ_WRITE requests contain the data sent to the device, while the IRP_MJ_READ requests contain the data sent by the device.
If you cannot do this by software interception means, a simple multi-channel logic analyze (such as one of the FX2 USB designs) should be able to capture traffic on both the transmit and receive lines, and then allow you to software decode this at leisure to see the full interplay of transmissions, responses, and any delays in between.

Bluetooth Android issue

I am running a multi thread application on android and adobe air, in native android 2 bluetooth sockets are set up and a couple of server threads for the air app to communicate with the bluetooth sockets of native android. It's basically socket programming and it all works on one device I used to programme it.
The device i used to develop this app was slow, i therefore got myself another tablet to test (android vega) and it is very fast at communicating my bluetooth data as it has 2.1edr version.
The problem is with the Advent Vega tablet the bluetooth streams just disconnect for no apparent reason intermittently and in the adb log window i just get trying to connect to device all of a sudden when the disconnect occurs, i have no mention of the crash anywhere in the log, this happens to both bluetooth connected threads at the same time so it must be something to do with the bluetooth radio im suspecting. The other tablet device runs the app fine but slower (no disconnects). I have even installed a custom 3.0 rom on the vega to see if it was a os problem but the disconnect problem persisted on 3.0 as well.
Due to the fact there is no mention of this in the adb log i am just basically staring at a screen with no idea of why it disconnects for 2 days now!! The only way to get the app to run again after this disconnection occurs is to restart the bluetooth on the device but this disconnect occurs again eventually when next run. It seems to improve the amount of time it stays alive tansferring data when the app is first run afater a re boot.
I have gone through all code of the run() and stopping() of each thread and it seems to exit gracefully, i close the bluetooth sockets only, it seems from research no need to close the bluetooth input and output but i have also tried that approach to closing.
Can anyone offer suggestions as to why both bluetooth read/write loops would just stop all of a sudden and disconnect? Seemingly effecting the adb log as well as it just says trying to connect...
Or any suggestions as to how to better debug when this occurs?
Or even what somebody else would do in this situation.
Hope someone can help, i have a great phone remote app for the android tablet owner community and it hinges on this final issue which i have been stuck on for 2 days.
I had problems with disconnects, and implemented a keepalive by sending a ping request and a ping ack.
This worked fine for me...

Implementing native android code with AIR code

After following these instructions to integrate Adobe AIR with native Android I have a few issues.
I have managed to get a bluetooth connection going in native android, setting up 2 BluetoothSockets which then shows the air app also packaged within the apk. This included air app requires 2 connections to somewhere (normally wifi).
I have it connecting to TestService1 and TestService2, which is then passing the traffic between these services and the BluetoothSockets.
It is a little slow as i have to put Thread.sleep(80) in between reading from bt socket and writing to the AIR app for it to work currently.
My 2 questions are
Is there any way to get the AIR app to know about and access the Bluetooth Sockets created in the Android code rather than having the 2 Services being the middle men?
Is this kind of release (hybrid) allowed in Android Marketplace does anyone know?
Really hoping to find an answer to question 1 as currently my bluetooth server is continously sending data and using the TestService1 and 2 to get this bluetooth data to the AIR app and is causing a 10 seconds lag.
Thanks in advance
These apps are definitely allowed in the Android market.
You should be able to send Bluetooth data immediately over the socket to the AIR app. It doesn't seem like you should need 2 separate services or a sleep. I think your service that is talking to the Bluetooth can also listen on a socket and send data over that socket when it gets it.

Categories