アンドロイドと他のアームデバイスの間でBLE経由でデータを交換しようとしていますが、大きなデータがMTUの制限から小さなフラグメントに分割されました。ロバストネスのために、前のフレームが確認されたときに(によって)1つのフレームのみが送信される(writeCharacteristic
によって)。ここで問題が発生します:アンドロイドデバイスが最後のフレームの送信を完了し、ピアデバイスからデータを受信すると(onCharacteristicChanged
によって)、それはonCharacteristicChanged
より後になります(少なくともログにはそれがあります)。BLE通信でonCharacteristicChanged()が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]
注:すべてがOKだったので、ピアデバイス内のコードが正しいはずです私はアンドロイドの代わりにiOSでテストします。
十分な情報が提供されており、助力をいただければ幸いです。ありがとうございます!
通知の前にペリフェラルが書き込み応答を送信したことは本当に確かですか?これを確認するには、BLEスニッファハードウェアを使用するか、HCIスヌープログを調べてAndroidで有効にしてからWiresharkを調べます。そしてその注文は本当にあなたのために重要ですか?いずれにしても動作するようにコードを書き直すことはできませんでしたか? – Emil
はい、フロントラインBPA600を使用してこの問題をチェックしました。エアロログは注文が正しいことを示していました。私の意見では、私の使用や設定で何かが間違っていた可能性があります。私のコードにおける状態の変化は、これら2つの関数に依存しますが、この問題を避けるために書き直すことができます。とにかく私はそれを確認し、最後にあなたに感謝:) – shinyathena