首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >onCharacteristicWrite()正在被调用,但它并不总是编写

onCharacteristicWrite()正在被调用,但它并不总是编写
EN

Stack Overflow用户
提问于 2016-08-23 19:22:27
回答 1查看 7.5K关注 0票数 3

我有一个定制的硬件和蓝牙低能芯片。我用一个带有500个u32s的数组来设置它,比如arrayn == n。我正在开发一个安卓应用程序,它可以连接到设备上,请求数组的长度,然后一次请求数组中的数据点。

这款android应用程序似乎运行良好。它连接到设备,请求长度,并在收到上一段之后继续请求下一段数据。但是,通过数组的半程(从2到450个元素中的任何地方),它都会编写另一个命令,并且它会一直执行到onCharacteristicWrite(),但是它永远不会收到响应。我的BLE外围设备连接到CoolTerm,它甚至从未接收到这个命令。下面是我的代码和日志的片段:

BLEService:

代码语言:javascript
复制
 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的这一部分中被接收:

代码语言:javascript
复制
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的代码:

代码语言:javascript
复制
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);
}

我相当肯定,快速发送命令没有任何问题。它实际上非常慢,这是我故意做的,这样我就可以更容易地测试东西,然后再进入我的项目的下一部分。

来自我的调试日志之一的片段:

代码语言:javascript
复制
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日志片段:

代码语言:javascript
复制
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

注意,在我的外围日志中,它似乎没有接收到数据点53的请求。作为参考,onCharacteristicWrite调试中的第一个十六进制字节是命令。命令02只意味着我请求在接下来的2个字节包含的任何索引处设置一个数据池。

我注意到,在Android中,没有用于请求数据点51的onCharacteristicWrite日志。在每次停止获取数据之前,这种情况似乎都会发生,但我不确定这是否重要,还是只是日志缓冲区的问题。

我已经运行了相当多的测试试图注意到任何模式,并且我注意到当设备没有连接到调试电缆时,它似乎得到了更多的数据点。在这一点上,我唯一的想法是,也许我对异步中断回调有问题,但我不知道会做什么。有没有人想过为什么在调用onCharacteristicWrite之后,它似乎没有真正地编写数据呢?

谢谢

编辑:

我听从了Emil的建议,打开了蓝牙日志。我和wireshark一起玩,弄明白了到底发生了什么。我再次试用了我的应用程序,它一直运行到索引102,直到它停止运行,这时我断开了设备的连接。我在Wireshark中搜索了数据包,发现我的设备确实收到了大约102的数据,但它没有发送103的请求。我再次检查了我的android日志,onCharacteristicWrite内部的一条日志语句说它发送了命令02 67 00,这是对103的请求。因此,onCharacteristicWrite似乎正在被调用,但其特性并不是实际编写的。

经过更多的凝视和思考之后,我非常肯定,要么是onCharacteristicWrite被错误地调用了,因为数据从未被写入,要么是某种异步的东西正在中断它并阻止它传输。我不知道会怎么做。

最后编辑:

尽管据我从规范中了解到,只有在进行可靠、成功的写入时才会调用onCharacteristicWrite,但我还是决定检查writeCharacteristic的返回值。我几个小时前就该查过了。你知道吗,上次的请求是假的。

我认为,即使返回是假的,onCharacteristicWrite也被调用了,这是一个错误。我已经读到,使用onCharacteristicWrite调用来编写下一个数据块是安全的。要么他们错了,要么这里出了什么乱七八糟的事情。不管怎样,我想检查那些函数调用返回值是个不错的主意。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-24 18:18:59

现在我想我看到了。有时,通知会在onWriteCharacteristic回调之前到达。由于您在通知回调中发出下一个写,所以前面的写仍然挂起。您必须确保在发出下一次写入之前已经调用了onWriteCharacteristic。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39109178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档