write的问题

公告

大中华汽车电子生态圈社区并入开发者社区- 更多资讯点击此

Tip / 登入 to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
YaTr_3516311
Level 5
Level 5
25 sign-ins First solution authored 100 replies posted

Hi,

pastedImage_0.png

在测试write的命令的时候,我发现有时候会没有GATT event过来。

1. 根据文档说不需要重送,那么这个event最终会过来吗?有没有timeout的时间?

2. 在多链接的情况下,如果第一个connection的write的event没有过来,第二个connection的write不能发送?

0 点赞
1 解答
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

Hi,

写在开始前:

log如果可以配上注释,方便我这边阅读的话,我会非常感谢。

log能提供原文档和抓取环境的话,我也会非常感谢。

您遇到的真实情况应该是,对端设备在您发送Write之前它已经主动发起了disconnect操作,只是到达时存在延迟,然后您log的打印存在先后失序而导致的。亦即,您的write请求其实完全没有效果,对应于write的log只是应用层方面对发起意愿的粗略记录而已,实际上它没能被真实执行并被对端设备接受。您会看到这样的log,是因为您的log并非完全是协议栈的trace,它不严谨地部分混合了应用层的console记录,故给您造成了“发起write后却直接遇到了disconnect”的假象。而这样的日志并不能真实反映协议栈实际执行时序。您应该优先只分析蓝牙协议栈的完整trace,并且己方设备和对端设备的trace一起对比分析最好。

具体分析起来,站在对端设备的立场来看,它早在您发起write请求之前就已经主动发起了disconnect,所以它并不会响应您的write请求,即使该请求有传递过来也会被丢弃。并且对端设备因为根本上没有响应您的write请求,所以也就不会向您发送write response。

其实问题处理也没有那么复杂,摆在己方设备面前的无非就两条路:第一,如果自己认为自己发送并执行了write,那它就只能在忍耐限度内无条件等待下去,然后在超出忍耐限度后当异常处理,而这一般而言就是强制终止连接。第二,收到disconnect请求的event后,根据disconnect的处理流程,它也只能无条件地立即抛弃所有任务,进入disconnect的流程并终止连接。所以无论是选项一还是选项二,如无意外您最后都需要强制终止连接,故问题实际上还是很好处理的。

不管怎样,这种情况的确属于异常情况。而异常情况都需要您这边自行调查并解决,论坛这边很难对此提供支持。或者,您可以联系销售代表或FAE,来更好帮您解决问题。

<<<<<<<<<<<<<>>>>>>>>>>>>>

Sincere regards from​ C. L.

<<<<<<<<<<<<<>>>>>>>>>>>>>

在原帖中查看解决方案

0 点赞
7 回复数
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

Hi,

  1. GATT event没有timeout,是最终会过来的。在L2CAP、LL或者PL层或许有timeout机制,会自动触发对端设备对该event数据包的超时重传,但都是在下层内部自动处理的,在GATT层不会有表示。Write Complete event对GATT操作的原子性而言是必不可缺的,其类似于ACK机制。若没有过来,说明对端设备正在处理中,或已经出现异常。
    除非你使用的是WriteWithoutResponse的GATT命令,该命令不会要求对端GATT Server返回RSP。详情请参见:
    https://iotexpert.com/2019/01/02/ble-write-request-write-command-signed-write-command-prepare-write/
  2. GATT event只针对单链接(即单实例)的情况。在多链接下,每个connection分别遵循文档原则即可。

<<<<<<<<<<<<<>>>>>>>>>>>>>

Sincere regards from​ C. L.

<<<<<<<<<<<<<>>>>>>>>>>>>>

0 点赞

1. 最终会过来,那么是多久会过来?总有一个时间吧

2. 我的理解是  第二个链接还是可以write的(在第一个write event没有过来的情况下)?

0 点赞
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

Hi,

  1. 没有多久会过来的概念,它就是没有timeout的时间值。如果你等不到,说明通信有问题了,或者对端设备异常了,或者自己设备的协议栈崩溃了……反正超出了你的程序设计的忍耐上限您都应该当成异常处理(无论您程序的忍耐时长有多短),当成异常处理的意思是这里没有标准化的处理流程,敬请improvise;如果不着急,忍耐时值超高,那等到地老天荒海枯石烂沧海桑田敢叫日月换新天,也不是不可以的。
  2. 你的理解是没问题的。两个链接(实例)之间没有锁关系。

<<<<<<<<<<<<<>>>>>>>>>>>>>

Sincere regards from​ C. L.

<<<<<<<<<<<<<>>>>>>>>>>>>>

0 点赞

1. 1)那么在这种情况下,只能重启蓝牙模块才可以恢复,对吧?disconnect可以回复吗?

2)如果在发了write的命令,没有Write Complete event的这段时间里,过来了disconnect的event,那么是不是Write Complete event就不会过来了?这个算是正常的流程吗?在这种情况下,disconnect消息过来后,能继续发送write的命令?

0 点赞
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

Hi,

  1. 重启蓝牙模块或许可以恢复,但如果程序设计有问题,那稍后再次进入这样的write流程时也可能会再次遇到这个问题,故重启也不一定能恢复。
    disconnect或许可以恢复,这类似于重启。但如果对端的协议栈已经宕机,发送disconnect命令给它它是不会响应的,它只会一直宕机下去,所以您下次让己方设备再连接它并不会成功,也就不能继续发送write;如果是己方的协议栈宕机,那你可能从根本上就不能执行disconnect流程,恢复无从谈起,只能重启或重置。故disconnect也不一定能恢复。
  2. 您如果没有发送disconnect命令但收到了disconnect的event,这可能是对端在主动发起disconnect操作。
    对端设备虽然可以随时发起disconnect,但协议栈对事件的处理都是FIFO的,所以即使对端设备试图在正在处理GATT Write的过程中便disconnect,那也是要等到Write Response执行了以后disconnect的请求才会被响应的。GATT Write的原子性不会被disconnect打断。所以一般而言,发起write以后,您很难会在等待Write Complete event的过程中先等来disconnect的event的,极限的情况也只会是等来Write Complete event后立马下一个event就是disconnect的event
    这就是为什么规范都只会要求发送write以后就只是等待Write Complete event。
    所以如果您实在遇到了这种假想的情况,那请唤之“异常”。

<<<<<<<<<<<<<>>>>>>>>>>>>>

Sincere regards from​ C. L.

<<<<<<<<<<<<<>>>>>>>>>>>>>

0 点赞

关于第二点,一般情况是Write Complete event后立马下一个event就是disconnect的event

我是抓到了这样的log(发送write的命令,然后disconnect过来了,没有看到write complete event),所以提出的问题

pastedImage_0.png

这种异常情况不知道是怎么产生的,如下是我们这边的流程

1. scan

2. scan到设备后connect

3. connect up后会设置mtu

4. mtu设置好后,开始发送write的命令

0 点赞
Charles_Lai
Moderator
Moderator
Moderator
500 replies posted 250 solutions authored 250 sign-ins

Hi,

写在开始前:

log如果可以配上注释,方便我这边阅读的话,我会非常感谢。

log能提供原文档和抓取环境的话,我也会非常感谢。

您遇到的真实情况应该是,对端设备在您发送Write之前它已经主动发起了disconnect操作,只是到达时存在延迟,然后您log的打印存在先后失序而导致的。亦即,您的write请求其实完全没有效果,对应于write的log只是应用层方面对发起意愿的粗略记录而已,实际上它没能被真实执行并被对端设备接受。您会看到这样的log,是因为您的log并非完全是协议栈的trace,它不严谨地部分混合了应用层的console记录,故给您造成了“发起write后却直接遇到了disconnect”的假象。而这样的日志并不能真实反映协议栈实际执行时序。您应该优先只分析蓝牙协议栈的完整trace,并且己方设备和对端设备的trace一起对比分析最好。

具体分析起来,站在对端设备的立场来看,它早在您发起write请求之前就已经主动发起了disconnect,所以它并不会响应您的write请求,即使该请求有传递过来也会被丢弃。并且对端设备因为根本上没有响应您的write请求,所以也就不会向您发送write response。

其实问题处理也没有那么复杂,摆在己方设备面前的无非就两条路:第一,如果自己认为自己发送并执行了write,那它就只能在忍耐限度内无条件等待下去,然后在超出忍耐限度后当异常处理,而这一般而言就是强制终止连接。第二,收到disconnect请求的event后,根据disconnect的处理流程,它也只能无条件地立即抛弃所有任务,进入disconnect的流程并终止连接。所以无论是选项一还是选项二,如无意外您最后都需要强制终止连接,故问题实际上还是很好处理的。

不管怎样,这种情况的确属于异常情况。而异常情况都需要您这边自行调查并解决,论坛这边很难对此提供支持。或者,您可以联系销售代表或FAE,来更好帮您解决问题。

<<<<<<<<<<<<<>>>>>>>>>>>>>

Sincere regards from​ C. L.

<<<<<<<<<<<<<>>>>>>>>>>>>>

0 点赞