一台设备已经连上 Wi-Fi,配置器也收到了“入网成功”,为什么本地中枢里仍然看不到它?

在 BLE+Wi-Fi Combo 终端上,这个现象并不矛盾。BLE 负责把设备带入网络,Wi-Fi 提供网络连通性,终端还要找到正确的中枢、完成安全认证、激活和状态同步,才能真正进入业务在线状态。排查这类问题,关键是看清每一步交给下一步的是什么,以及下一步有没有接住。

本文以 OpenHarmony 统一互联 3.0 的 iot_connect 工程为例,结合 WS63 应用终端、DAYU200 配置器和 Hi3516CV610 本地中枢的联调,完整说明从配网到 DTLS 保活的实现。重点放在连接过程、代码职责和可复核的运行证据。

一、先认识三个参与方

本文场景中,配置器是设备首次接入系统的入口,应用终端是被管理的设备,Hub 是局域网内的本地中枢。

参与方本次使用的设备在接入过程中的职责
配置器DAYU200通过 BLE 完成近端配置,向终端下发接入资料,并向 Hub 同步终端管理资料
应用终端WS63 BLE+Wi-Fi Combo保存配置、接入 Wi-Fi、发现 Hub,作为 DTLS Client 建立会话并上报设备状态
本地中枢Hi3516CV610 Hub提供发现和安全接入服务,作为 DTLS Server 验证终端、处理激活与后续业务

这三种硬件是本次实现的载体。换成其他产品后,网络驱动和板级适配可能改变,但角色之间的职责仍然成立。

img


图 1:三方关系。 BLE 配置链路、配置器到 Hub 的管理链路、终端到 Hub 的 DTLS 链路各有自己的会话和状态。

BLE、Wi-Fi 和“在线”分别解决什么

在本文的 Combo 接入方式中,BLE 为首次配置提供近端入口。设备尚不知道 Wi-Fi 参数时,配置器仍能通过 GATT 与它通信,完成安全协商和配置下发。配置完成后,终端的中枢业务由 Wi-Fi 上的安全会话承载。

因此,需要分别确认三个结果:

  • BLE 可通信:配置器能够向终端发送配置请求,终端能够响应。
  • Wi-Fi 已入网:终端已经获得可用的局域网连接。
  • 业务已在线:Hub 已接受终端激活,并完成设备信息和首次状态同步。

这一区分直接决定排障方向。Wi-Fi 已连上但 Hub 不显示设备时,应继续检查发现、安全会话和业务响应;重新检查 BLE 广播往往已经离故障点太远。

二、配网阶段真正交付的是一组接入条件

配网不只是在终端里写入 SSID 和密码。后续连接中枢还依赖管理域、中枢相关配置以及管理员预共享密钥(PSK)。与此同时,Hub 也需要取得该终端的接入资料,才能识别它发起的安全会话。

下面的时序展示主要依赖关系。配置器向 Hub 同步资料与终端 Wi-Fi 入网可能由不同事件驱动;图中顺序用于说明成功接入所需的条件,不要求两条链路严格串行。

img


图 2:配置阶段为终端和 Hub 准备同一条安全链路所需的条件。

这里要区分两类密钥使用场景。配置器与终端之间的 SPEKE 配置会话,保护近端配置交互;终端与 Hub 之间的 DTLS 会话,使用管理员 PSK 建立运行期安全通信。本文 Combo 流程不需要先经过 BLE-only 业务中的 createPskSession 才能建立 DTLS。

identity 和 PSK 必须成对核对

PSK identity 用于让 Hub 找到对应的凭据记录,PSK 则参与安全认证。当前 Application Terminal 从安全配置中选择管理员 PSK,并以其 pskId 作为 identity。对应代码位于:

  • core/network/app_terminal/net_app_terminal_credential.c:读取、校验和选择管理员凭据。
  • core/network/app_terminal/net_app_terminal_session.c:将凭据与发现结果组装成建链参数。

