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;
}