我有一個定製的硬件與藍牙低能量芯片。我已經用500 u32s的數組設置它,例如array [n] == n。我正在研究一個可連接到設備的android應用程序,請求數組的長度,然後一次請求數組中的數據點。onCharacteristicWrite()被調用,但它並不總是寫
Android應用似乎大多工作正常。它連接到設備,請求長度,並在收到上一部分後繼續請求下一條數據。然而,在數組中的任何部分(任何地方有2到450個元素 - 看起來不一致),它會寫入另一個命令,並且它會一直到onCharacteristicWrite(),但它永遠不會收到響應。我將我的BLE外設連接到CoolTerm,並且它甚至從未收到該命令。下面是我的代碼片段和原木:
BLEService:
private final BluetoothGattCallback bleGattCallback = new BluetoothGattCallback() {
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
Log.d("onCharacteristicRead", byteArrToHex(characteristic.getValue()));
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if(status != BluetoothGatt.GATT_SUCCESS){
Log.d("onCharacteristicWrite", "Failed write, retrying");
gatt.writeCharacteristic(characteristic);
}
Log.d("onCharacteristicWrite", byteArrToHex(characteristic.getValue()));
super.onCharacteristicWrite(gatt, characteristic, status);
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
Log.d("onCharacteristicChanged", byteArrToHex(characteristic.getValue()));
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
};
我省略了相關描述回調的不必要的部分寫道,連接狀態的變化,等等。當數據被廣播,它接收MainActivity的這一部分:
private BroadcastReceiver messageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String receivedUUID = intent.getStringExtra("uuid");
byte[] data = intent.getByteArrayExtra("data");
Log.d("messageReceiver", "received intent in mainActivity with uuid " + receivedUUID.toString());
if(receivedUUID.equals(READ_LEN_UUID.toString()) && currentlyReading) {
datapoints = new ArrayList<Long>();
numberOfDatapoints = 0;
numberOfDatapoints |= (data[0] & 0xff);
numberOfDatapoints |= (data[1] & 0xff) << 8;
numberOfDatapoints |= (data[2] & 0xff) << 16;
numberOfDatapoints |= (data[3] & 0xff) << 24;
Log.d("RECEIVER TEST:", "number of datapoints = " + numberOfDatapoints);
if(numberOfDatapoints > 0) {
bleService.requestDatapoint(0);
}
} else if (receivedUUID.equals(READ_DATAPOINT_UUID.toString()) && currentlyReading){
long message = 0;
message |= (data[0] & 0xff);
message |= (data[1] & 0xff) << 8;
message |= (data[2] & 0xff) << 16;
message |= (data[3] & 0xff) << 24;
Log.d("Datapoint Recieved", "Index " + datapoints.size() + " = " + message);
datapoints.add(message);
if(datapoints.size() < numberOfDatapoints){
bleService.requestDatapoint(datapoints.size());
}
}
}
};
的代碼調用writeCharacteristic:
public void requestDatapoint(int index){
Log.d("requestDatapoint", "Requested datapoint at " + index);
BluetoothGattCharacteristic commandChar = this.gattService.getCharacteristic(WRITE_UUID);
byte[] request = new byte[3];
// command - 2 = get index
request[0] = (byte) (2 & 0xff);
// index
request[1] = (byte) ((index) & 0xff);
request[2] = (byte) ((index >> 8) & 0xff);
commandChar.setValue(request);
bleGatt.writeCharacteristic(commandChar);
}
我很確定發送命令太快沒有問題。這實際上非常慢,我故意這樣做,以便在進入項目的下一部分之前,我可以更輕鬆地進行測試。
08-23 12:08:18.470 16753-16753/sethp.datalogcollector D/requestDatapoint: Requested datapoint at 49
08-23 12:08:18.570 16753-16765/sethp.datalogcollector D/onCharacteristicWrite: 02 31 00
08-23 12:08:18.570 16753-16765/sethp.datalogcollector D/onCharacteristicChanged: 31 00 00 00
08-23 12:08:18.570 16753-16765/sethp.datalogcollector D/BLEService: Characteristic found. UUID: 00020000-5f5f-4a49-4847-464544434241
08-23 12:08:18.575 16753-16753/sethp.datalogcollector D/messageReceiver: received intent in mainActivity with uuid 00020000-5f5f-4a49-4847-464544434241
08-23 12:08:18.575 16753-16753/sethp.datalogcollector D/Datapoint Recieved: Index 49 = 49
08-23 12:08:18.575 16753-16753/sethp.datalogcollector D/requestDatapoint: Requested datapoint at 50
08-23 12:05:55.585 16753-16765/sethp.datalogcollector D/onCharacteristicWrite: 02 32 00
08-23 12:05:55.585 16753-16765/sethp.datalogcollector D/onCharacteristicChanged: 32 00 00 00
08-23 12:05:55.585 16753-16765/sethp.datalogcollector D/BLEService: Characteristic found. UUID: 00020000-5f5f-4a49-4847-464544434241
08-23 12:05:55.585 16753-16753/sethp.datalogcollector D/messageReceiver: received intent in mainActivity with uuid 00020000-5f5f-4a49-4847-464544434241
08-23 12:05:55.590 16753-16753/sethp.datalogcollector D/Datapoint Recieved: Index 50 = 50
08-23 12:05:55.590 16753-16753/sethp.datalogcollector D/requestDatapoint: Requested datapoint at 51
08-23 12:05:55.680 16753-16845/sethp.datalogcollector D/onCharacteristicWrite: 02 33 00
08-23 12:05:55.685 16753-16764/sethp.datalogcollector D/onCharacteristicChanged: 33 00 00 00
08-23 12:05:55.685 16753-16764/sethp.datalogcollector D/BLEService: Characteristic found. UUID: 00020000-5f5f-4a49-4847-464544434241
08-23 12:05:55.685 16753-16753/sethp.datalogcollector D/messageReceiver: received intent in mainActivity with uuid 00020000-5f5f-4a49-4847-464544434241
08-23 12:05:55.685 16753-16753/sethp.datalogcollector D/Datapoint Recieved: Index 51 = 51
08-23 12:05:55.685 16753-16753/sethp.datalogcollector D/requestDatapoint: Requested datapoint at 52
08-23 12:05:55.785 16753-16765/sethp.datalogcollector D/onCharacteristicChanged: 34 00 00 00
08-23 12:05:55.785 16753-16765/sethp.datalogcollector D/BLEService: Characteristic found. UUID: 00020000-5f5f-4a49-4847-464544434241
08-23 12:05:55.785 16753-16753/sethp.datalogcollector D/messageReceiver: received intent in mainActivity with uuid 00020000-5f5f-4a49-4847-464544434241
08-23 12:05:55.785 16753-16753/sethp.datalogcollector D/Datapoint Recieved: Index 52 = 52
08-23 12:05:55.785 16753-16753/sethp.datalogcollector D/requestDatapoint: Requested datapoint at 53
08-23 12:05:55.790 16753-16765/sethp.datalogcollector D/onCharacteristicWrite: 02 35 00
和我的相應CoolTerm日誌摘錄:
command: 02
index: 0031
command = 2
datapoint at 49 = 49
attempting to send 49
command: 02
index: 0032
command = 2
datapoint at 50 = 50
attempting to send 50
command: 02
index: 0033
command = 2
datapoint at 51 = 51
attempting to send 51
command: 02
index: 0034
command = 2
datapoint at 52 = 52
attempting to send 52
注意,在我的周圍的日誌,它不會出現接收請求從我的調試日誌,一個
的片斷for datapoint 53. 作爲參考,onCharacteristicWrite調試中的第一個十六進制字節是命令。命令02只是意味着我正在請求一個數據點在下一個2字節包含的索引處。
我注意到,在Android日誌中,沒有用於請求數據點51的onCharacteristicWrite日誌。這似乎每次都發生在它停止獲取數據之前,但我不確定這是否顯着或如果這只是日誌緩衝區的問題。
我已經運行了很多測試,試圖注意到任何模式,並且我注意到,當設備沒有連接到調試電纜時,它似乎獲得了更多的數據點。我現在唯一的想法是,也許我有一個異步中斷回調的問題,但我不知道會做什麼。有沒有人想過爲什麼在調用onCharacteristicWrite之後似乎沒有真正寫入數據?
感謝
編輯:
我跟着埃米爾的建議,並開啓藍牙記錄。我用wireshark玩弄了一下,弄清楚發生了什麼事情。我再次嘗試了我的應用程序,然後運行到索引102,直到它停止,此時我斷開了設備連接。我在Wireshark中挖掘了數據包,發現我的設備DID收到了大約102的數據,但它沒有發送103的請求。我仔細檢查了我的android日誌,並從onCharacteristicWrite內部的一條Log語句表示它發送了命令02 67 00,這是對103的請求。所以,看起來onCharacteristicWrite被調用,但實際上並沒有寫入該特性。
經過一番更多的盯着和思考之後,我很確定1)onCharacteristicWrite被錯誤地調用,因爲數據永遠不會被寫入,或者2)某種程度上異步的中斷會阻止它傳輸。我不知道這樣做會是什麼。
最後編輯:
即使這樣,據我從規範理解,onCharacteristicWrite只應該被稱爲當一個可靠的,成功寫入過程中,我決定檢查從writeCharacteristic的返回值。我應該在幾個小時前檢查。你知道什麼,它是在最後一次請求時返回錯誤的。
我認爲onCharacteristicWrite被調用即使返回值爲false也是一個錯誤。我讀過使用onCharacteristicWrite調用寫入下一塊數據是安全的。要麼他們錯了,要麼就是在這裏發生一些棘手的事情。無論哪種方式,我想這是一個非常好的主意,檢查這些函數調用返回值。
你可以顯示實際調用writeCharacteristic的代碼嗎? – Emil
當然,現在加入它 – Seth
嗯,這似乎很奇怪。您是否使用https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html#WRITE_TYPE_NO_RESPONSE?此外,您可以嘗試啓用bluetooth hci snoop日誌,然後在Wireshark中檢查它以查看無線發送的內容。 – Emil