NetAppTerminalLoadAdminCredential() 会区分管理员、管理和操作等 PSK 类型,选择管理员记录;遇到内容不同的多个管理员记录时按配置冲突处理。这个设计使“使用哪一把密钥”有确定答案,也避免随机取列表第一项带来的不稳定行为。

联调时要把同一设备的配置器记录、终端凭据选择和 Hub 查找结果对应起来。只看到终端写入成功,还不能证明 Hub 已经准备好同一组凭据。日志中保留一致的匿名设备标签、PSK 类型和查找结果即可,无需输出密钥内容。

三、发现 Hub:找到候选,再把它交给业务层

Wi-Fi 可用后,LAN Search 负责寻找本地中枢。当前实现既处理主动搜索的响应,也处理 /hub/syncAccessInfo 携带的接入信息。两条路径最终汇入 NetLanSearchProcessHubAccessInfo()。

发现信息至少要回答三件事:候选属于哪个管理域、服务地址和端口是什么、支持哪种安全传输。LAN Search 对信息做解析和基本校验;Application Terminal 再检查候选能力是否匹配当前镜像选中的 TLS 或 DTLS 后端。

img

图 3:发现交付与后续建链的关系。 上层接收发现结果,表示它接受并安排了后续动作;安全会话尚需单独建立。

为什么停止搜索的时机很重要

如果先停止搜索,再调用上层,而上层恰好未初始化或无法创建动作定时器,这条候选结果就没有后续处理者。当前实现先调用 NetAppTerminalOnHubDiscovered(),成功后保存结果并停止搜索;交付或保存失败时继续搜索,必要时重新启动搜索定时器。

这几步保证的是后续仍有交付机会。上层已经接受结果而本地保存失败时,上层动作可能已经被安排,跨模块状态并不是一个可原子回滚的事务。因此,Application Terminal 还要识别同一中枢的重复发现,避免重复建立会话。

域匹配与安全认证各有职责

域和能力校验用于筛选候选。它们不能替代 PSK 认证:收到一个格式正确、域匹配的发现报文,不足以证明发报方持有合法密钥。只有下一阶段的安全握手才能检验这一点。

代码阅读可从 core/network/lan_search/net_lan_search_coap_api.c 开始,依次跟踪 NetLanSearchProcessHubAccessInfo() 和 NetAppTerminalOnHubDiscovered(),最后进入 NetAppTerminalSessionOpen()。

四、建立 DTLS 会话,把“找到地址”变成“可以安全收发”

本文 WS63 镜像选用 DTLS/UDP。Application Terminal 在建链前检查当前状态、候选端口和 DTLS 能力位,随后加载管理员凭据,调用 NetSecureChannelOpen()。

Secure Channel 负责组织 Socket、Link、Session 和 CoAP Endpoint,启动连接,并接入接收监听和协议事件处理。成功后,Application Terminal 使用该 Endpoint 发起激活请求。凭据临时副本在被底层消费后清理;建链任何一步失败,都应释放已创建资源。

这条链路还依赖构建配置。GN 中的 iot_connect_mbedtls_psk_support 控制适配层的 PSK 支持;如果关闭,设置 PSK 的调用就可能返回“不支持”。这类失败发生在终端本地,排查时不能直接归因于 Hub 拒绝了密钥。

下面是三类常见观察结果及其含义:

观察结果可以得出的结论下一步检查
发现响应解析成功已得到候选 Hub上层是否接受、能力位是否匹配
Hub 的 PSK 查找命中Hub 找到了 identity 对应记录握手是否完成,密钥与套件是否匹配
DTLS 握手完成安全会话已建立激活及后续业务响应是否成功

安全会话和业务请求是不同的层次

