Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin BlegatCharacteristicException:试图指示->;时的GATT异常状态129;写入->;通知BLE血糖仪_Kotlin_Rx Java2_Rxandroidble - Fatal编程技术网

Kotlin BlegatCharacteristicException:试图指示->;时的GATT异常状态129;写入->;通知BLE血糖仪

Kotlin BlegatCharacteristicException:试图指示->;时的GATT异常状态129;写入->;通知BLE血糖仪,kotlin,rx-java2,rxandroidble,Kotlin,Rx Java2,Rxandroidble,我正在尝试使用rxAndroidBle库读取血糖仪中存储的所有记录。根据我发现的一些资源,配对/连接和连接到设备后,该过程包括三个主要步骤: 记录访问控制点特性(RACP)中的设置指示 关于葡萄糖测量特性的设置通知 在RACP特征上写入两个字节0x01、0x01 然后,如果有任何记录,通知应该是流动的 现在,这个流程在装有安卓7.0的LG G5上运行得很好,但在我能访问的其他手机上就不行了。它将抛出一个可怕的关贸总协定内部错误(状态129),这有点模棱两可。我发现它描述了我可能面临的情况 我担心

我正在尝试使用rxAndroidBle库读取血糖仪中存储的所有记录。根据我发现的一些资源,配对/连接和连接到设备后,该过程包括三个主要步骤:

  • 记录访问控制点特性(RACP)中的设置指示
  • 关于葡萄糖测量特性的设置通知
  • 在RACP特征上写入两个字节0x01、0x01
  • 然后,如果有任何记录,通知应该是流动的

    现在,这个流程在装有安卓7.0的LG G5上运行得很好,但在我能访问的其他手机上就不行了。它将抛出一个可怕的关贸总协定内部错误(状态129),这有点模棱两可。我发现它描述了我可能面临的情况

    我担心的是,这是可行的,但它可能与固件有关,这很奇怪,因为我看到它在其他连接到血糖仪的应用程序上完美地工作,在任何设备上都没有问题

    下面是我的测试代码现在的样子:

    fun loadRecords(rxBleDevice: RxBleDevice){
    ...
    ...
    rxBleDevice.establishConnection(false)
       .flatMap { rxBleConnection: RxBleConnection ->
            rxBleConnection.setupIndication(racpUUID)
                .flatMapSingle {
                    Single.just(rxBleConnection)
                }
        }
        .flatMap { rxBleConnection ->
            writeAndReadOnNotification(racpUUID, 
                                       glucoseUUID, 
                                       byteArrayOf(0x01, 0x01), 
                                       false, 
                                       rxBleConnection)
        }
        .subscribe(
            { it:ByteArray ->
                decodeReading(it)
            },Logger::logException)
    }
    
    private fun writeAndReadOnNotification(writeTo: UUID, readOn: UUID,
                                               bytes: ByteArray,
                                               isIndication: Boolean,
                                        rxBleConnection:RxBleConnection)
    : Observable<ByteArray> {
        val notifObservable = if (isIndication)
                rxBleConnection.setupIndication(readOn)
            else
                rxBleConnection.setupNotification(readOn)
        return notifObservable.flatMap { notificationObservable ->
                Observable.combineLatest(
                        notificationObservable,
                        rxBleConnection.writeCharacteristic(writeTo, bytes).toObservable(),
                        BiFunction { readBytes: ByteArray, writeBytes: ByteArray -> readBytes })
            }
        }
    
    
    fun loadRecords(rxBleDevice: RxBleDevice){
    ...
    //Do stuff
    ...
        rxBleDevice.establishConnection(false)
            .flatMap { rxBleConnection: RxBleConnection ->
    
        rxBleConnection.setupNotification(glucoseUUID,
                                          NotificationSetupMode.QUICK_SETUP)
            .flatMapSingle {
                Single.just(Pair(it, rxBleConnection))
            }
        }
        .flatMap { (observable, rxBleConnection)  ->
            writeAndReadOnNotification(racpUUID, 
                                       racpUUID, 
                                       byteArrayOf(0x01, 0x01),
                                       true, 
                                       rxBleConnection).subscribe()
            observable
        }
        .subscribe(
            {
                decodeReading(it)
            },Logger::logException)
    }
    

    我的代码中有什么遗漏吗?为什么它能在一些手机上工作?

    我自己设法解决了这个问题。通过查看我之前发布的日志,我发现在设置指示和通知之后,指示和通知都被禁用,因此我对库进行了深入的探索,以了解它为什么这样做。我发现,在以任何特征设置通知之前,都不应该设置指示(即使它们是两个不同的特征)。因此,阅读本文的主要步骤应按以下顺序进行:

  • 建立葡萄糖特性通知并持续观察
  • 在RACP上设置指示
  • 将0x01、0x01写入RACP
  • 利润
  • 我还在库代码中找到了此注释:

    /*
    *注意:由于特征的状态性质,如果在setupNotification()之前将setupIndication()设置为
    *将不会设置通知,并将发出其他类型ReadySetException的BleCharacteristicNotification
    */
    
    这导致我将通知部分移到指示部分之前。 下面是它现在的样子:

    fun loadRecords(rxBleDevice: RxBleDevice){
    ...
    ...
    rxBleDevice.establishConnection(false)
       .flatMap { rxBleConnection: RxBleConnection ->
            rxBleConnection.setupIndication(racpUUID)
                .flatMapSingle {
                    Single.just(rxBleConnection)
                }
        }
        .flatMap { rxBleConnection ->
            writeAndReadOnNotification(racpUUID, 
                                       glucoseUUID, 
                                       byteArrayOf(0x01, 0x01), 
                                       false, 
                                       rxBleConnection)
        }
        .subscribe(
            { it:ByteArray ->
                decodeReading(it)
            },Logger::logException)
    }
    
    private fun writeAndReadOnNotification(writeTo: UUID, readOn: UUID,
                                               bytes: ByteArray,
                                               isIndication: Boolean,
                                        rxBleConnection:RxBleConnection)
    : Observable<ByteArray> {
        val notifObservable = if (isIndication)
                rxBleConnection.setupIndication(readOn)
            else
                rxBleConnection.setupNotification(readOn)
        return notifObservable.flatMap { notificationObservable ->
                Observable.combineLatest(
                        notificationObservable,
                        rxBleConnection.writeCharacteristic(writeTo, bytes).toObservable(),
                        BiFunction { readBytes: ByteArray, writeBytes: ByteArray -> readBytes })
            }
        }
    
    
    fun loadRecords(rxBleDevice: RxBleDevice){
    ...
    //Do stuff
    ...
        rxBleDevice.establishConnection(false)
            .flatMap { rxBleConnection: RxBleConnection ->
    
        rxBleConnection.setupNotification(glucoseUUID,
                                          NotificationSetupMode.QUICK_SETUP)
            .flatMapSingle {
                Single.just(Pair(it, rxBleConnection))
            }
        }
        .flatMap { (observable, rxBleConnection)  ->
            writeAndReadOnNotification(racpUUID, 
                                       racpUUID, 
                                       byteArrayOf(0x01, 0x01),
                                       true, 
                                       rxBleConnection).subscribe()
            observable
        }
        .subscribe(
            {
                decodeReading(it)
            },Logger::logException)
    }
    

    我知道它看起来很难看,需要抛光。

    我自己解决了这个问题。通过查看我之前发布的日志,我发现在设置指示和通知之后,指示和通知都被禁用,因此我对库进行了深入的探索,以了解它为什么这样做。我发现,在以任何特征设置通知之前,都不应该设置指示(即使它们是两个不同的特征)。因此,阅读本文的主要步骤应按以下顺序进行:

  • 建立葡萄糖特性通知并持续观察
  • 在RACP上设置指示
  • 将0x01、0x01写入RACP
  • 利润
  • 我还在库代码中找到了此注释:

    /*
    *注意:由于特征的状态性质,如果在setupNotification()之前将setupIndication()设置为
    *将不会设置通知,并将发出其他类型ReadySetException的BleCharacteristicNotification
    */
    
    这导致我将通知部分移到指示部分之前。 下面是它现在的样子:

    fun loadRecords(rxBleDevice: RxBleDevice){
    ...
    ...
    rxBleDevice.establishConnection(false)
       .flatMap { rxBleConnection: RxBleConnection ->
            rxBleConnection.setupIndication(racpUUID)
                .flatMapSingle {
                    Single.just(rxBleConnection)
                }
        }
        .flatMap { rxBleConnection ->
            writeAndReadOnNotification(racpUUID, 
                                       glucoseUUID, 
                                       byteArrayOf(0x01, 0x01), 
                                       false, 
                                       rxBleConnection)
        }
        .subscribe(
            { it:ByteArray ->
                decodeReading(it)
            },Logger::logException)
    }
    
    private fun writeAndReadOnNotification(writeTo: UUID, readOn: UUID,
                                               bytes: ByteArray,
                                               isIndication: Boolean,
                                        rxBleConnection:RxBleConnection)
    : Observable<ByteArray> {
        val notifObservable = if (isIndication)
                rxBleConnection.setupIndication(readOn)
            else
                rxBleConnection.setupNotification(readOn)
        return notifObservable.flatMap { notificationObservable ->
                Observable.combineLatest(
                        notificationObservable,
                        rxBleConnection.writeCharacteristic(writeTo, bytes).toObservable(),
                        BiFunction { readBytes: ByteArray, writeBytes: ByteArray -> readBytes })
            }
        }
    
    
    fun loadRecords(rxBleDevice: RxBleDevice){
    ...
    //Do stuff
    ...
        rxBleDevice.establishConnection(false)
            .flatMap { rxBleConnection: RxBleConnection ->
    
        rxBleConnection.setupNotification(glucoseUUID,
                                          NotificationSetupMode.QUICK_SETUP)
            .flatMapSingle {
                Single.just(Pair(it, rxBleConnection))
            }
        }
        .flatMap { (observable, rxBleConnection)  ->
            writeAndReadOnNotification(racpUUID, 
                                       racpUUID, 
                                       byteArrayOf(0x01, 0x01),
                                       true, 
                                       rxBleConnection).subscribe()
            observable
        }
        .subscribe(
            {
                decodeReading(it)
            },Logger::logException)
    }
    
    我知道它看起来很丑,需要擦亮