kai-morich / SimpleBluetoothTerminal

Android terminal app for Bluetooth classic devices using SPP profile
MIT License
447 stars 166 forks source link

Mysterious bufferoverflow, BlueGiga WT12, flow control issue? #3

Closed OuterObsessionSoftware closed 4 years ago

OuterObsessionSoftware commented 5 years ago

I'm developing an app for some hardware that has a BlueGiga WT12 bluetooth modem. The hardware device sends 56 byte packets at around 100hz. I'm testing on a Samsung S5 and S8.

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 1-2hz.

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.

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 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.

kai-morich commented 5 years ago

for fastest transfer you have to use a separate thread (see my SerialSocket.run) and dispatch incoming data to the main thread (see my SerialService.onSerialRead) then you should get up to a few kilobgte/second

OuterObsessionSoftware commented 5 years ago

Yeah I've used your SerialSocket and SerialService implementation, so as it stands the data's getting read on a separate thread and then sent to the main thread through listener.onSerialRead(data);

What doesn't make sense is even if I comment out socket.getInputStream().read(buffer); the device still gets a buffer overflow

kai-morich commented 5 years ago

I haven't done performance tests with my bluetooth app but for my usb app. There I noticed sporadic data loss for continuous data transfer at >= 38400 baud. This looks ridiculously low for todays GHz CPUs, but Android is not an RTOS and you likely cannot get much faster. With BLE you probably have more options to tune performance.

OuterObsessionSoftware commented 5 years ago

I had the same thought with BLE but when I mentioned it to my team they said it was tried previously with bad results. They said it didn't play nice because in our case we are dealing with a contentious data stream and apparently BLE doesn't like that or something.

On paper there should be more then enough speed to handle the data rates we're dealing with now.

My next experiment might be to disable flow control on the WT12 and see if that does anything.

OuterObsessionSoftware commented 4 years ago

I'm continuing the discussion on Stack Overflow, so far it seems like flow control just doesn't work properly Android.

https://stackoverflow.com/questions/57797272/bluetooth-spp-mysterious-bufferoverflow-android-bluegiga-wt12-potential-flow/57831249#57831249