DTLS 负责安全传输;CoAP 负责请求、响应及 UDP 场景下的报文可靠性;Application Terminal 负责业务结果和状态迁移。CoAP 的 CON 消息可以获得确认并按规则重传,但空 ACK 只确认报文接收,业务响应可能稍后到达。协议层反馈仍需结合业务结果判断。RFC 7252,第 4.2 节与第 5.2 节

实际观察时应同时保留“发送结果、响应内容、业务解析结果”,才能区分未发出、未响应和业务拒绝。

五、为什么首次上报完成才进入 ONLINE

握手之后,当前业务主线有三个连续步骤:

请求作用成功后的状态推进
POST /hub/activate完成终端在 Hub 上的业务激活ACTIVATING → ACTIVATED → SYNCING_INFO
POST /hub/syncDevInfo同步终端设备信息SYNCING_INFO → SYNCING_SERVICES
POST /dataReport首次上报设备当前状态SYNCING_SERVICES → ONLINE
POST /hub/heartbeat在线后的周期保活成功时清零心跳失败计数

其中 /dataReport 没有 /hub 前缀。URI 来自当前工程的请求构造实现,移植时应与对端协议共同核对。

首次全量上报成功才进入 ONLINE,是一个有用的业务判据:此时不仅能连上 Hub,设备信息和初始状态也已经完成同步。若只在握手成功时就宣布在线,上层可能立即显示一台缺少设备模型或状态的终端。

img


图 4:业务上线过程。 图中同步和上报同样经过 CoAP 与安全会话,为突出业务阶段省略了中间转发箭头。

从真实日志看状态推进

以下内容摘自终端正常联调记录,省略日志前缀、源码行号和无关记录,保留原始状态与操作结果文本:

app terminal state 3->4 reason=0
app terminal state 4->5 reason=0
app terminal state 5->6 reason=0
app terminal state 6->7 reason=0
app terminal state 7->8 reason=0
app terminal state 8->9 reason=0
app terminal runtime op=1 category=0
app terminal state 9->10 reason=0
app terminal runtime op=2 category=0
app terminal state 10->11 reason=0
app terminal runtime op=3 category=0
app terminal runtime op=3 category=0

在该版本的枚举中,3~11 依次对应 DISCOVERING_HUB、DISCOVERED、PREPARING、CONNECTING、ACTIVATING、ACTIVATED、SYNCING_INFO、SYNCING_SERVICES、ONLINE。op=1/2/3 分别表示设备信息同步、数据上报和心跳,category=0 表示本次操作成功。

真正有判别力的是 op=2 category=0 之后出现 10->11,并且后续多次 op=3 category=0。前者说明初始状态同步已经完成,后者说明进入在线态后保活仍在运行。状态数字属于实现细节,换版本阅读日志时应以 net_app_terminal.h 中的枚举为准。

为什么响应回调与状态变化不一定紧挨着

当前实现会复制有限长度的响应快照,再由业务调度处理结果。网络回调传入的 Payload 有自己的生命周期;如果回调结束后仍保留原始指针,后续解析可能访问无效内存。复制快照既让数据生命周期明确,也为在合适的调度边界执行重连、释放会话等操作提供条件。

因此,“收到响应”的日志与“进入下一状态”的日志可能隔着其他调度事件。判断时应关联操作类型和业务结果,不能仅凭日志相邻关系推断调用顺序。

六、在线以后:一条会话承担上报与保活

当前实现以 30 秒为心跳定时器周期,心跳和在线状态上报复用同一条安全会话。若运行请求或其结果尚待处理,本次心跳回调会跳过发送,因此 30 秒是调度配置值,并不保证线上报文间隔始终精确为 30 秒。

状态变化也可能发生在请求等待期间。例如一笔心跳正在等待 Hub 响应,设备的开关属性此时发生改变。如果发送层暂时忙,就直接丢掉这次上报,Hub 会一直保留旧状态。

当前策略是在 runtimePending 或 runtimeResultPending 时设置 reportDirty。待请求结果消费完成后,再从设备模型读取最新状态,合并安排一次全量补报。

