DSoftBus 设备发现机制技术分析
1. 概述
DSoftBus(分布式软总线)的设备发现机制基于 Publish-Subscribe(发布-订阅) 模型。
- 发布端 (Publisher):主动广播自身能力(Capability)与设备信息。
- 订阅端 (Subscriber):注册发现请求,监听特定能力或所有设备的广播。
在 ui/devicemanagerclient 的实现中,UI 客户端主要扮演 订阅端 的角色,通过主动发现(Active Discovery)模式寻找局域网内的设备。
2. 核心数据结构:SubscribeInfo
设备发现的行为由 SubscribeInfo 结构体定义,决定了发现的模式、介质与频率。
cpp
// 引用自 devicemanagerclient.cpp
static SubscribeInfo s_disc_sInfo = {
.subscribeId = DISC_SUBSCRIBE_ID, // 订阅 ID,唯一标识(部分实现中会随机生成)
.mode = DISCOVER_MODE_ACTIVE, // 主动发现模式 (Active)
.medium = COAP, // 传输介质:COAP (基于 UDP 的低功耗协议)
.freq = HIGH, // 扫描频率:高频 (HIGH)
.isSameAccount = false, // 账号过滤:false 表示发现所有设备,不限同账号
.isWakeRemote = false, // 远程唤醒:false
.capability = CAPABILITY, // 业务能力标识,例如 "osdCapability"
.capabilityData = nullptr,
.dataLen = 0
};
关键字段解析
- mode (DISCOVER_MODE_ACTIVE) :
- Active (主动):设备主动发送探测包(Probe),寻找周围设备。适用于实时性要求高的场景。
- Passive (被动):仅监听周围设备的广播包,不主动探测。适用于后台低功耗场景。
- medium (COAP) :
- 使用 CoAP (Constrained Application Protocol) 协议。在 DSoftBus 中,这通常对应于基于 WiFi/UDP 的发现通道,适用于局域网环境。
- 其他介质可能包括 BLE (蓝牙低功耗) 等。
- capability :
- 只有声明了相同能力(Publish 对应 Capability)的设备才会被发现,实现了业务隔离。
3. 发现流程全链路分析
从用户点击 UI 到底层协议栈的调用链路如下:
3.1. 应用层 (UI/Client)
- 触发:用户点击"发现"按钮。
- 调用 :
devicemanagerclient.cpp调用StartDeviceDiscovery(s_disc_sInfo)。- 若正在发现,则先调用
StopDeviceDiscovery停止旧任务(刷新逻辑)。 - 生成随机
subscribeId(在部分逻辑中) 以区分任务。
- 若正在发现,则先调用
3.2. SDK 层 (Device Manager SDK)
- 接口封装 :
devicemanagersdk.cpp中的StartDeviceDiscovery。 - 序列化 :将
SubscribeInfo序列化为OHOS::Parcel对象。 - IPC 通信 :通过
SendRequest发送指令给 DeviceManager 服务端(独立进程)。
3.3. 服务端与软总线核心 (DSoftBus Core)
- 请求分发:服务端接收 IPC 请求,解析参数。
- LNN (Local Network Node) 模块 :
lnn_discovery_manager.c负责管理发现策略。 - 适配层 :调用
LnnStartCoapDiscovery->DiscCoapStartDiscovery。 - 协议栈适配 :
disc_nstackx_adapter.c将请求转换为NSTACKX_DiscoverySettings。
3.4. 协议栈底层 (NSTACKX)
- 执行发现 :
nstackx_common.c中的NSTACKX_StartDeviceDiscovery。 - 事件循环 :将发现任务
DeviceDiscoverInnerConfigurable投递到epoll事件循环。 - 网络交互:底层通过 Socket 发送 UDP 组播/广播报文(CoAP 协议)。
3.5. 设备上线回调 (Callback Path)
当网络层收到对端设备的响应报文时:
- 协议栈:解析报文,提取设备信息(DeviceID, Name, Capability)。
- 回调上报 :
NSTACKX->DiscCoapOnDeviceFoundLnnDiscoveryImplCallback->DeviceFoundISoftbusDiscoveryCallback(IPC 回传) -> SDK 客户端
- UI 处理 :
devicemanagerclient.cpp的OnDeviceFound(const AuthDeviceInfo &info, bool isOnline)被触发。- UI 更新 :通过 Qt 信号
SigAddConnectDevInfo(若在线) 或SigAddDscoveryDevInfo(若离线) 将设备添加到列表。
4. 调用时序图
Network(CoAP) DSoftBus_Service DeviceManagerSDK DeviceManagerClient User Network(CoAP) DSoftBus_Service DeviceManagerSDK DeviceManagerClient User 扫描周围设备... 点击 "发现" StartDeviceDiscovery(info) IPC: StartDiscovery 发送 CoAP Probe 报文 收到设备响应 (Device Found) IPC Callback: OnDeviceFound OnDeviceFound(AuthDeviceInfo) 更新设备列表显示
5. 总结
DSoftBus 的发现机制通过分层架构实现了业务与底层协议的解耦:
- UI 层 仅需关注业务配置(如 Capability)。
- SDK 层 负责进程间通信与接口标准化。
- Core 层 负责具体的协议选择(CoAP/BLE)与策略管理。
- NSTACKX 层 处理底层的 Socket 通信与报文解析。
这种设计使得上层应用可以无感地使用多种发现介质,并能灵活切换主动/被动模式以平衡功耗与响应速度。