视角:配置器(手机 App)日志 · 依据:配置器日志 + 中枢侧日志 + iotc 源码三方交叉核实

0 · 一句话概括

配网全程 11 步,两个平面:

BLE GATT 平面(步骤 1~8)
手机与设备通过蓝牙完成发现、建链、SPEKE 认证、PSK 下发、WiFi 凭证下发。步骤 3(SPEKE msg4)之后 payload 全程加密。

UDP / CoAP 平面(步骤 9~11)
设备拿到 IP 后不再走蓝牙,改为 UDP 广播上线通告,手机再与中枢做 HubSync 与设备管理信息同步。

介质切换点在步骤 8 → 9 之间:netCfg 100 是 BLE 平面最后一个事件,online_notify 是 UDP 平面第一个事件,二者由同一 CONNECTED / NET_CONNECT 事件平行驱动,无严格先后(实证:18:06:46.123 先收到 notify,.146 才报 100)。

1 · 总览表

步阶段名平面方向关键报文要点
1蓝牙广播扫描BLE设备 → 手机ADV(含 softApSsid)拿到设备标识与协议类型
2BLE 连接 / GATT 发现BLE双向GATT 15F1E600-…按 service-name 路由
3SPEKE 协商BLE双向msg1→msg2→msg3→msg4此后 payload 全程加密;对重传敏感
4deviceInfoBLE手机 → 设备prodId / udid / 协议版本决定后续协议分支
5getProvisionRequestBLE手机 → 设备pskAuth 参数取认证参数
6provisionPSKBLE手机 → 设备pskId + psk手机下发;先 PSK 后 WiFi
7hubCfgBLE手机 → 设备ssid / pwd / bssid / channel真实 WiFi 凭证下发
8netCfg 上报BLE设备 → 手机104 → 100100 是提前上报,非连通证明
9online_notifyUDP设备 → 手机255.255.255.255:5683非请求广播;真正的入网判据
10HubSyncUDP手机 → 中枢SEARCH → DTLS 5670三段式,使能本地中枢
11synvDevManageInfoUDP手机 → 中枢POST /hub/synvDevManageInfo同步设备管理信息

2 · BLE GATT 平面(步骤 1~8)

此后 payload 加密手机(配置器)设备1. ADV 广播(含 softApSsid)2. BLE 连接 · GATT 15F1E6003. SPEKE msg1→msg4(X25519)4. deviceInfo:prodId/udid/协议版本5. getProvisionRequest:pskAuth 参数6. provisionPSK:pskId+psk7. hubCfg:ssid/pwd/bssid/channel8. netCfg 上报:104→100

BLE GATT 平面:步骤 1~8,SPEKE 握手完成后进入加密区

步骤 1 · 蓝牙广播扫描

方向设备 → 手机(广播)
关键字段softApSsid、prodId、protocol、udid
日志关键词CoapDeviceScanManager、diag scanItem prodId=... protocol=... udid=...
易错点配置器侧 stopScanDevice 不等 binder 完成就 startScan → BLE binder busy → 等 60s → superseded 死循环,扫描根本起不来

步骤 2 · BLE 连接 + GATT 服务发现

方向双向
服务 UUID15F1E600-A277-43FC-A484-DD39EF8A9100
路由方式按 service-name 分发(g_svcInfoTab),不走 ServiceProxy
后续订阅配网特征值(CCCD 写 0x0001),进入 SPEKE

步骤 3 · SPEKE 协商(最脆弱的一步)

方向双向,四步 msg1 → msg2 → msg3 → msg4
算法SPEKE/v2,X25519;iterations 为关键参数
完成标志PakeTask: verifyProof 命中 → PakeTaskStatus 65535(终态);正常路径 32769 → 32770 → 65535
此后所有 payload 加密,日志只剩 cmdType 与长度

实证过的失败模式:重传定时器竞态

  1. 设备侧 iterations=10000 时 msg1→msg2 耗时 1561ms(1000 时为 143ms)
  2. 手机侧 PAKE 重传定时器 1500ms → msg1 被重传 → 设备对两条各回一条 msg2(逐字节相同)
  3. 手机状态机被重入两次 sendClientConfirm → 两个不一致的 kcfData2 → 设备拒第一条:{"errCode":-196548}
  4. -196548 = IOTC_CORE_COMM_SEC_ERR_SPEKE_VERIFY_HMAC(module=3,base -196608,index 60)
  5. 手机已推进到终态 65535,spekeMsg4 被当作 insignificant passThrough data 丢弃 → 12.6s 超时 → speke fail.
  6. 源码:security_speke_nego_ctx.c:357-374(NegoContextVerifyHmac)、security_speke_server.c:99
  7. 判据差异:走 CoAP 传输时 libcoap 按 token/MID 天然去重,同样 iterations=10000 也能成功;走 BLE GATT 无去重,重传必然重复回调
  8. 修复方向:iterations 回退 1000;重传超时 ≥3000ms;sendClientConfirm 按 sessionId+msgId 幂等

