summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorMike Playle <mike.playle@realvnc.com>2010-10-22 13:58:17 +0100
committerMike Playle <mike.playle@realvnc.com>2011-04-04 08:56:22 +0100
commit36aa8839d5509d12323a6025329d6913cbaa353b (patch)
tree1aadc4aa7325748ae1e8d42cf29d449bfb290dbe /core
parentc6b22e2727bd3730edd5ad72831a9bb4670d00f3 (diff)
downloadframeworks_base-36aa8839d5509d12323a6025329d6913cbaa353b.zip
frameworks_base-36aa8839d5509d12323a6025329d6913cbaa353b.tar.gz
frameworks_base-36aa8839d5509d12323a6025329d6913cbaa353b.tar.bz2
Fix data corruption when writing to Bluetooth socket
Writes to Bluetooth sockets are handled by writeNative() in android_bluetooth_BluetoothSocket.cpp. This calls asocket_write() which is implemented in abort_socket.c. This latter function sleeps until poll() indicates that the socket is writeable, then calls write() once, returning the number of bytes written. However writeNative() just returns this byte count to the caller; it's eventually ignored in BluetoothOutputStream.java. This doesn't match the semantics of a Java OutputStream, which is required to block until all bytes have been written. This fix adds a loop to writeNative() that repeatedly calls the lower level write function until all the data has been written (or an error occurred in which case we should exit the loop early). With this change it is possible to write large amounts of data to a Bluetooth socket without experiencing data loss. Change-Id: I0b464382817e15adec32ba0e3cb37e7d1cccc730
Diffstat (limited to 'core')
-rw-r--r--core/jni/android_bluetooth_BluetoothSocket.cpp20
1 files changed, 13 insertions, 7 deletions
diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp
index 31ebf8c..a62537d 100644
--- a/core/jni/android_bluetooth_BluetoothSocket.cpp
+++ b/core/jni/android_bluetooth_BluetoothSocket.cpp
@@ -448,7 +448,7 @@ static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
#ifdef HAVE_BLUETOOTH
LOGV(__FUNCTION__);
- int ret;
+ int ret, total;
jbyte *b;
int sz;
struct asocket *s = get_socketData(env, obj);
@@ -471,15 +471,21 @@ static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
return -1;
}
- ret = asocket_write(s, &b[offset], length, -1);
- if (ret < 0) {
- jniThrowIOException(env, errno);
- env->ReleaseByteArrayElements(jb, b, JNI_ABORT);
- return -1;
+ total = 0;
+ while (length > 0) {
+ ret = asocket_write(s, &b[offset], length, -1);
+ if (ret < 0) {
+ jniThrowIOException(env, errno);
+ env->ReleaseByteArrayElements(jb, b, JNI_ABORT);
+ return -1;
+ }
+ offset += ret;
+ total += ret;
+ length -= ret;
}
env->ReleaseByteArrayElements(jb, b, JNI_ABORT); // no need to commit
- return (jint)ret;
+ return (jint)total;
#endif
jniThrowIOException(env, ENOSYS);