Reputation: 51
I use modified Google Bluetooth Chat application to proceed client-server Bluetooth RFCOMM communication between two Android devices (with Android 5 and Android 6).
There is some code of my client application:
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final BufferedInputStream mmInStream;
private final BufferedOutputStream mmOutStream;
private ByteBuffer outputBuffer = null;
private int currentOperation = 0;
private byte currentMessageType = 0;
ConnectedThread(BluetoothSocket socket) {
Log.d(LOG_TAG, "create ConnectedThread: Insecure");
mmSocket = socket;
BufferedInputStream tmpIn = null;
BufferedOutputStream tmpOut = null;
try {
tmpIn = new BufferedInputStream(socket.getInputStream());
tmpOut = new BufferedOutputStream(socket.getOutputStream());
} catch (IOException e) {
Log.e(LOG_TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
setState(STATE_CONNECTED);
}
public void run() {
Log.i(LOG_TAG, "BEGIN mConnectedThread");
byte[] buffer;
ByteBuffer intBuf;
int tempInt;
while (mState == STATE_CONNECTED) {
try {
if(mmInStream.available()>8) {
Log.i(LOG_TAG, mmInStream.available() + " f");
buffer = new byte[9];
mmInStream.read(buffer, 0, 9);
intBuf = ByteBuffer.wrap(buffer);
Log.i(LOG_TAG, "NEW MESSAGE: "+intBuf.getInt()+" "+intBuf.get()+" "+intBuf.getInt());
intBuf.rewind();
tempInt = intBuf.getInt();
Log.i(LOG_TAG, tempInt + " GET OP ID " + intBuf.capacity());
currentMessageType = intBuf.get();
Log.i(LOG_TAG, currentMessageType + " GET OP TYPE");
// ... some more code
}
}
catch (IOException err ) {
Log.e(LOG_TAG, "disconnected", err);
connectionLost();
break;
}
}
}
void write(byte[] data) {
try {
Log.i(LOG_TAG, "WRITE NEW MESSAGE: "+data.length);
mmOutStream.write(data);
SystemClock.sleep(200);
} catch (IOException e) {
Log.e(LOG_TAG, "Exception during write", e);
}
}
void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(LOG_TAG, "close() of connect socket failed", e);
}
}
This part manages the BluetoothSocket read/write operations.
So what's the problem? When I send data with size <10000 bytes (byte array) it all goes normally. But then I try to send some big-sized data (>10000 bytes) and recieve this message (with LogCat):
12-22 12:53:49.849 28177-28177/com.lukanin.testappjava2 I/(BLUETOOTH): DATA LENGTH: 35722 OPT ID: 1 TYPE: 11
12-22 12:53:49.849 28177-28177/com.lukanin.testappjava2 I/(BLUETOOTH): SEND DATA: 1 11 35722
12-22 12:53:49.849 28177-28177/com.lukanin.testappjava2 I/(BLUETOOTH): WRITE NEW MESSAGE: 35731
[ 12-22 12:53:49.849 21464:21536 D/ ]
PORT_WriteDataCO: tx queue is full,tx.queue_size:10890,tx.queue.count:11,available:14941
[ 12-22 12:53:49.959 21464:21536 D/ ]
PORT_WriteDataCO: tx queue is full,tx.queue_size:10890,tx.queue.count:11,available:3061
I think there is some kind of OutputStream overflow, but I can't understand how to fix it. What should I do to prevent such situation? Is there any methods to check the OutputStream write availability?
P.S. This situation is relevant for Android 5 (on Android 6 all seems to be normal).
Upvotes: 1
Views: 2395
Reputation: 3964
I am not sure whether this will help, but try to write in chunks:
private static funal int CHUNK_SIZE = 200;
.....
int currentIndex = 0;
int size = data.length;
while (currentIndex < size) {
int currentLength = Math.Min(size-currentIndex, CHUNK_SIZE);
memOutStream.write(data, currentIndex, currentLength);
currentIndex += currentLength;
}
Upvotes: 0
Reputation: 4662
In Android 5,
/* if we're over buffer high water mark, we're done */
if ((p_port->tx.queue_size > PORT_TX_HIGH_WM)
|| (p_port->tx.queue.count > PORT_TX_BUF_HIGH_WM))
{
port_flow_control_user(p_port);
event |= PORT_EV_FC;
debug("tx queue is full,tx.queue_size:%d,tx.queue.count:%d,available:%d",
p_port->tx.queue_size, p_port->tx.queue.count, available);
break;
}
I don't know the values for PORT_TX_HIGH_WM or PORT_TX_BUF_HIGH_WM but assume that this tx.queue_size is more than the maximum you can send.
Upvotes: 0