I have an application that needs to acquire data from a device connected to a WiFi Network. The device has a built in WiFi Module so the application has to connect to the module's WiFi Network and start to acquire data. Important: This network IS NOT connected to Internet
The problem is that in some devices (Samsung J7 neo, Samsung J1 Ace... etc) I can get a constant data transmission rate, but in others I can't (Specifically in Tablet Samsung Gallaxy Tab A, for example).
The acquisition module generates data at 37Kb/s and It can buffer up to 1Mb of data, but the buffer gets full and overflow.
- I'm reading all I can in intervals of 500ms
- I tried using C++ and Java Sockets (in a test application) with the same result
- I'm using WIFI_MODE_FULL_HIGH_PERF to maximize the WiFi performance
- I'm disabling cellular data network
I know that I'm demanding real-time behavior to an Android application, but I can't beleave that I can not get a transmision rate of 37kb/s over this WiFi network. I know that the problem could be in the acquisition module (I don't have much control over that) but the strange thing is that the comunication works perfect with a lot of android devices.
I will try to sniff the WiFi network to see if I find something, some suggestion?
This test is part of a much more large experimentation. As I told at the begining, the application works Ok on a lot of mobile devices, but It doesn't work on others. I can't find a pattern to identify these devices or the cause of the problem. I would appreciate a lot any help on this
Specifications:
- Works OK on a Samsung J7 neo (SM-J701M) with Android 8.1.0
- Doesn't work on a Tablet Samsung Galaxy Tab A (SMT350) with Android 7.1.1
This is a Java test class that reproduce the problem:
public class Acquisition extends Thread {
private boolean isRunning;
private int bytesCounter;
private boolean isOnError;
Socket sk;
public Acquisition () {
isRunning = false;
isOnError = false;
}
public static void Log (String msg) {
Log.d ("app", msg);
}
public void run () {
isRunning = true;
byte buffer[] = new byte[100000];
bytesCounter = 0;
try {
sk = new Socket ("192.168.1.1", 2000);
InputStream input = sk.getInputStream ();
// This is the stop an start command I send to the device to start acquiring
sk.getOutputStream().write ("PF|0000|".getBytes());
sk.getOutputStream().write ("PA|0000|".getBytes());
while (this.isRunning) {
this.sleep(500);
int ret = input.read (buffer, 0, 100000);
if (ret > 0) {
Log ("Reading:" + ret + " bytes");
bytesCounter += ret;
} else {
Log ("Error. Cod: " + ret);
isRunning = false;
}
}
} catch (Exception ex) {
Log ("Acquisition error: " + ex.getMessage());
}
}
public void Stop () {
try {
isRunning = false;
wait(1000);
} catch (Exception ex) {
Log ("Error stopping thread: " + ex.getMessage());
}
}
public int GetBytesCounter () {
return this.bytesCounter;
}
}
Update
I have made two tests to see what is happening with the communication.
This is the result of sniffing the network:
Here it can be seen that the TCP packets traffic is interrupted between the seconds 12 and 13.9. This is happening more than once in the acquisition process and is causing the communication gets interrupted. In the second image it can bee seen what is happening at the moment the packet traffic stops
The second test was to send ICMP packets (using ping) from different android devices to the acquisition module. What we seen is that only the devices having troubles in the first test losts packets in the ping test, the average of lost packets was close to 20%. This could explain the TCP retransmissions we see in wireshark.
Conclusion
I wrote this post thinking that there could be a problem with Android (or some versions of Android), but it seems that the Wifi Hardware is so diverse in mobile devices that there is no way to have in a minimum transaction rate common for all devices.