步骤 4 · deviceInfo

方向手机 → 设备(加密)
取回字段prodId / udid / deviceModel / scannedProtocol / protocolVersion
说明常被忽略,但它是后面选择协议分支(BLE 协议 / softap 协议)的依据
补充事实queryDeviceInfo 回包里没有 devId,devId 由手机侧生成并在步骤 7 下发;每轮 devId 不同属正常

步骤 5 · getProvisionRequest

方向手机 → 设备(加密)
请求payloadLength = 266
回包{"code":0,"version":"2.0","cipherSuite":1,"pskAuth":{sessionId,vid,pid,pskId,...}}
日志关键词deviceAuth success、pskAuth

步骤 6 · provisionPSK

方向手机下发给设备(不是设备回给手机)
报文{"domainId","pskId":"4225","psk":"97F7E8...","valid":...}
设备回包{"code":0},共 10 字节
时机先 PSK,后 WiFi 配置(步骤 6 在步骤 7 之前)
陷阱:两套 PSK 体系不能混为一谈。
provisionPSK 下发的是配网用 PSK;DTLS initLocalHub 用的是另一把(来自 ConfiguratorCredentialStore,identity A)。排查时以 pskId 来源区分。

步骤 7 · hubCfg

方向手机 → 设备(加密)
字段ssid / password / bssid / channel / devId / code
日志关键词hubConfig success
注意设备侧 CopyWifiResultFromOhos 只比 SSID + 加密类型,不比 bssid;IsWifiConnectedToTarget 也只比 ssid。bssid 下发错了不会阻塞连接

步骤 8 · netCfg 上报 104 → 100

方向设备 → 手机(加密)
状态码104 = connecting,100 = IOTC_CORE_WIFI_EVENT_CONNECTED
陷阱100 不等于拿到 IP:svc_conn_action.c:78-101 在 IotcConnectWifi() 返回后立刻 publish CONNECTED。实证假阳性:104→100 只隔 8ms(正常轮次 3.9~5.1s)
触发链wifi_service_adapter.c:32/44(.eventNetConnect)→ ble_svc_netcfg_status.c:104-108:报 100 时主动补发一次 IOTC_SDK_AILIFE_EVENT_WIFI_NET_CONNECT → 驱动 lan_search 起 coap → 发 online_notify
真正判据连通性判定在 60s WIFI_VERIFY_CONNECT_TIMEOUT_MS 里,失败才发 102

3 · UDP / CoAP 平面(步骤 9~11)

设备手机(配置器)中枢9. online_notify 广播255.255.255.255:5683 · 非请求广播 · 配置器 waitOnline 判据10. HubSync:SEARCH → DTLS 5670HUB_SEARCH 组播 → HUB_IDENTITY → initLocalHub(DTLS)11. POST /hub/synvDevManageInfoDTLS CoAP · 依赖步骤 10 成功

UDP / CoAP 平面:步骤 9~11,蓝牙不再参与

步骤 9 · online_notify

方向设备 → 手机,受限广播 255.255.255.255:5683 → 手机 0.0.0.0:5683
性质非请求主动上报(不是某个请求的响应)
源码net_lan_search_coap_api.c:124-215,SEND_COUNT=5、INTERVAL=1s
双受众①配置器:waitOnline 60s 窗口,onlinenotifyRx=1 → onlineJudge → result=true,这是 App 判定"配网成功"的端到端证据;②中枢:同一广播发现新设备,驱动后续 HubSync

4 个静默跳过点(命中即"零发包",日志里什么都看不到)

  1. net_lan_search_coap_api.c:88-93:ConfigGetDevId 失败/空 → 只打 online notify devId invalid
  2. net_lan_search_svc.c:77-79:!enableOnlineNotify → 直接 return,无任何日志
  3. NetLanSearchCoapStackStart 失败 → start lan search coap server error %d
  4. 5 次发送全落在"还没拿到 IP"的窗口 → send onlinenotify error %d

工程实践建议(基于实测)

  1. 100 的上报应以"真实连通"为门控(目标 SSID 已关联 + IP 已就绪)后再发一次,而不是在连接 API 返回时立刻发
  2. online_notify 发送前先判本地 IP 非 0.0.0.0,未就绪不消耗重发次数
  3. 重发策略改为"先快后慢"(如 5×1s 快发后降频 5s,总时长覆盖配置器 60s 等待窗口)
  4. 同时发受限广播 255.255.255.255 与子网定向广播,避免只依赖一种

步骤 10 · HubSync

