mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-30 15:52:12 +01:00
Make sure the USB scheduling is thread safe.
This commit is contained in:
parent
69fbefee85
commit
75ce520503
@ -312,7 +312,7 @@ public class HidUAVTalk extends TelemetryTask {
|
|||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
// Enqueue the first read
|
// Enqueue the first read
|
||||||
readData();
|
queueRead();
|
||||||
|
|
||||||
while (!shutdown) {
|
while (!shutdown) {
|
||||||
// If there are no request
|
// If there are no request
|
||||||
@ -325,9 +325,8 @@ public class HidUAVTalk extends TelemetryTask {
|
|||||||
} else if (returned == writeRequest) {
|
} else if (returned == writeRequest) {
|
||||||
if (DEBUG) Log.d(TAG, "Received write completed request");
|
if (DEBUG) Log.d(TAG, "Received write completed request");
|
||||||
writePending = false;
|
writePending = false;
|
||||||
|
sendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
sendData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,63 +350,79 @@ public class HidUAVTalk extends TelemetryTask {
|
|||||||
* it to the input stream
|
* it to the input stream
|
||||||
*/
|
*/
|
||||||
ByteBuffer readBuffer = ByteBuffer.allocate(MAX_HID_PACKET_SIZE);
|
ByteBuffer readBuffer = ByteBuffer.allocate(MAX_HID_PACKET_SIZE);
|
||||||
private void queueRead() {
|
|
||||||
if(!readRequest.queue(readBuffer, MAX_HID_PACKET_SIZE)) {
|
|
||||||
if (ERROR) Log.e(TAG, "Failed to queue request");
|
|
||||||
} else
|
|
||||||
readPending = true;
|
|
||||||
}
|
|
||||||
public void readData() {
|
|
||||||
|
|
||||||
if (!readPending) {
|
/**
|
||||||
queueRead();
|
* Schedules a USB read
|
||||||
} else { // We just received a read
|
*/
|
||||||
|
private void queueRead() {
|
||||||
|
synchronized(readRequest) {
|
||||||
|
if(!readRequest.queue(readBuffer, MAX_HID_PACKET_SIZE)) {
|
||||||
|
if (ERROR) Log.e(TAG, "Failed to queue request");
|
||||||
|
} else
|
||||||
|
readPending = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads data from the last USB transaction and schedules another read
|
||||||
|
*/
|
||||||
|
public void readData() {
|
||||||
|
synchronized(readRequest) {
|
||||||
|
|
||||||
|
if (!readPending) {
|
||||||
|
if (ERROR) Log.e(TAG, "Tried to read read while a transaction was not pending");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We just received a read
|
||||||
readPending = false;
|
readPending = false;
|
||||||
// Packet format:
|
// Packet format:
|
||||||
// 0: Report ID (1)
|
// 0: Report ID (1)
|
||||||
// 1: Number of valid bytes
|
// 1: Number of valid bytes
|
||||||
// 2:63: Data
|
// 2:63: Data
|
||||||
|
|
||||||
int dataSize = readBuffer.get(1); // Data size
|
int dataSize = readBuffer.get(1); // Data size
|
||||||
//Assert.assertEquals(1, buffer.get()); // Report ID
|
//Assert.assertEquals(1, buffer.get()); // Report ID
|
||||||
//Assert.assertTrue(dataSize < buffer.capacity());
|
//Assert.assertTrue(dataSize < buffer.capacity());
|
||||||
|
|
||||||
if (readBuffer.get(0) != 1 || readBuffer.get(1) < 0 || readBuffer.get(1) > (readBuffer.capacity() - 2)) {
|
if (readBuffer.get(0) != 1 || readBuffer.get(1) < 0 || readBuffer.get(1) > (readBuffer.capacity() - 2)) {
|
||||||
if (ERROR) Log.e(TAG, "Badly formatted HID packet");
|
if (ERROR) Log.e(TAG, "Badly formatted HID packet");
|
||||||
} else {
|
} else {
|
||||||
byte[] dst = new byte[dataSize];
|
byte[] dst = new byte[dataSize];
|
||||||
readBuffer.position(2);
|
readBuffer.position(2);
|
||||||
readBuffer.get(dst, 0, dataSize);
|
readBuffer.get(dst, 0, dataSize);
|
||||||
if (DEBUG) Log.d(TAG, "Entered read");
|
if (DEBUG) Log.d(TAG, "Entered read");
|
||||||
inTalkStream.write(dst);
|
inTalkStream.write(dst);
|
||||||
if (DEBUG) Log.d(TAG, "Got read: " + dataSize + " bytes");
|
if (DEBUG) Log.d(TAG, "Got read: " + dataSize + " bytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue another read
|
// Queue another read
|
||||||
queueRead();
|
queueRead();
|
||||||
}
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a packet if data is available
|
* Send a packet if data is available
|
||||||
*/
|
*/
|
||||||
public void sendData() {
|
public void sendData() {
|
||||||
|
synchronized(writeRequest) {
|
||||||
|
// Don't try and send data till previous request completes
|
||||||
|
if (writePending)
|
||||||
|
return;
|
||||||
|
|
||||||
// Don't try and send data till previous request completes
|
ByteBuffer packet = outTalkStream.getHIDpacket();
|
||||||
if (writePending)
|
if (packet != null) {
|
||||||
return;
|
if (DEBUG) Log.d(TAG, "Writing to device()");
|
||||||
|
|
||||||
ByteBuffer packet = outTalkStream.getHIDpacket();
|
int bufferDataLength = usbEndpointWrite.getMaxPacketSize();
|
||||||
if (packet != null) {
|
Assert.assertTrue(packet.capacity() <= bufferDataLength);
|
||||||
if (DEBUG) Log.d(TAG, "Writing to device()");
|
|
||||||
|
|
||||||
int bufferDataLength = usbEndpointWrite.getMaxPacketSize();
|
if(writeRequest.queue(packet, bufferDataLength))
|
||||||
Assert.assertTrue(packet.capacity() <= bufferDataLength);
|
writePending = true;
|
||||||
|
else if (ERROR)
|
||||||
if(writeRequest.queue(packet, bufferDataLength))
|
Log.e(TAG, "Write queuing failed");
|
||||||
writePending = true;
|
}
|
||||||
else if (ERROR)
|
|
||||||
Log.e(TAG, "Write queuing failed");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -446,6 +461,9 @@ public class HidUAVTalk extends TelemetryTask {
|
|||||||
data.put((byte) oneByte);
|
data.put((byte) oneByte);
|
||||||
data.notify();
|
data.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there is not a write request queued, add one
|
||||||
|
sendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -457,6 +475,8 @@ public class HidUAVTalk extends TelemetryTask {
|
|||||||
data.put(b);
|
data.put(b);
|
||||||
data.notify();
|
data.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendData();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user