在我们的自定义配置文件中,我们有一个由客户端/中心设备在空中编写的特征。这个特征在user_custs1_def.h中定义为CHAR_LEN为254(这是它应该达到的最大大小)。在测试中,我们发现只要新的写入值在长度上等于或小于之前的写入值,那么一切都可以正常工作。但是,如果新值比先前写入的值长(即使新值仍然比初始的CHAR_LEN 254短得多),写入就会失败,系统的行为开始变得不稳定。例如,对该特性进行较长时间的写入后,该特性就不能通过空中读取,与客户机的连接变得不稳定。
在编写较长的字符串的情况下,custs1_task.c中的gattc_write_req_ind_handler()函数从未被调用,因此问题发生在代码的这一点之前。
我们怎样才能实现所需的功能?即,可以从客户端的任何值(最多254个字节)一个可写的特性,而不管该特征的当前内容?
设备:

嗨mkelwood,
似乎写一个比之前写的价值更大的特征值,不是问题,我不能复制它。在DSPS中,你可以有你想要的功能,所以请检查这些特性是如何在这个项目中实现的。
谢谢,PM_Dialog
你好PM_Dialog,
感谢您的答复。我有一些额外的信息。我对这个问题初步结论是不正确的;它是不是比导致问题以前写长写。相反,它是比(MTU - 3)长的写入字节,其中所需要的写入长特征值步骤(蓝牙规范5.0第3卷部分G部分4.9.4)。
我已经附上了OTA捕获文件显示问题的截图。DA14585为从设备(GATT服务器)。目标特征有处理53。在连接和发现之后,我向特征写入一个短值(长度小于MTU - 3),它成功了(参见帧4468和4473)。我读回了正确的值(帧6926和6932)。然后我尝试写一个21字节长的值(比MTU - 3多一个字节)。GATT客户端发送一个Prepare write Request(帧7334,突出显示的帧),没有来自DA14585的响应。奴隶现在是破碎的和无反应的。
我已经尝试将目标特征权限设置为WRITE_REQ和WRITE_COMMAND。附加的捕获具有WRITE_REQ权限。使用WRITE_COMMAND, GATT客户端不会让我写一个长值到特征(它抱怨坏参数)。
所以我现在的问题是,为什么写长特征值程序不工作?为什么DA14585不响应准备写响应?我是否需要做任何特殊的事情来支持从GATT服务器端准备写/执行写序列?
谢谢你的帮助!
我更新到SDK 6.0.10.511;这个问题与写长的特点值一直保持。设备无法从中央一个准备写请求做出响应,并且设备没有响应,直到断开/重新连接。
嗨mkelwood,
如果你不使用,或者你不想MTU交流,你应该实现写长的特点值作为SDK的ble_app_peripheral例子实施。请看看SDK的这个例子。如果要被写入的特性值的长度大于20个字节,则user_svc1_long_val_att_info_req_handler()在user_catch_rest_hndl()函数将被触发。如果长度小于20字节的user_svc1_long_val_wr_ind_handler()将被执行。所以,如果你想在不MTU交换发送超过20个字节,你应该做相同的实现作为ble_app_peripheral例子的user_svc1_long_val_att_info_req_handler()函数。因为你这样做,主机发送一个“准备写请求”,并用“准备写响应”从设备将响应。否则,如果你想要做一个简单的写请求和发送超过20个字节,则应该增加MTU大小。
谢谢,PM_Dialog
谢谢PM_Dialog提供的这些信息!我已经按照您的建议实现了att_info_req_handler代码,这解决了写长特征值的问题。wr_ind_handler在接收到EXECUTE WRITE命令后仍然被调用;这是预期和首选的行为。
我从来没有想到att_info_req_handler是编写长特征的代码。即使看到ble_app_peripheral应用程序中的代码,我也不会在这个和Prepare Write/Execute Write序列之间建立连接。我在Dialog或Riviera Waves的文档中都找不到这方面的文档。我希望有更好的文档关于这些更模糊的回调。
嗨mkelwood,
很高兴你想通您的问题了。
谢谢,PM_Dialog