Java源码示例:com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException
示例1
@SuppressLint("CheckResult")
public static boolean doReset(Ob1G5CollectionService parent, RxBleConnection connection) {
if (connection == null) return false;
parent.msg("Hard Resetting Transmitter");
connection.writeCharacteristic(Control, nn(new ResetTxMessage().byteSequence))
.subscribe(characteristicValue -> {
if (d)
UserError.Log.d(TAG, "Wrote ResetTxMessage request!!");
parent.msg("Hard Reset Sent");
}, throwable -> {
parent.msg("Hard Reset maybe Failed");
UserError.Log.e(TAG, "Failed to write ResetTxMessage: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + getStatusName(status));
}
});
return true;
}
示例2
boolean sendOtaChunk(final UUID uuid, final byte[] bytes) {
if (I.connection == null || !I.isConnected) return false;
I.connection.writeCharacteristic(uuid, bytes)
.observeOn(Schedulers.io())
.subscribeOn(Schedulers.io())
.subscribe(
characteristicValue -> {
if (D)
UserError.Log.d(TAG, "Wrote record request request: " + bytesToHex(characteristicValue));
busy = false;
}, throwable -> {
UserError.Log.e(TAG, "Failed to write record request: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
} else {
if (throwable instanceof BleDisconnectedException) {
changeState(CLOSE);
}
UserError.Log.d(TAG, "Throwable in Record End write: " + throwable);
}
});
return true; // only that we didn't fail in setup
}
示例3
@SuppressLint("CheckResult")
public static boolean doReset(Ob1G5CollectionService parent, RxBleConnection connection) {
if (connection == null) return false;
parent.msg("Hard Resetting Transmitter");
connection.writeCharacteristic(Control, nn(new ResetTxMessage().byteSequence))
.subscribe(characteristicValue -> {
if (d)
UserError.Log.d(TAG, "Wrote ResetTxMessage request!!");
parent.msg("Hard Reset Sent");
}, throwable -> {
parent.msg("Hard Reset maybe Failed");
UserError.Log.e(TAG, "Failed to write ResetTxMessage: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + getStatusName(status));
}
});
return true;
}
示例4
@SuppressLint("CheckResult")
public static boolean doReset(Ob1G5CollectionService parent, RxBleConnection connection) {
if (connection == null) return false;
parent.msg("Hard Resetting Transmitter");
connection.writeCharacteristic(Control, nn(new ResetTxMessage().byteSequence))
.subscribe(characteristicValue -> {
if (d)
UserError.Log.d(TAG, "Wrote ResetTxMessage request!!");
parent.msg("Hard Reset Sent");
}, throwable -> {
parent.msg("Hard Reset maybe Failed");
UserError.Log.e(TAG, "Failed to write ResetTxMessage: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + getStatusName(status));
}
});
return true;
}
示例5
boolean sendOtaChunk(final UUID uuid, final byte[] bytes) {
if (I.connection == null || !I.isConnected) return false;
I.connection.writeCharacteristic(uuid, bytes)
.observeOn(Schedulers.io())
.subscribeOn(Schedulers.io())
.subscribe(
characteristicValue -> {
if (D)
UserError.Log.d(TAG, "Wrote record request request: " + bytesToHex(characteristicValue));
busy = false;
}, throwable -> {
UserError.Log.e(TAG, "Failed to write record request: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
} else {
if (throwable instanceof BleDisconnectedException) {
changeState(CLOSE);
}
UserError.Log.d(TAG, "Throwable in Record End write: " + throwable);
}
});
return true; // only that we didn't fail in setup
}
示例6
@SuppressLint("CheckResult")
public static boolean doReset(Ob1G5CollectionService parent, RxBleConnection connection) {
if (connection == null) return false;
parent.msg("Hard Resetting Transmitter");
connection.writeCharacteristic(Control, nn(new ResetTxMessage().byteSequence))
.subscribe(characteristicValue -> {
if (d)
UserError.Log.d(TAG, "Wrote ResetTxMessage request!!");
parent.msg("Hard Reset Sent");
}, throwable -> {
parent.msg("Hard Reset maybe Failed");
UserError.Log.e(TAG, "Failed to write ResetTxMessage: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + getStatusName(status));
}
});
return true;
}
示例7
static boolean propagateErrorIfOccurred(
Output<?> output,
BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status,
BleGattOperationType operationType
) {
return isException(status) && propagateStatusError(output, new BleGattCharacteristicException(
gatt,
characteristic,
status,
operationType
));
}
示例8
private void requestBulk(final ThinJamItem item) {
final BulkUpRequestTx packet = new BulkUpRequestTx(item.type, item.width == 0 ? 0 : 1, item.buffer.length, item.buffer, item.quiet);
if (D)
UserError.Log.d(TAG, "Bulk request request: " + bytesToHex(packet.getBytes()));
// value will get notification result itself
I.connection.writeCharacteristic(THINJAM_WRITE, packet.getBytes()).subscribe(
// I.connection.writeCharacteristic(THINJAM_BULK, packet.getBytes()).subscribe(
response -> {
if (D)
UserError.Log.d(TAG, "Bulk request response: " + bytesToHex(response));
if (packet.responseOk(response)) {
UserError.Log.d(TAG, "Bulk channel opcode: " + packet.getBulkUpOpcode(response));
bulkSend(packet.getBulkUpOpcode(response), item.buffer, 15, item.quiet);
} else {
UserError.Log.d(TAG, "Bulk request failed: " + packet.responseText(response));
if (packet.responseText(response).toLowerCase().contains("busy")
&& item.retryCounterOk()) {
UserError.Log.d(TAG, "Device is busy, scheduling retry");
Inevitable.task("bulk-retry-" + item.toS(), 3000, () -> {
UserError.Log.d(TAG, "Retrying requestBulk: " + item.toS());
requestBulk(item);
});
}
}
}, throwable -> {
UserError.Log.e(TAG, "Failed to write bulk request: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
} else {
UserError.Log.d(TAG, "Throwable in Bulk End write: " + throwable);
}
});
}
示例9
private void sendTime() {
final String func = "SetTime";
final SetTimeTx outbound = new SetTimeTx();
UserError.Log.d(TAG, "Outbound: " + bytesToHex(outbound.getBytes()));
I.connection.writeCharacteristic(THINJAM_WRITE, outbound.getBytes()).subscribe(
response -> {
SetTimeTx reply = new SetTimeTx(response);
if (D)
UserError.Log.d(TAG, func + " response: " + bytesToHex(response) + " " + reply.toS());
UserError.Log.e(TAG, "Time difference with watch: " + ((outbound.getTimestamp() - reply.getTimestamp()) / 1000d));
changeNextState();
}, throwable -> {
UserError.Log.e(TAG, "Failed to write " + func + " request: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
} else {
UserError.Log.d(TAG, "Throwable in " + func + " " + throwable);
if (throwable instanceof BleCharacteristicNotFoundException) {
UserError.Log.d(TAG, "Assuming wrong firmware version");
changeNextState();
} else {
changeState(CLOSE);
}
}
});
}
示例10
private void requestBulk(final ThinJamItem item) {
final BulkUpRequestTx packet = new BulkUpRequestTx(item.type, item.width == 0 ? 0 : 1, item.buffer.length, item.buffer, item.quiet);
if (D)
UserError.Log.d(TAG, "Bulk request request: " + bytesToHex(packet.getBytes()));
// value will get notification result itself
I.connection.writeCharacteristic(THINJAM_WRITE, packet.getBytes()).subscribe(
// I.connection.writeCharacteristic(THINJAM_BULK, packet.getBytes()).subscribe(
response -> {
if (D)
UserError.Log.d(TAG, "Bulk request response: " + bytesToHex(response));
if (packet.responseOk(response)) {
UserError.Log.d(TAG, "Bulk channel opcode: " + packet.getBulkUpOpcode(response));
bulkSend(packet.getBulkUpOpcode(response), item.buffer, 15, item.quiet);
} else {
UserError.Log.d(TAG, "Bulk request failed: " + packet.responseText(response));
if (packet.responseText(response).toLowerCase().contains("busy")
&& item.retryCounterOk()) {
UserError.Log.d(TAG, "Device is busy, scheduling retry");
Inevitable.task("bulk-retry-" + item.toS(), 3000, () -> {
UserError.Log.d(TAG, "Retrying requestBulk: " + item.toS());
requestBulk(item);
});
}
}
}, throwable -> {
UserError.Log.e(TAG, "Failed to write bulk request: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
} else {
UserError.Log.d(TAG, "Throwable in Bulk End write: " + throwable);
}
});
}
示例11
private void sendTime() {
final String func = "SetTime";
final SetTimeTx outbound = new SetTimeTx();
UserError.Log.d(TAG, "Outbound: " + bytesToHex(outbound.getBytes()));
I.connection.writeCharacteristic(THINJAM_WRITE, outbound.getBytes()).subscribe(
response -> {
SetTimeTx reply = new SetTimeTx(response);
if (D)
UserError.Log.d(TAG, func + " response: " + bytesToHex(response) + " " + reply.toS());
UserError.Log.e(TAG, "Time difference with watch: " + ((outbound.getTimestamp() - reply.getTimestamp()) / 1000d));
changeNextState();
}, throwable -> {
UserError.Log.e(TAG, "Failed to write " + func + " request: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
} else {
UserError.Log.d(TAG, "Throwable in " + func + " " + throwable);
if (throwable instanceof BleCharacteristicNotFoundException) {
UserError.Log.d(TAG, "Assuming wrong firmware version");
changeNextState();
} else {
changeState(CLOSE);
}
}
});
}
示例12
@SuppressLint("CheckResult")
public static boolean doCheckAuth(Ob1G5CollectionService parent, RxBleConnection connection) {
if (connection == null) return false;
parent.msg("Authorizing");
if (parent.android_wear) {
speakSlowly = true;
UserError.Log.d(TAG, "Setting speak slowly to true"); // WARN should be reactive or on named devices
}
final AuthRequestTxMessage authRequest = new AuthRequestTxMessage(getTokenSize(), usingAlt());
UserError.Log.i(TAG, "AuthRequestTX: " + JoH.bytesToHex(authRequest.byteSequence));
connection.setupNotification(Authentication)
// .timeout(10, TimeUnit.SECONDS)
.timeout(15, TimeUnit.SECONDS) // WARN
// .observeOn(Schedulers.newThread()) // needed?
.doOnNext(notificationObservable -> {
connection.writeCharacteristic(Authentication, nn(authRequest.byteSequence))
.subscribe(
characteristicValue -> {
// Characteristic value confirmed.
if (d)
UserError.Log.d(TAG, "Wrote authrequest, got: " + JoH.bytesToHex(characteristicValue));
speakSlowly();
connection.readCharacteristic(Authentication).subscribe(
readValue -> {
authenticationProcessor(parent, connection, readValue);
}, throwable -> {
UserError.Log.e(TAG, "Could not read after AuthRequestTX: " + throwable);
});
//parent.background_automata();
},
throwable -> {
UserError.Log.e(TAG, "Could not write AuthRequestTX: " + throwable);
parent.incrementErrors();
}
);
}).flatMap(notificationObservable -> notificationObservable)
//.timeout(5, TimeUnit.SECONDS)
//.observeOn(Schedulers.newThread())
.subscribe(bytes -> {
// incoming notifications
UserError.Log.d(TAG, "Received Authentication notification bytes: " + JoH.bytesToHex(bytes));
authenticationProcessor(parent, connection, bytes);
}, throwable -> {
if (!(throwable instanceof OperationSuccess)) {
if (((parent.getState() == Ob1G5CollectionService.STATE.CLOSED)
|| (parent.getState() == Ob1G5CollectionService.STATE.CLOSE))
&& (throwable instanceof BleDisconnectedException)) {
UserError.Log.d(TAG, "normal authentication notification throwable: (" + parent.getState() + ") " + throwable + " " + JoH.dateTimeText(tsl()));
parent.connectionStateChange(CLOSED_OK_TEXT);
} else if ((parent.getState() == Ob1G5CollectionService.STATE.BOND) && (throwable instanceof TimeoutException)) {
// TODO Trigger on Error count / Android wear metric
// UserError.Log.e(TAG,"Attempting to reset/create bond due to: "+throwable);
// parent.reset_bond(true);
// parent.unBond(); // WARN
} else {
UserError.Log.e(TAG, "authentication notification throwable: (" + parent.getState() + ") " + throwable + " " + JoH.dateTimeText(tsl()));
parent.incrementErrors();
if (throwable instanceof BleCannotSetCharacteristicNotificationException
|| throwable instanceof BleGattCharacteristicException) {
parent.tryGattRefresh();
parent.changeState(Ob1G5CollectionService.STATE.SCAN);
}
}
if ((throwable instanceof BleDisconnectedException) || (throwable instanceof TimeoutException)) {
if ((parent.getState() == Ob1G5CollectionService.STATE.BOND) || (parent.getState() == Ob1G5CollectionService.STATE.CHECK_AUTH)) {
if (parent.getState() == Ob1G5CollectionService.STATE.BOND) {
UserError.Log.d(TAG, "SLEEPING BEFORE RECONNECT");
threadSleep(15000);
}
UserError.Log.d(TAG, "REQUESTING RECONNECT");
parent.changeState(Ob1G5CollectionService.STATE.SCAN);
}
}
}
});
return true;
}
示例13
private void bulkSend(final int opcode, final byte[] buffer, final int offset, boolean quiet) {
UserError.Log.d(TAG, "bulksend called: opcode " + opcode + " total " + buffer.length + " offset: " + offset + " quiet:" + quiet);
if (buffer != null && offset < buffer.length) {
final BulkUpTx packet = (opcode >= OPCODE_BULK_R_XFER_0 ? new RBulkUpTx(opcode, buffer, offset) : new BulkUpTx(opcode, buffer, offset));
if (quiet) {
packet.setQuiet();
}
if (offset == 0) {
revisedOffset = 0; // reset counter as this is new bulk up
lastActionedRevisedOffset = -1;
// TODO we should check it if we have failed to act on revised offset
}
I.connection.writeCharacteristic(quiet ? THINJAM_BULK : THINJAM_WRITE, packet.getBytes())
.observeOn(Schedulers.newThread())
.subscribe(
response -> {
if (D)
UserError.Log.d(TAG, "Bulk Up Send response: " + bytesToHex(response));
if (packet.responseOk(response)) {
// WARNING recursion
final int nextOffset;
if (revisedOffset != 0 && revisedOffset < offset && revisedOffset != lastActionedRevisedOffset) {
nextOffset = revisedOffset; // TODO we only catch this if we send a packet
lastActionedRevisedOffset = nextOffset;
UserError.Log.d(TAG, "Retrying bulk send from: " + nextOffset);
} else {
nextOffset = offset + packet.getBytesIncluded();
}
revisedOffset = 0;
if (nextOffset < buffer.length) {
if (!quiet) {
JoH.threadSleep(100);
} else {
JoH.threadSleep(1);
}
bulkSend(opcode, buffer, nextOffset, packet.isQuiet());
} else {
UserError.Log.d(TAG, "Bulk send completed!");
if (!(packet instanceof RBulkUpTx)) {
commandQueue.poll(); // removes first item from the queue which should be the one we just processed!
}
Inevitable.task("tj-next-queue", 4000, this::processQueue); // wait 1 second and then retry this upload if we get success reply notification then we remove it elsewhere
}
} else {
UserError.Log.d(TAG, "Bulk Send failed: " + packet.responseText(response));
if (!quiet) {
Inevitable.task("tj-next-queue", 20000, this::processQueue); // retry shortly
if (JoH.ratelimit("tj-allow-bulk-retry", 2)) {
UserError.Log.d(TAG, "Retrying packet");
bulkSend(opcode, buffer, offset, quiet); // retry packet send
}
} else {
UserError.Log.d(TAG, "Quiet is set so not attempting any response to failure here");
}
}
}, throwable -> {
UserError.Log.e(TAG, "Failed to write bulk Send: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
} else {
UserError.Log.d(TAG, "Throwable in Bulk SEnd write: " + throwable);
}
});
} else {
UserError.Log.d(TAG, "Invalid buffer in bulkSend");
}
}
示例14
@SuppressLint("CheckResult")
public static boolean doCheckAuth(Ob1G5CollectionService parent, RxBleConnection connection) {
if (connection == null) return false;
parent.msg("Authorizing");
if (parent.android_wear) {
speakSlowly = true;
UserError.Log.d(TAG, "Setting speak slowly to true"); // WARN should be reactive or on named devices
}
final AuthRequestTxMessage authRequest = new AuthRequestTxMessage(getTokenSize(), usingAlt());
UserError.Log.i(TAG, "AuthRequestTX: " + JoH.bytesToHex(authRequest.byteSequence));
connection.setupNotification(Authentication)
// .timeout(10, TimeUnit.SECONDS)
.timeout(15, TimeUnit.SECONDS) // WARN
// .observeOn(Schedulers.newThread()) // needed?
.doOnNext(notificationObservable -> {
connection.writeCharacteristic(Authentication, nn(authRequest.byteSequence))
.subscribe(
characteristicValue -> {
// Characteristic value confirmed.
if (d)
UserError.Log.d(TAG, "Wrote authrequest, got: " + JoH.bytesToHex(characteristicValue));
speakSlowly();
connection.readCharacteristic(Authentication).subscribe(
readValue -> {
authenticationProcessor(parent, connection, readValue);
}, throwable -> {
UserError.Log.e(TAG, "Could not read after AuthRequestTX: " + throwable);
});
//parent.background_automata();
},
throwable -> {
UserError.Log.e(TAG, "Could not write AuthRequestTX: " + throwable);
parent.incrementErrors();
}
);
}).flatMap(notificationObservable -> notificationObservable)
//.timeout(5, TimeUnit.SECONDS)
//.observeOn(Schedulers.newThread())
.subscribe(bytes -> {
// incoming notifications
UserError.Log.d(TAG, "Received Authentication notification bytes: " + JoH.bytesToHex(bytes));
authenticationProcessor(parent, connection, bytes);
}, throwable -> {
if (!(throwable instanceof OperationSuccess)) {
if (((parent.getState() == Ob1G5CollectionService.STATE.CLOSED)
|| (parent.getState() == Ob1G5CollectionService.STATE.CLOSE))
&& (throwable instanceof BleDisconnectedException)) {
UserError.Log.d(TAG, "normal authentication notification throwable: (" + parent.getState() + ") " + throwable + " " + JoH.dateTimeText(tsl()));
parent.connectionStateChange(CLOSED_OK_TEXT);
} else if ((parent.getState() == Ob1G5CollectionService.STATE.BOND) && (throwable instanceof TimeoutException)) {
// TODO Trigger on Error count / Android wear metric
// UserError.Log.e(TAG,"Attempting to reset/create bond due to: "+throwable);
// parent.reset_bond(true);
// parent.unBond(); // WARN
} else {
UserError.Log.e(TAG, "authentication notification throwable: (" + parent.getState() + ") " + throwable + " " + JoH.dateTimeText(tsl()));
parent.incrementErrors();
if (throwable instanceof BleCannotSetCharacteristicNotificationException
|| throwable instanceof BleGattCharacteristicException) {
parent.tryGattRefresh();
parent.changeState(Ob1G5CollectionService.STATE.SCAN);
}
}
if ((throwable instanceof BleDisconnectedException) || (throwable instanceof TimeoutException)) {
if ((parent.getState() == Ob1G5CollectionService.STATE.BOND) || (parent.getState() == Ob1G5CollectionService.STATE.CHECK_AUTH)) {
if (parent.getState() == Ob1G5CollectionService.STATE.BOND) {
UserError.Log.d(TAG, "SLEEPING BEFORE RECONNECT");
threadSleep(15000);
}
UserError.Log.d(TAG, "REQUESTING RECONNECT");
parent.changeState(Ob1G5CollectionService.STATE.SCAN);
}
}
}
});
return true;
}
示例15
private void getRecords(final int firstIndex, final int lastIndex) {
final int numberOfRecords = lastIndex - firstIndex;
if (numberOfRecords > 30) {
I.connection.writeCharacteristic(KEEPALIVE, new KeepAliveTx().getBytes()).subscribe(
value -> {
UserError.Log.d(TAG, "Wrote keep alive for " + numberOfRecords);
}, throwable -> {
UserError.Log.d(TAG, "Got exception in keep alive" + throwable);
});
}
final RecordTx packet = new RecordTx(firstIndex, lastIndex);
UserError.Log.d(TAG, "getRecords called, loading: " + firstIndex + " to " + lastIndex);
I.connection.setupIndication(RECORD_INDICATE).doOnNext(notificationObservable -> {
I.connection.writeCharacteristic(RECORD_START, packet.startBytes()).subscribe(valueS -> {
UserError.Log.d(TAG, "Wrote record start: " + bytesToHex(valueS));
I.connection.writeCharacteristic(RECORD_END, packet.endBytes()).subscribe(valueE -> {
UserError.Log.d(TAG, "Wrote record end: " + bytesToHex(valueE));
I.connection.writeCharacteristic(RECORD_REQUEST, packet.triggerBytes()).subscribe(
characteristicValue -> {
if (D)
UserError.Log.d(TAG, "Wrote record request request: " + bytesToHex(characteristicValue));
}, throwable -> {
UserError.Log.e(TAG, "Failed to write record request: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
}
});
}, throwable -> {
UserError.Log.d(TAG, "Throwable in Record End write: " + throwable);
});
}, throwable -> {
UserError.Log.d(TAG, "Throwable in Record Start write: " + throwable);
// throws BleGattCharacteristicException status = 128 for "no resources" eg nothing matches
});
})
.flatMap(notificationObservable -> notificationObservable)
.timeout(120, TimeUnit.SECONDS)
.observeOn(Schedulers.newThread())
.subscribe(bytes -> {
records.add(bytes);
UserError.Log.d(TAG, "INDICATE INDICATE: " + HexDump.dumpHexString(bytes));
}, throwable -> {
if (!(throwable instanceof OperationSuccess)) {
if (throwable instanceof BleDisconnectedException) {
UserError.Log.d(TAG, "Disconnected when waiting to receive indication: " + throwable);
} else {
UserError.Log.e(TAG, "Error receiving indication: " + throwable);
}
Inevitable.task("check-records-queue", 100, this::processRecordsQueue);
}
});
}
示例16
private boolean isErrorResponse(final Object throwable) {
return throwable instanceof BleGattCharacteristicException && ((BleGattException) throwable).getStatus() == 1;
}
示例17
@SuppressLint("CheckResult")
public static boolean doCheckAuth(Ob1G5CollectionService parent, RxBleConnection connection) {
if (connection == null) return false;
parent.msg("Authorizing");
if (parent.android_wear) {
speakSlowly = true;
UserError.Log.d(TAG, "Setting speak slowly to true"); // WARN should be reactive or on named devices
}
final AuthRequestTxMessage authRequest = new AuthRequestTxMessage(getTokenSize(), usingAlt());
UserError.Log.i(TAG, "AuthRequestTX: " + JoH.bytesToHex(authRequest.byteSequence));
connection.setupNotification(Authentication)
// .timeout(10, TimeUnit.SECONDS)
.timeout(15, TimeUnit.SECONDS) // WARN
// .observeOn(Schedulers.newThread()) // needed?
.doOnNext(notificationObservable -> {
connection.writeCharacteristic(Authentication, nn(authRequest.byteSequence))
.subscribe(
characteristicValue -> {
// Characteristic value confirmed.
if (d)
UserError.Log.d(TAG, "Wrote authrequest, got: " + JoH.bytesToHex(characteristicValue));
speakSlowly();
connection.readCharacteristic(Authentication).subscribe(
readValue -> {
authenticationProcessor(parent, connection, readValue);
}, throwable -> {
UserError.Log.e(TAG, "Could not read after AuthRequestTX: " + throwable);
});
//parent.background_automata();
},
throwable -> {
UserError.Log.e(TAG, "Could not write AuthRequestTX: " + throwable);
parent.incrementErrors();
}
);
}).flatMap(notificationObservable -> notificationObservable)
//.timeout(5, TimeUnit.SECONDS)
//.observeOn(Schedulers.newThread())
.subscribe(bytes -> {
// incoming notifications
UserError.Log.d(TAG, "Received Authentication notification bytes: " + JoH.bytesToHex(bytes));
authenticationProcessor(parent, connection, bytes);
}, throwable -> {
if (!(throwable instanceof OperationSuccess)) {
if (((parent.getState() == Ob1G5CollectionService.STATE.CLOSED)
|| (parent.getState() == Ob1G5CollectionService.STATE.CLOSE))
&& (throwable instanceof BleDisconnectedException)) {
UserError.Log.d(TAG, "normal authentication notification throwable: (" + parent.getState() + ") " + throwable + " " + JoH.dateTimeText(tsl()));
parent.connectionStateChange(CLOSED_OK_TEXT);
} else if ((parent.getState() == Ob1G5CollectionService.STATE.BOND) && (throwable instanceof TimeoutException)) {
// TODO Trigger on Error count / Android wear metric
// UserError.Log.e(TAG,"Attempting to reset/create bond due to: "+throwable);
// parent.reset_bond(true);
// parent.unBond(); // WARN
} else {
UserError.Log.e(TAG, "authentication notification throwable: (" + parent.getState() + ") " + throwable + " " + JoH.dateTimeText(tsl()));
parent.incrementErrors();
if (throwable instanceof BleCannotSetCharacteristicNotificationException
|| throwable instanceof BleGattCharacteristicException) {
parent.tryGattRefresh();
parent.changeState(Ob1G5CollectionService.STATE.SCAN);
}
}
if ((throwable instanceof BleDisconnectedException) || (throwable instanceof TimeoutException)) {
if ((parent.getState() == Ob1G5CollectionService.STATE.BOND) || (parent.getState() == Ob1G5CollectionService.STATE.CHECK_AUTH)) {
if (parent.getState() == Ob1G5CollectionService.STATE.BOND) {
UserError.Log.d(TAG, "SLEEPING BEFORE RECONNECT");
threadSleep(15000);
}
UserError.Log.d(TAG, "REQUESTING RECONNECT");
parent.changeState(Ob1G5CollectionService.STATE.SCAN);
}
}
}
});
return true;
}
示例18
private void bulkSend(final int opcode, final byte[] buffer, final int offset, boolean quiet) {
UserError.Log.d(TAG, "bulksend called: opcode " + opcode + " total " + buffer.length + " offset: " + offset + " quiet:" + quiet);
if (buffer != null && offset < buffer.length) {
final BulkUpTx packet = (opcode >= OPCODE_BULK_R_XFER_0 ? new RBulkUpTx(opcode, buffer, offset) : new BulkUpTx(opcode, buffer, offset));
if (quiet) {
packet.setQuiet();
}
if (offset == 0) {
revisedOffset = 0; // reset counter as this is new bulk up
lastActionedRevisedOffset = -1;
// TODO we should check it if we have failed to act on revised offset
}
I.connection.writeCharacteristic(quiet ? THINJAM_BULK : THINJAM_WRITE, packet.getBytes())
.observeOn(Schedulers.newThread())
.subscribe(
response -> {
if (D)
UserError.Log.d(TAG, "Bulk Up Send response: " + bytesToHex(response));
if (packet.responseOk(response)) {
// WARNING recursion
final int nextOffset;
if (revisedOffset != 0 && revisedOffset < offset && revisedOffset != lastActionedRevisedOffset) {
nextOffset = revisedOffset; // TODO we only catch this if we send a packet
lastActionedRevisedOffset = nextOffset;
UserError.Log.d(TAG, "Retrying bulk send from: " + nextOffset);
} else {
nextOffset = offset + packet.getBytesIncluded();
}
revisedOffset = 0;
if (nextOffset < buffer.length) {
if (!quiet) {
JoH.threadSleep(100);
} else {
JoH.threadSleep(1);
}
bulkSend(opcode, buffer, nextOffset, packet.isQuiet());
} else {
UserError.Log.d(TAG, "Bulk send completed!");
if (!(packet instanceof RBulkUpTx)) {
commandQueue.poll(); // removes first item from the queue which should be the one we just processed!
}
Inevitable.task("tj-next-queue", 4000, this::processQueue); // wait 1 second and then retry this upload if we get success reply notification then we remove it elsewhere
}
} else {
UserError.Log.d(TAG, "Bulk Send failed: " + packet.responseText(response));
if (!quiet) {
Inevitable.task("tj-next-queue", 20000, this::processQueue); // retry shortly
if (JoH.ratelimit("tj-allow-bulk-retry", 2)) {
UserError.Log.d(TAG, "Retrying packet");
bulkSend(opcode, buffer, offset, quiet); // retry packet send
}
} else {
UserError.Log.d(TAG, "Quiet is set so not attempting any response to failure here");
}
}
}, throwable -> {
UserError.Log.e(TAG, "Failed to write bulk Send: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
} else {
UserError.Log.d(TAG, "Throwable in Bulk SEnd write: " + throwable);
}
});
} else {
UserError.Log.d(TAG, "Invalid buffer in bulkSend");
}
}
示例19
@SuppressLint("CheckResult")
public static boolean doCheckAuth(Ob1G5CollectionService parent, RxBleConnection connection) {
if (connection == null) return false;
parent.msg("Authorizing");
if (parent.android_wear) {
speakSlowly = true;
UserError.Log.d(TAG, "Setting speak slowly to true"); // WARN should be reactive or on named devices
}
final AuthRequestTxMessage authRequest = new AuthRequestTxMessage(getTokenSize(), usingAlt());
UserError.Log.i(TAG, "AuthRequestTX: " + JoH.bytesToHex(authRequest.byteSequence));
connection.setupNotification(Authentication)
// .timeout(10, TimeUnit.SECONDS)
.timeout(15, TimeUnit.SECONDS) // WARN
// .observeOn(Schedulers.newThread()) // needed?
.doOnNext(notificationObservable -> {
connection.writeCharacteristic(Authentication, nn(authRequest.byteSequence))
.subscribe(
characteristicValue -> {
// Characteristic value confirmed.
if (d)
UserError.Log.d(TAG, "Wrote authrequest, got: " + JoH.bytesToHex(characteristicValue));
speakSlowly();
connection.readCharacteristic(Authentication).subscribe(
readValue -> {
authenticationProcessor(parent, connection, readValue);
}, throwable -> {
UserError.Log.e(TAG, "Could not read after AuthRequestTX: " + throwable);
});
//parent.background_automata();
},
throwable -> {
UserError.Log.e(TAG, "Could not write AuthRequestTX: " + throwable);
parent.incrementErrors();
}
);
}).flatMap(notificationObservable -> notificationObservable)
//.timeout(5, TimeUnit.SECONDS)
//.observeOn(Schedulers.newThread())
.subscribe(bytes -> {
// incoming notifications
UserError.Log.d(TAG, "Received Authentication notification bytes: " + JoH.bytesToHex(bytes));
authenticationProcessor(parent, connection, bytes);
}, throwable -> {
if (!(throwable instanceof OperationSuccess)) {
if (((parent.getState() == Ob1G5CollectionService.STATE.CLOSED)
|| (parent.getState() == Ob1G5CollectionService.STATE.CLOSE))
&& (throwable instanceof BleDisconnectedException)) {
UserError.Log.d(TAG, "normal authentication notification throwable: (" + parent.getState() + ") " + throwable + " " + JoH.dateTimeText(tsl()));
parent.connectionStateChange(CLOSED_OK_TEXT);
} else if ((parent.getState() == Ob1G5CollectionService.STATE.BOND) && (throwable instanceof TimeoutException)) {
// TODO Trigger on Error count / Android wear metric
// UserError.Log.e(TAG,"Attempting to reset/create bond due to: "+throwable);
// parent.reset_bond(true);
// parent.unBond(); // WARN
} else {
UserError.Log.e(TAG, "authentication notification throwable: (" + parent.getState() + ") " + throwable + " " + JoH.dateTimeText(tsl()));
parent.incrementErrors();
if (throwable instanceof BleCannotSetCharacteristicNotificationException
|| throwable instanceof BleGattCharacteristicException) {
parent.tryGattRefresh();
parent.changeState(Ob1G5CollectionService.STATE.SCAN);
}
}
if ((throwable instanceof BleDisconnectedException) || (throwable instanceof TimeoutException)) {
if ((parent.getState() == Ob1G5CollectionService.STATE.BOND) || (parent.getState() == Ob1G5CollectionService.STATE.CHECK_AUTH)) {
if (parent.getState() == Ob1G5CollectionService.STATE.BOND) {
UserError.Log.d(TAG, "SLEEPING BEFORE RECONNECT");
threadSleep(15000);
}
UserError.Log.d(TAG, "REQUESTING RECONNECT");
parent.changeState(Ob1G5CollectionService.STATE.SCAN);
}
}
}
});
return true;
}
示例20
private void getRecords(final int firstIndex, final int lastIndex) {
final int numberOfRecords = lastIndex - firstIndex;
if (numberOfRecords > 30) {
I.connection.writeCharacteristic(KEEPALIVE, new KeepAliveTx().getBytes()).subscribe(
value -> {
UserError.Log.d(TAG, "Wrote keep alive for " + numberOfRecords);
}, throwable -> {
UserError.Log.d(TAG, "Got exception in keep alive" + throwable);
});
}
final RecordTx packet = new RecordTx(firstIndex, lastIndex);
UserError.Log.d(TAG, "getRecords called, loading: " + firstIndex + " to " + lastIndex);
I.connection.setupIndication(RECORD_INDICATE).doOnNext(notificationObservable -> {
I.connection.writeCharacteristic(RECORD_START, packet.startBytes()).subscribe(valueS -> {
UserError.Log.d(TAG, "Wrote record start: " + bytesToHex(valueS));
I.connection.writeCharacteristic(RECORD_END, packet.endBytes()).subscribe(valueE -> {
UserError.Log.d(TAG, "Wrote record end: " + bytesToHex(valueE));
I.connection.writeCharacteristic(RECORD_REQUEST, packet.triggerBytes()).subscribe(
characteristicValue -> {
if (D)
UserError.Log.d(TAG, "Wrote record request request: " + bytesToHex(characteristicValue));
}, throwable -> {
UserError.Log.e(TAG, "Failed to write record request: " + throwable);
if (throwable instanceof BleGattCharacteristicException) {
final int status = ((BleGattCharacteristicException) throwable).getStatus();
UserError.Log.e(TAG, "Got status message: " + Helper.getStatusName(status));
}
});
}, throwable -> {
UserError.Log.d(TAG, "Throwable in Record End write: " + throwable);
});
}, throwable -> {
UserError.Log.d(TAG, "Throwable in Record Start write: " + throwable);
// throws BleGattCharacteristicException status = 128 for "no resources" eg nothing matches
});
})
.flatMap(notificationObservable -> notificationObservable)
.timeout(120, TimeUnit.SECONDS)
.observeOn(Schedulers.newThread())
.subscribe(bytes -> {
records.add(bytes);
UserError.Log.d(TAG, "INDICATE INDICATE: " + HexDump.dumpHexString(bytes));
}, throwable -> {
if (!(throwable instanceof OperationSuccess)) {
if (throwable instanceof BleDisconnectedException) {
UserError.Log.d(TAG, "Disconnected when waiting to receive indication: " + throwable);
} else {
UserError.Log.e(TAG, "Error receiving indication: " + throwable);
}
Inevitable.task("check-records-queue", 100, this::processRecordsQueue);
}
});
}
示例21
private boolean isErrorResponse(final Object throwable) {
return throwable instanceof BleGattCharacteristicException && ((BleGattException) throwable).getStatus() == 1;
}