1# 分布式软总线组件<a name="ZH-CN_TOPIC_0000001103650648"></a> 2 3- [分布式软总线组件<a name="ZH-CN_TOPIC_0000001103650648"></a>](#分布式软总线组件) 4 - [简介<a name="section13587125816351"></a>](#简介) 5 - [系统架构<a name="section13587185873516"></a>](#系统架构) 6 - [目录<a name="section161941989596"></a>](#目录) 7 - [约束<a name="section119744591305"></a>](#约束) 8 - [说明<a name="section1312121216216"></a>](#说明) 9 - [使用说明<a name="section1698318421816"></a>](#使用说明) 10 - [相关仓<a name="section1371113476307"></a>](#相关仓) 11 12## 简介<a name="section13587125816351"></a> 13 14现实中多设备间通信方式多种多样\(WIFI、蓝牙等\),不同的通信方式使用差异大,导致通信问题多;同时还面临设备间通信链路的融合共享和冲突无法处理等挑战。分布式软总线实现近场设备间统一的分布式通信管理能力,提供不区分链路的设备间发现连接、组网和传输能力,主要功能如下: 15 16- 发现连接:提供基于Wifi、蓝牙等通信方式的设备发现连接能力。 17- 设备组网:提供统一的设备组网和拓扑管理能力,为数据传输提供已组网设备信息。 18- 数据传输:提供数据传输通道,支持消息、字节、流、文件的数据传输能力。 19 20业务方通过使用分布式软总线提供的API实现设备间的高速通信,不用关心通信细节,进而实现业务平台的高效部署与运行能力。 21 22## 系统架构<a name="section13587185873516"></a> 23 24 25**图 1** 分布式软总线组件架构图<a name="fig4460722185514"></a> 26 27## 目录<a name="section161941989596"></a> 28 29分布式软总线组件主要代码目录结构如下: 30 31```text 32//foundation/communication/dsoftbus 33├── adapter # 适配层代码 34├── components # 依赖组件代码 35├── core # 核心代码 36│ ├── adapter # 适配层代码 37│ ├── authentication # 认证代码 38│ ├── bus_center # 组网代码 39│ ├── common # 通用代码 40│ ├── connection # 连接代码 41│ ├── discovery # 发现代码 42│ ├── frame # 框架代码 43│ └── transmission # 传输代码 44├── interfaces # 对外接口代码 45├── sdk # 运行业务进程代码 46│ ├── bus_center # 组网代码 47│ ├── discovery # 发现代码 48│ ├── frame # 框架代码 49│ └── transmission # 传输代码 50├── tests # 测试代码 51└── tools # 工具代码 52``` 53 54## 约束<a name="section119744591305"></a> 55 56- 组网设备需在同一局域网中 或者 距离相近的近场设备间。 57- 组网之前,需先完成设备绑定,绑定流程参见[安全基础能力子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E5%AE%89%E5%85%A8%E5%9F%BA%E7%A1%80%E8%83%BD%E5%8A%9B%E5%AD%90%E7%B3%BB%E7%BB%9F.md)中说明。 58- 传输完成数据收发之后,业务要主动关闭会话,释放资源。 59 60## 说明<a name="section1312121216216"></a> 61 62### 使用说明<a name="section1698318421816"></a> 63 64>**须知:** 65>使用跨设备通信时,必须添加权限`ohos.permission.DISTRIBUTED_DATASYNC`和`ohos.permission.DISTRIBUTED_SOFTBUS_CENTER`,该权限类型为 _**dangerous**_ 。 66 67**1、发现** 68 69- **发布流程** 70 711. 上层应用需要对外发布自身能力时,调用服务发布接口发布自身能力。 72 73 ```C 74 // 发布回调 75 typedef struct { 76 /** Callback for publish result */ 77 void (*OnPublishResult)(int publishId, PublishResult reason); 78 } IPublishCb; 79 80 // 发布信息 81 typedef struct { 82 int publishId; // 发布消息Id 83 DiscoverMode mode; // 发布模式 84 ExchangeMedium medium; // 发布媒介 85 ExchangeFreq freq; // 发布频率 86 const char *capability; // 被发现设备需要具备的能力 87 unsigned char *capabilityData; // 业务发布的自定义数据 88 unsigned int dataLen; // 数据长度 89 bool ranging; // 是否测距 90 } PublishInfo; 91 92 // 发布服务 93 int32_t PublishLNN(const char *pkgName, const PublishInfo *info, const IPublishCb *cb); 94 ``` 95 962. 上层应用不再需要对外发布自身能力时,调用StopPublishLNN接口注销服务。 97 98 ```C 99 // 注销服务 100 int32_t StopPublishLNN(const char *pkgName, int32_t publishId); 101 ``` 102 103 104- **发现流程** 105 1061. 上层应用需要发现特定能力设备时,调用发现接口启动发现。 107 108 ```C 109 // 发现回调 110 typedef struct { 111 /** Callback that is invoked when a device is found */ 112 void (*OnDeviceFound)(const DeviceInfo *device); 113 /** Callback for a subscription result */ 114 void (*OnDiscoverResult)(int32_t refreshId, RefreshResult reason); 115 } IRefreshCallback; 116 117 // 发现服务 118 int32_t RefreshLNN(const char *pkgName, const SubscribeInfo *info, const IRefreshCallback *cb); 119 ``` 120 1212. 当软总线发现到设备时,通过回调接口通知业务所发现的设备信息。 1223. 上层应用不再需要发现时,调用StopRefreshLNN接口停止设备发现。 123 124 ```C 125 // 停止发现 126 int32_t StopRefreshLNN(const char *pkgName, int32_t refreshId); 127 ``` 128 129**2、组网** 130 1311. 发起组网请求,携带组网连接地址信息,并且提供组网执行结果回调函数。 132 133 ```C 134 // 组网连接地址 135 typedef struct { 136 ConnectionAddrType type; 137 union { 138 struct BrAddr { 139 char brMac[BT_MAC_LEN]; 140 } br; 141 struct BleAddr { 142 char bleMac[BT_MAC_LEN]; 143 uint8_t udidHash[UDID_HASH_LEN]; 144 } ble; 145 struct IpAddr { 146 char ip[IP_STR_MAX_LEN]; 147 uint16_t port; 148 } ip; 149 } info; 150 char peerUid[MAX_ACCOUNT_HASH_LEN]; 151 } ConnectionAddr; 152 153 // 组网连接地址类型 154 typedef enum { 155 CONNECTION_ADDR_WLAN = 0, 156 CONNECTION_ADDR_BR, 157 CONNECTION_ADDR_BLE, 158 CONNECTION_ADDR_ETH, 159 CONNECTION_ADDR_MAX 160 } ConnectionAddrType; 161 162 // 组网请求执行结果回调 163 typedef void (*OnJoinLNNResult)(ConnectionAddr *addr, const char *networkId, int32_t retCode); 164 165 // 发起组网请求 166 int32_t JoinLNN(const char *pkgName, ConnectionAddr *target, OnJoinLNNResult cb); 167 ``` 168 1692. 等待组网结果,JoinLNN\(\)返回成功表示软总线接受了组网请求,组网结果通过回调函数通知业务;组网回调函数中addr参数内容和JoinLNN\(\)的入参互相匹配;retCode如果为0,表示组网成功,此时networkId为有效值,后续传输、退网等接口均需使用该参数;retCode如果不为0,表示组网失败,此时networkId为无效值。 1703. 使用传输相关接口进行数据传输。 1714. 发送退网请求,携带组网成功后返回的networkId,并且提供退网执行结果回调。 172 173 ```C 174 // 退网执行结果回调 175 typedef void (*OnLeaveLNNResult)(const char *networkId, int32_t retCode); 176 177 // 退网请求 178 int32_t LeaveLNN(const char *pkgName, const char *networkId, OnLeaveLNNResult cb); 179 ``` 180 1815. 等待退网完成,OnLeaveLNNResult\(\)的networkId和退网请求接口中的networkId互相匹配;retCode为0表示退网成功,否则退网失败。退网成功后,networkId变为无效值,后续不应该被继续使用。 1826. 使用节点(即设备)注册和注销接口,监听网络中节点状态变化等事件。 183 184 ```C 185 // 事件掩码 186 #define EVENT_NODE_STATE_ONLINE 0x1 187 #define EVENT_NODE_STATE_OFFLINE 0x02 188 #define EVENT_NODE_STATE_INFO_CHANGED 0x04 189 #define EVENT_NODE_STATUS_CHANGED 0x08 190 #define EVENT_NODE_STATE_MASK 0xF 191 192 // 节点信息 193 typedef struct { 194 char networkId[NETWORK_ID_BUF_LEN]; 195 char deviceName[DEVICE_NAME_BUF_LEN]; 196 uint16_t deviceTypeId; 197 } NodeBasicInfo; 198 199 // 节点状态事件回调 200 typedef struct { 201 uint32_t events; // 组网事件掩码 202 void (*onNodeOnline)(NodeBasicInfo *info); // 节点上线事件回调 203 void (*onNodeOffline)(NodeBasicInfo *info); // 节点下线事件回调 204 void (*onNodeBasicInfoChanged)(NodeBasicInfoType type, NodeBasicInfo *info); // 节点信息变化事件回调 205 void (*onNodeStatusChanged)(NodeStatusType type, NodeStatus *status); // 设备运行状态变化事件回调 206 } INodeStateCb; 207 208 // 注册节点状态事件回调 209 int32_t RegNodeDeviceStateCb(const char *pkgName, INodeStateCb *callback); 210 211 // 注销节点状态事件回调 212 int32_t UnregNodeDeviceStateCb(INodeStateCb *callback); 213 ``` 214 215**3、传输** 216 2171. 创建Socket。 218 219 ```C 220 typedef struct { 221 char *name; // 本端Socket名称 222 char *peerName; // 对端Socket名称 223 char *peerNetworkId; // 对端Socket的网络ID 224 char *pkgName; // 调用者包名 225 TransDataType dataType; // 传输的数据类型,需要与发送方法一致 226 } SocketInfo; 227 228 // 创建Socket 229 int32_t Socket(SocketInfo info); 230 ``` 231 2322. 服务端启动监听,客户端进行绑定。 233 234 ```C 235 // Socket回调函数 236 typedef struct { 237 void (*OnBind)(int32_t socket, PeerSocketInfo info); 238 void (*OnShutdown)(int32_t socket, ShutdownReason reason); 239 void (*OnBytes)(int32_t socket, const void *data, uint32_t dataLen); 240 void (*OnMessage)(int32_t socket, const void *data, uint32_t dataLen); 241 void (*OnStream)(int32_t socket, const StreamData *data, const StreamData *ext, const StreamFrameInfo *param); 242 void (*OnFile)(int32_t socket, FileEvent *event); 243 void (*OnQos)(int32_t socket, QoSEvent eventId, const QosTV *qos, uint32_t qosCount); 244 void (*OnError)(int32_t socket, int32_t errCode); 245 } ISocketListener; 246 247 typedef enum { 248 QOS_TYPE_MIN_BW, // 最小带宽 249 QOS_TYPE_MAX_WAIT_TIMEOUT, // Bind超时时间 250 QOS_TYPE_MIN_LATENCY, // 最小建链时延 251 QOS_TYPE_RTT_LEVEL, // 往返时间级别 252 QOS_TYPE_MAX_BUFFER, // 最大缓存(预留) 253 QOS_TYPE_FIRST_PACKAGE, // 首包大小(预留) 254 QOS_TYPE_MAX_IDLE_TIMEOUT, // 最大空闲时间 255 QOS_TYPE_TRANS_RELIABILITY, // 传输可靠性(预留) 256 QOS_TYPE_BUTT, 257 } QosType; 258 259 typedef struct { 260 QosType qos; 261 int32_t value; 262 } QosTV; 263 264 // 监听Socket,由服务端开启。 265 int32_t Listen(int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener); 266 267 // 绑定Socket,由客户端开启。 268 int32_t Bind(int32_t socket, const QosTV qos[], uint32_t qosCount, const ISocketListener *listener); 269 ``` 270 2714. 通过Socket向对端设备发送数据。 272 273 ```C 274 // 发送字节数据 275 int32_t SendBytes(int32_t socket, const void *data, uint32_t len); 276 // 发送消息数据 277 int32_t SendMessage(int32_t socket, const void *data, uint32_t len); 278 // 发送流数据 279 int32_t SendStream(int32_t socket, const StreamData *data, const StreamData *ext, const StreamFrameInfo *param); 280 // 发送文件 281 int32_t SendFile(int32_t socket, const char *sFileList[], const char *dFileList[], uint32_t fileCnt); 282 ``` 283 2845. 关闭Socket。 285 286 ```C 287 // 关闭Socket 288 void Shutdown(int32_t socket); 289 ``` 290 291**4、设备管理相关** 292 293- **选择Wi-Fi保活模式** 294 2951. 业务在软总线客户端调用ShiftLNNGear,通过IPC接口调用到服务端ShiftLNNGear,策略管理模块按照策略对TCP长连接的keepalive属性进行调整。 296 297 ```C 298 typedef struct { 299 ModeCycle cycle; // 保活探测间隔 300 ModeDuration duration; // 心跳模式持续时间 301 bool wakeupFlag; // 是否心跳唤醒对端设备 302 ModeAction action; // 选择模式动作 303 } GearMode; 304 305 typedef enum { 306 HIGH_FREQ_CYCLE = 30, // 心跳间隔30s 307 MID_FREQ_CYCLE = 60, // 心跳间隔60s 308 LOW_FREQ_CYCLE = 5 * 60, // 心跳间隔5min 309 DEFAULT_FREQ_CYCLE = 10 * 60, // 心跳间隔10min 310 } ModeCycle; 311 312 // 按照策略对TCP长连接的keepalive参数进行调整 313 int32_t ShiftLNNGear(const char *pkgName, const char *callerId, const char *targetNetworkId, const GearMode *mode); 314 ``` 315 3162. 业务指定不同的保活探测间隔,对应不同的TCP保活时长。 317 318 ```C 319 HIGH_FREQ_CYCLE = 30,代表TCP保活时长在40s以内; 320 MID_FREQ_CYCLE = 60,代表TCP保活时长在70s以内; 321 LOW_FREQ_CYCLE = 5*60,代表TCP保活时长在315s以内; 322 DEFAULT_FREQ_CYCLE = 10*60,代表TCP保活时长在615s以内。 323 ``` 324 325## 相关仓<a name="section1371113476307"></a> 326 327[分布式软总线子系统](https://gitee.com/openharmony/docs/blob/master/zh-cn/readme/%E5%88%86%E5%B8%83%E5%BC%8F%E8%BD%AF%E6%80%BB%E7%BA%BF%E5%AD%90%E7%B3%BB%E7%BB%9F.md) 328 329**communication_dsoftbus** 330 331[communication_bluetooth](https://gitee.com/openharmony/communication_bluetooth) 332 333[communication_ipc](https://gitee.com/openharmony/communication_ipc) 334 335[communication_wifi](https://gitee.com/openharmony/communication_wifi) 336