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![](figures/dsoftbus-architecture_zh.png)
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