簡體   English   中英

Android BLE-外圍設備| onCharacteristicRead返回錯誤的值或其一部分(但重復)

[英]Android BLE - Peripheral | onCharacteristicRead return wrong value or part of it (but repeated)

我對這個問題迷失了方向。

事實是,一個發布字符串值的android設備:“ 78d89537-4309-4728-87f6-3ab2bbe231d8”(36個字節)。 我正在使用定義為

 anonIdCharacteristic = new BluetoothGattCharacteristic(TippeeBluetoothManager.UUID_READ_CHARACTERISTIC,
            BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_BROADCAST,
            BluetoothGattCharacteristic.PERMISSION_READ  );
    anonIdCharacteristic.setValue(idToAdvertise);

如您所見,我在“閱讀”模式下投放廣告,沒有通知。

當另一個Android設備連接並嘗試讀取特征時,將調用onCharacteristicRead方法, 傳遞的值錯誤。 更具體地說是:

“ 78d89537-4309-4728-87f678d89537-4309-4728-87f678d89537-4309-4728-87f6 ...”(600字節)

這是預期值的一部分,但會重復。

如果我將自己放在調試“服務器端”,則可以看到發送的字節數正確。 在調試“客戶端”字節為600

我究竟做錯了什么 ?

提前致謝

----編輯-

我發現了更多信息。

現在,我以新月形偏移量反復調用onCharacteristicReadRequest,這導致了“臟”緩沖區,現在我以這種方式進行響應:

if (BluetoothManager.UUID_READ_CHARACTERISTIC.equals(characteristic.getUuid())) { mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, getStoredValue()); return; }

使用偏移值。 尚無法正常工作,但確實如此。

我不知道該告訴應用程序響應多長時間。

好的,我明白了,所以我會留下我的答復來幫助別人解決我的問題。

正確的解決方案是

@Override
        public void onCharacteristicReadRequest(BluetoothDevice device,
                                                int requestId,
                                                int offset,
                                                BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
            Log.i(TAG, "onCharacteristicReadRequest " + characteristic.getUuid().toString());

            byte[] fullValue = getStoredValue();

            //check
            if (offset > fullValue.length) {
                mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, new byte[]{0} );
                return;

            }


            int size = fullValue.length - offset;
            byte[] response = new byte[size];

            for (int i = offset; i < fullValue.length; i++) {
                response[i - offset] = fullValue[i];
            }



            if (MYBluetoothManager.UUID_READ_CHARACTERISTIC.equals(characteristic.getUuid())) {
                mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, response);
                return;
            }



            mGattServer.sendResponse(device,
                    requestId,
                    BluetoothGatt.GATT_FAILURE,
                    0,
                    null);
        }

    };

回調函數被多次調用,並帶有偏移量,這很明顯。 不清楚的是,我應該用一個包含從該偏移量開始的所有數據的數組作為響應。

所以我首先准備一個包含所有數據的數組。 如果請求的偏移量超出了數據的長度,我只返回一個0字節的數組。

如果不是這樣,那么我將從回調請求的偏移量開始准備原始數組的一部分,直到獲得一些信息為止。 因此,如果數組包含大量信息,則不重要,在第二,第三次回調中,我知道從哪里開始返回數據。

抱歉,如果不清楚,但是啟用日志記錄,您將了解我的意思。

祝大家好運

希望您仍然參與其中,因為我沒有在網上找到任何答案,只能自己“挖土”。

因此,我將嘗試將其分解:

假設我們已經在兩個android BLE設備(中央和外圍設備)之間建立了連接,

  1. 當BLE中央設備發出針對給定特性的characterRead(...)請求時,將以相關特性作為參數在外圍設備中調用onReadCharacteristic(...)回調。 正確的方法是發出sendResponse(...)方法,將值作為中心讀取的有用值(外圍設備實際要回答的內容)。 因此,正如我所見,您對這種方法非常正確,一切都很好。

  2. Give鏈接的MTU大小是默認值-20個字節。(實際上為23個字節,但對於GATT協議,我們需要3個字節)。因此,任何大於20個字節的緩沖區都將被android拆分為塊(碎片)。 您在這里有幾種選擇:

    2.1。 了解如何使用給定的android機制工作,並根據偏移量發送相應的代碼塊。

    2.2。 使用來自中央的requestMtu(...)API更改鏈接的MTU大小,以便它可以支持更大的消息。

    2.3。 知道鏈接的MTU,並自己建立分段機制(每次調用都會使偏移量始終為0)。

綜上所述,android具有您不知道的碎片化機制。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM