问题背景:

根据applications_sample_iot_connect_samples/wifi_ble_combo/hi3863/README.md · ohos-oneconnect/applications_sample_iot_connect_samples - AtomGit文档,在OH master底座上配置wifi/ble combo配网功能demo,编译hi3863遇到配网失败问题。

 

定位过程&根因分析:

初步分析日志,是状态机卡在了阶段4。

阶段3->4是在配网阶段,设备侧向云端发送了认证消息,云端返回响应。但在日志中,设备侧没有收到云端返回的响应,导致超时,应用发出了断连,重新开始发出蓝牙广播。

目前从三个方面去排查问题。首先怀疑是否是设备侧发送到云端的消息有问题,二是云端收到了消息但没有向设备侧发送响应消息,三是云端发出了响应消息但是设备侧没有收到。

在发送函数中增加日志,打印发送的数据长度。重新抓取日志,发现设备侧确实是成功向云端发送了两条数据。

 

那么需要去排查第二点,是否是因为云端收到了消息但没有向设备侧发送响应消息。去排查了云端日志,云端流程是正常的,云端发给coap服务了,然后查看了云端coap服务的代码和日志,确定coap是向设备发出去了响应了。

 

那么问题应该就是出现在第三个方面了,云端发出了响应消息但是设备侧没有收到。

设备侧没有收到,先排查下是否是硬件问题,但是hi3863又没有办法抓tcpdump数据包。于是协调了两三块板子,都烧录镜像试了一下,都没有收到云端发来的响应,那么问题就是出现在代码流程上。

于是在foundation/communication/iot_connect/core/wifi/infrastructure/transport/socket/trans_socket_tcp.c文件中接收消息的函数中增加日志打印,抓取日志,一条打印都没有,那么继续往下追代码。

在调用底层代码的位置添加日志,抓取的日志中还是没有任何相关打印。

值得注意的是,我们设备侧的消息是能够成功发送到云端的,说明设备侧与云端的socket连接可能是成功建立了的,发送数据是并且在日志中也能看到,通过fd = 256这个套接字去发送的。

get addinfo connect.harmonytsc.com

IC_INFO:trans_link.c:118, link[CLOUD_TCP] connect ok

IC_DEBUG:event_source_fd.c:289, watch fd 256/1

IC_DEBUG:coap_endpoint_client.c:251, endpoint client send CSM packet

@lfq@ [TCP DEBUG] TcpSocketSend: fd=256, data->len=7, tmo=10000

@lfq@ [LWIP] lwip_send: fd=256, netconn_write_partly err=0, written=7

查看代码,也是通过调用IotcSelect监听fd=256这个套接字去判断是否有数据包过来。

在此函数中我也添加了日志。

@lfq@ [LWIP] IotcSelect: maxFd=256, readSet=0xa58614, ms=1

@lfq@ [LWIP] IotcSelect: lwip_select returned -1, errno=9

根据错误码,errno=9代表EBADF 无效文件描述符(fd 已关闭 / 不存在)。就是说这个fd在send出消息后就失效了,但是按理说也没有其他进程或线程来关闭socket,这个fd不应该失效啊。继续追代码,调用了select去监听fd,这个函数最终调用到的是ws63v100 的sdk中的lwip中去了,那么问题就是出现在ws63v100中。

但是我找到了lwip_select函数,但是在其中添加的函数并没有日志打印,说明都没有调用到这里来,那么回到foundation/communication/iot_connect/adapter/socket/iotc_socket.c文件中查看调用select的位置,怀疑在这里调用的select函数是系统函数,而send调用的是lwip实现的lwip_send,所以调用的函数根本就不对。那么在这里,修改为

int32_t ret = lwip_select(maxFd + 1, (readSet == NULL) ? NULL : &read,

        (writeSet == NULL) ? NULL : &write,

        (exceptSet == NULL) ? NULL : &except, &timeout);

但是修改后,发现还是收不到消息。继续查看lwip_select的实现和声明,

最终发现在device/soc/hisilicon/ws63v100/sdk/open_source/lwip/lwip_v2.1.3/src/include/lwip/sockets.h文件中,将lwip_select又重定向到了系统select函数而不是lwip自身实现的函数了。

 

解决方案:

问题找到了,那么直接修改然后验证。

在device/soc/hisilicon/ws63v100/sdk/open_source/lwip/lwip_v2.1.3/src/include/lwip/sockets.h文件中,注释调lwip_select的重定向。

并且在foundation/communication/iot_connect/adapter/socket/iotc_socket.c文件的IotcSelect函数中,修改调用select为lwip_select。

编译镜像去验证wifiblecombo功能,配网成功。

 

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