img


图 5:忙时保留补报意图,空闲后读取最新状态。

这种合并适合“最终状态”上报,例如开关、模式和目标值。若业务要求每一条事件都不能丢,例如计费流水或报警发生次数,则需要有序事件队列、序号和确认机制,不能直接套用一个 dirty 标志。

心跳失败则需要另一类处理。当前实现以 3 次心跳失败为本地阈值,可重试通信故障达到阈值时关闭旧会话,进入重连流程;失败状态也允许同一 Hub 的新发现再次触发接入。重试间隔和上限是工程策略,产品可以根据网络和功耗要求调整。正常心跳日志验证的是在线路径,异常恢复仍应通过独立的超时和断网测试验证。

七、如何把一次成功接入变成可复核的结论

三端联调容易出现“各自都有成功日志,拼起来却不是同一台设备”的问题。建议把同一设备、同一轮配置作为观察单元,并分别在三端找证据。

验证阶段终端侧观察对端侧观察
配置完成管理员凭据与网络配置处理成功配置器收到对应请求结果
网络接入Wi-Fi 可用,触发在线通知配置器看到该终端的通知
中枢发现候选校验、交付成功Hub 收到搜索或发出接入信息
DTLS 建链连接成功,进入激活阶段Hub 识别该终端并完成握手
业务上线激活、同步、首次上报成功Hub 处理对应业务请求
运行保活连续多轮心跳成功Hub 收到对应心跳并响应

三端时钟未同步时,优先通过匿名设备标签、操作类型和请求响应关系对齐。本文所用 Hub 日志的日期与终端不一致,不能用绝对时间直接计算跨设备延迟。

本次三端记录支持的结论是:在所测 WS63 Combo 与 Hub 配置下,BLE 配置、Wi-Fi 接入、发现、DTLS、激活、同步、首次上报和连续心跳形成了完整正常链路。TLS 真机、重启后的凭据恢复、长期稳定性和异常恢复需要各自的验证记录。

遇到问题,从最后一个成功阶段继续查

现象优先检查
Wi-Fi 已入网,但没有开始安全连接搜索收发、管理域、能力位、发现交付与动作定时器
找到 Hub,但 PSK 设置失败PSK 构建开关、管理员凭据类型与参数合法性
Hub 找不到 identity配置器到 Hub 的资料同步及两端凭据关联
握手成功,但未进入 ONLINE激活、同步、首次上报分别停在哪一步
ONLINE 但状态不更新请求 pending、结果 pending、dirty 补报是否被消费
短暂在线后不再有心跳定时器、当前请求占用、失败计数及会话恢复

八、沿代码继续阅读

以下路径均相对于 foundation/communication/iot_connect/:

文件建议关注的内容
core/network/lan_search/net_lan_search_coap_api.c候选发现解析、上层交付和搜索停止条件
core/network/app_terminal/net_app_terminal_credential.c管理员 PSK 的选择和临时凭据清理
core/network/app_terminal/net_app_terminal_session.c能力检查、建链参数、会话关闭
core/network/app_terminal/net_app_terminal_coap.cURI、请求构造、响应回调和 pending 标志
core/network/app_terminal/net_app_terminal_payload.c业务 Payload 构造与响应解析
core/network/app_terminal/net_app_terminal_svc.c上线状态推进、补报、心跳与重试
core/network/transport/secure_channel/TLS/DTLS 后端与公共安全会话管理

接入链路稳定的基础,是每个阶段都有明确的输入、完成条件和失败后的处理者。按这条顺序读代码、组织日志,设备“已经配网却没有在线”的问题就能逐步缩小到具体的模块和状态。

本文涉及的传输分层与资源取舍,可继续阅读《让 TLS 与 DTLS 共用业务逻辑:Secure Channel 分层设计》。

Logo

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

更多推荐