三段式:

  1. HUB_SEARCH:组播 239.255.71.2:5685,5 次 × 3s,超时 → {"found":false}(带 preferHash 仍会继续走下一步)
  2. HUB_IDENTITY:HUB_IDENTITY skip cloud verify (lab flag) —— 设计行为,不是失败
  3. initLocalHub:DTLS 中枢IP:5670,DTLS13 3s 超时 → 回退 DTLS12 30s,仍 udpReadable=0 → 33s 后 {"mCode":268369917} = 0xF0010003
现象判据排查方向
HUB_SEARCH 5 次全超时{"found":false}① 中枢侧 socket 是否 bind 且已加入组播组(bind 0.0.0.0:5685 ≠ 能收组播,必须 IP_ADD_MEMBERSHIP);② 配置器组播出口网卡是否选对(多网卡时默认路由可能走错接口);③ 中枢业务状态机未就绪时 handler 会早退不回包
initLocalHub DTLS 零回包udpReadable=0 持续到超时① DTLS server 根本没收包:看 socket inode 创建时机、是否挂进事件循环;② 收到了但静默丢弃:PSK/credential 未装载(PSK 模式找不到 identity 时很多实现不回 alert);③ udpReadable=0 只是本端没收包,不能证明对端没收到
DTLS13 失败3s 超时后回退 DTLS12属兼容路径,回退成功即可用;两边版本能力需对齐
errCode 268369917= 0xF0010003本地中枢使能失败,可重试
认知要点:WiFi 配网流程与中枢状态机是两套独立的东西。BLE/SPEKE/hubCfg/netCfg/online_notify 全部走通,也不代表中枢已进入可服务状态——步骤 10/11 的前置条件是中枢自身的业务状态机已 READY。

步骤 11 · synvDevManageInfo

方向手机 → 中枢
报文DTLS CoAP POST /hub/synvDevManageInfo
拼写源码里是 synv(不是 sync),grep 时别写错
成功标志synvDevManageInfo errCode=0 → 配置器侧 netConfig result = true,整条配网链路结束
合法跳过待配设备不是中枢时:HUB_ENABLE skip not hub-center → state=HUB_SKIP provisionOk=true,是设计行为,不是失败
依赖以步骤 10 的 initLocalHub 成功为前提;HubSync 失败则 HUB_SYNC skip,本报文不会执行

4 · 关键陷阱清单

#陷阱后果判据
1SPEKE iterations 过大 + BLE 无去重 + 1500ms 重传msg2 重复处理,-196548 HMAC 校验失败PakeTask: SPEKE3.0 iteration 出现 2 次
2netCfg 100 是提前上报假阳性,8ms 就报 100104→100 间隔 < 1s 即可疑
3两套 PSK(provisionPSK vs DTLS credential)排查时张冠李戴pskId 是否来自 ConfiguratorCredentialStore
4online_notify 4 个静默跳过点60s 超时,日志零线索onlinenotifyRx=0 coapRxAny=false
5中枢业务状态机未 READY(如停在 UNINIT)步骤 10/11 全挂,且 WiFi 侧全通也无济于事中枢日志 handler 进入后即返回、无 tx
6synv 拼写grep 搜不到—
7HUB_SKIP / HUB_IDENTITY skip误判为失败看 provisionOk=true 即可确认配网本体成功

5 · 排障速查表

日志关键词所处步骤常见结论
BLE binder busy / superseded session1扫描没起来,配网根本没开始
speke fail. / errCode:-1965483iterations + 重传竞态
verifyProof 0 次3密钥确认没通过
deviceAuth success5-6PSK 认证已过
netCfg 104 后无 1008WiFi 关联失败
104→100 间隔 < 1s8假阳性,看 notify 才准
onlinenotifyRx=0 + timer timeout9设备没真入网 / notify 被静默跳过
HUB_SEARCH ... found=false10a组播没入组 / 出口网卡错 / 中枢未就绪
initLocalHub ... 26836991710cDTLS 零回包,查 socket 与 PSK 凭证装载
HUB_SYNC skip11前置 HubSync 失败,或被设计跳过

6 · 小结:理解这套流程的三个关键

  1. 两个平面的切换点在步骤 8→9。BLE 只负责"把 WiFi 凭证安全地送进去",设备一入网,后续所有通信(配置器↔设备、配置器↔中枢)全部走 UDP/CoAP,蓝牙不再参与。
  2. 加密从步骤 3 结束后开始。SPEKE msg4 之后 payload 全程加密,所以步骤 4~8 的日志只能看到命令名和长度,看不到内容——这是判断"卡在认证前还是认证后"的自然分界。
  3. netCfg 100 不等于联网成功。真正端到端的入网证明是步骤 9 的 online_notify:设备真的拿到了 IP 并且局域网可达。这是配置器 waitOnline 的唯一可信判据。
Logo

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

更多推荐