为什么onCharacteristicWrite()晚于BLE通信中的onCharacteristicChanged()

时间:2017-06-16 09:43:15

标签: android bluetooth-lowenergy

我试图通过BLE在android和其他arm设备之间交换一些数据,并且由于MTU的限制,大数据被分成小片段。为了具有鲁棒性,只有在确认其前一帧(writeCharacteristic)时,才能发送一帧(onCharacteristicWrite)。现在问题出现了:当Android设备完成发送最后一帧然后从对等设备接收数据时(onCharacteristicChanged),它的接缝onCharacteristicWrite晚于onCharacteristicChanged(至少日志说那,这是我的代码。

@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    if (status != BluetoothGatt.GATT_SUCCESS) {
        stateProcessError();                 // State = STATE_IDLE
        return;                              // Log.v("error occurs", "do something");
    }
    Log.v("didsend", "State:" + State);
    processEvent(sp_event.DATA_SEND_CFM, null);
}

@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    Log.v("didrecv", "State:" + State);
    Object msg = constructRxMsg(characteristic.getValue());
    processEvent(sp_event.DATA_RECV_CFM, msg);
}

private void stateSendAuthReq(sp_event event) {
    switch (event) {
        case DATA_IDLE: {
            SPTxMsgAuthReq msg = new SPTxMsgAuthReq(Mode);
            sendData(msg.getMsg());
        }
            break;
        case DATA_SEND_CFM:
            State = sp_state.STATE_RECV_AUTH_RES;
            Log.v("sendReq", "change State");
            break;
        default:
            Log.v("sendReq", "default");
            this.stateProcessError();
            break;
    }
}

private void stateRecvAuthRes(sp_event event, SPRxMsgAuthRes msg) {
    if (sp_event.DATA_RECV_CFM != event || null == msg) {
        this.stateProcessError();
        return;
    }
    if (MSG_TYPE_AUTH_RES != msg.getType() || STATUS_AUTH_READY != msg.getStatus()) {   
        Log.v("recvAuthRes", "incorrect param");
        this.stateProcessError();
        return;
    }                
    State = sp_state.STATE_RECV_NONCE;
}

private void processEvent(sp_event event, Object msg) {
    switch (State) {
        case STATE_IDLE:
            this.stateSendAuthReq(event)
            break;
        case STATE_RECV_AUTH_RES:
            this.stateRecvAuthRes(event, (SPRxMsgAuthRes) msg);
            break;
        ......
    }
}

日志显示问题:

06-16 17:32:46.521 10300-10412/alps.ble.bt V/send: data:[-32, 3, 3, 1, 0]
06-16 17:32:46.621 10300-10406/alps.ble.bt V/didrecv: State:STATE_IDEL
06-16 17:32:46.621 10300-10406/alps.ble.bt V/constructRxMsg: data:[-31, 2, 3, 0]
06-16 17:32:46.621 10300-10406/alps.ble.bt V/error occurs: do something
06-16 17:32:46.621 10300-10406/alps.ble.bt V/didsend: State:STATE_IDLE

接下来是没有错误时的日志:

06-16 16:30:05.871 22401-22502/alps.ble.bt V/send: data:[-32, 3, 3, 1, 0]
06-16 16:30:05.911 22401-22471/alps.ble.bt D/BluetoothGatt: onClientConnParamsChanged() - Device=68:68:28:40:12:8E interval=39 status=0
06-16 16:30:05.961 22401-22413/alps.ble.bt V/didsend: State:STATE_IDLE
06-16 16:30:05.961 22401-22413/alps.ble.bt V/didrecv: State:STATE_RECV_AUTH_RES
06-16 16:30:05.961 22401-22413/alps.ble.bt V/constructRxMsg: data:[-31, 2, 3, 0]

注意:对等设备中的代码应该是正确的,因为当我在iOS而不是android上进行测试时一切正常。

我希望已经提供了足够的信息,我们将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

经过这么多尝试之后问题仍然存在,我别无选择,只能像使用缓冲区和标志一样避免它,我愿意分享它。

Error: Failed to fetch plugin https://github.com/zckrs/cordova-plugin-android-support-v4.git via registry.
Probably this is either a connection problem, or plugin spec is incorrect.
Check your connection and plugin name/version/URL.

Error: cmd: Command failed with exit code 1 Error output:
npm WARN package.json helloworld@1.0.0 No repository field.
npm WARN package.json helloworld@1.0.0 No README data
npm WARN addRemoteGit Error: not found: git
npm WARN addRemoteGit at getNotFoundError (C:\Program Files\nodejs\node_modules\npm\node_modules\which\which.js:14:12)
npm WARN addRemoteGit at F (C:\Program Files\nodejs\node_modules\npm\node_modules\which\which.js:69:19)
npm WARN addRemoteGit at E (C:\Program Files\nodejs\node_modules\npm\node_modules\which\which.js:81:29)
npm WARN addRemoteGit at C:\Program Files\nodejs\node_modules\npm\node_modules\which\which.js:90:16
npm WARN addRemoteGit at C:\Program Files\nodejs\node_modules\npm\node_modules\which\node_modules\isexe\index.js:44:5
npm WARN addRemoteGit at C:\Program Files\nodejs\node_modules\npm\node_modules\which\node_modules\isexe\windows.js:29:5

npm ERR! node v4.4.7
npm ERR! npm  v2.15.8
npm ERR! code ENOGIT

npm ERR! not found: git
npm ERR!
npm ERR! Failed using git.
npm ERR! This is most likely not a problem with npm itself.
npm ERR! Please check if you have git installed and in your PATH.

npm ERR! Please include the following file with any support request:
npm ERR! D:\ExerciseApp\node_modules\npm-debug.log

对于重新连接的情况,应清除缓冲区和标志。

private boolean isSending = false;
private byte[] lastRecvData = null;

private void sendData(byte[] data) {
    Log.v("1", "Send data ...");
    mCharacteristic.setValue(data);
    mBluetoothGatt.writeCharacteristic(mCharacteristic)
    isSending = true;
}

@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
    isSending = false;
    if (status != BluetoothGatt.GATT_SUCCESS) {
        return;
    }
    Log.v("2", "Send data successfully");
    processEvent(sp_event.DATA_SEND_CFM, null);

    if (lastRecvData != null) {
        Object msg = constructRxMsg(lastRecvData);
        processEvent(sp_event.DATA_RECV_CFM, msg);
        lastRecvData = null;
    }
}

@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
    if (isSending) {
        lastRecvData = characteristic.getValue().clone();
    }else {
        Log.v("3", "Recv data");
        Object msg = constructRxMsg(characteristic.getValue());
        processEvent(sp_event.DATA_RECV_CFM, msg);
    }
}

如果有人对这个问题有更好的想法或解决方案,我们将不胜感激,最后谢谢你。