com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException Java Examples

The following examples show how to use com.polidea.rxandroidble2.exceptions.BleGattCharacteristicException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Ob1G5StateMachine.java    From xDrip with GNU General Public License v3.0 6 votes vote down vote up
@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;
}
 
Example #2
Source File: BlueJayService.java    From xDrip with GNU General Public License v3.0 6 votes vote down vote up
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
}
 
Example #3
Source File: Ob1G5StateMachine.java    From xDrip-plus with GNU General Public License v3.0 6 votes vote down vote up
@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;
}
 
Example #4
Source File: Ob1G5StateMachine.java    From xDrip with GNU General Public License v3.0 6 votes vote down vote up
@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;
}
 
Example #5
Source File: Ob1G5StateMachine.java    From xDrip-plus with GNU General Public License v3.0 6 votes vote down vote up
@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;
}
 
Example #6
Source File: BlueJayService.java    From xDrip-plus with GNU General Public License v3.0 6 votes vote down vote up
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
}
 
Example #7
Source File: BlueJayService.java    From xDrip with GNU General Public License v3.0 5 votes vote down vote up
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);
                }

            });
}
 
Example #8
Source File: BlueJayService.java    From xDrip with GNU General Public License v3.0 5 votes vote down vote up
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);
                    }
                }
            });
}
 
Example #9
Source File: RxBleGattCallback.java    From RxAndroidBle with Apache License 2.0 5 votes vote down vote up
static boolean propagateErrorIfOccurred(
        Output<?> output,
        BluetoothGatt gatt,
        BluetoothGattCharacteristic characteristic,
        int status,
        BleGattOperationType operationType
) {
    return isException(status) && propagateStatusError(output, new BleGattCharacteristicException(
            gatt,
            characteristic,
            status,
            operationType
    ));
}
 
Example #10
Source File: BlueJayService.java    From xDrip-plus with GNU General Public License v3.0 5 votes vote down vote up
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);
                    }
                }
            });
}
 
Example #11
Source File: BlueJayService.java    From xDrip-plus with GNU General Public License v3.0 5 votes vote down vote up
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);
                }

            });
}
 
Example #12
Source File: InPenService.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
private boolean isErrorResponse(final Object throwable) {
    return throwable instanceof BleGattCharacteristicException && ((BleGattException) throwable).getStatus() == 1;
}
 
Example #13
Source File: InPenService.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
private boolean isErrorResponse(final Object throwable) {
    return throwable instanceof BleGattCharacteristicException && ((BleGattException) throwable).getStatus() == 1;
}
 
Example #14
Source File: InPenService.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
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);
                    }
                });

    }
 
Example #15
Source File: Ob1G5StateMachine.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
@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;
}
 
Example #16
Source File: BlueJayService.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
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");
    }
}
 
Example #17
Source File: Ob1G5StateMachine.java    From xDrip-plus with GNU General Public License v3.0 4 votes vote down vote up
@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;
}
 
Example #18
Source File: InPenService.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
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);
                    }
                });

    }
 
Example #19
Source File: Ob1G5StateMachine.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
@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;
}
 
Example #20
Source File: BlueJayService.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
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");
    }
}
 
Example #21
Source File: Ob1G5StateMachine.java    From xDrip with GNU General Public License v3.0 4 votes vote down vote up
@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;
}