[文章]【OpenHarmony软总线】——连接模块分析

阅读量0
0
0
  目录
  • 软总线介绍
  • connection模块
  • g_connManager


软总线介绍
总线(Bus)是计算机各种功能部件之间传送信息的公共通信干线,软总线与总线协议类似存在相似的功能但又又差异。总线协议中多个设备通过公共通信干线来进行通信,设备需要具备收发数据功能。openharmony 软总线需要将不同设备整合到一起,由于不同的设备通信存在差异,如wifi与蓝牙之间通信存在差异,软总线(bus)需要具备有处理不同类型设备之间通信功能。connect 模块用于这种不同类型设备管理,当然也包含于不同模块的连接管理,如认证模块。

connection模块
connection 包含的文件类型如下:

  1. connection
  2.   │
  3.   ├── ble        #低功耗蓝牙
  4.   ├── br         #蓝牙
  5.   ├── common      
  6.   ├── interface  #外部调用接口
  7.   ├── manager    #设备模块接入、启停管理
  8.   └── tcp        #tcp
复制代码

当前设备需要支持的蓝牙/wifi/网口通信(目前蓝牙应该没有完善),其他网口和wifi 都基于tcp协议。蓝牙BLE/BR 基于蓝牙协议,因此当设备A与设备B(wifi)tcp通信时,设备A与设备c(蓝牙)同时需要具备有蓝牙通信能力。



g_connManager

  1. ConnectFuncInterface *g_connManager[CONNECT_TYPE_MAX] = {0};
复制代码

g_connManager 用于管理不同类型设备通信功能。其中支持的类似有CONNECT_TCP、CONNECT_BR及CONNECT_BLE。
  1. typedef enum {
  2.     CONNECT_TCP = 1,
  3.     CONNECT_BR,
  4.     CONNECT_BLE,
  5.     CONNECT_TYPE_MAX
  6. } ConnectType;
复制代码

由于不同设备通信存在差异,需要通过回调来实现通信方式的配置,通信接口如下:
  1. typedef struct {
  2.     int32_t (*ConnectDevice)(const ConnectOption *option, uint32_t requestId, const ConnectResult *result);
  3.     int32_t (*PostBytes)(uint32_t connectionId, const char *data, int32_t len, int32_t pid, int32_t flag);
  4.     int32_t (*DisconnectDevice)(uint32_t connectionId);
  5.     int32_t (*DisconnectDeviceNow)(const ConnectOption *option);
  6.     int32_t (*GetConnectionInfo)(uint32_t connectionId, ConnectionInfo *info);
  7.     int32_t (*StartLocalListening)(const LocalListenerInfo *info);
  8.     int32_t (*StopLocalListening)(const LocalListenerInfo *info);
  9. } ConnectFuncInterface;
复制代码

设备启动时通ConnServerInit 函数进行初始化。ConnInitTcp、ConnInitBr、ConnInitBle 分别对应3种通信设备类型的初始化
  1. ConnectFuncInterface *ConnInitTcp(const ConnectCallback *callback)
  2. {
  3.     if (callback == NULL) {
  4.         SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "ConnectCallback is NULL.");
  5.         return NULL;
  6.     }
  7.     if (InitProperty() != SOFTBUS_OK) {
  8.         SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Can not InitProperty");
  9.         return NULL;
  10.     }
  11.     ConnectFuncInterface *interface = SoftBusCalloc(sizeof(ConnectFuncInterface));
  12.     if (interface == NULL) {
  13.         SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "InitTcp failed.");
  14.         return NULL;
  15.     }
  16.     interface->ConnectDevice = TcpConnectDevice;
  17.     interface->DisconnectDevice = TcpDisconnectDevice;
  18.     interface->DisconnectDeviceNow = TcpDisconnectDeviceNow;
  19.     interface->PostBytes = TcpPostBytes;
  20.     interface->GetConnectionInfo = TcpGetConnectionInfo;
  21.     interface->StartLocalListening = TcpStartListening;
  22.     interface->StopLocalListening = TcpStopListening;
  23.     g_tcpConnCallback = callback;

  24.     if (g_tcpConnInfoList == NULL) {
  25.         g_tcpConnInfoList = CreateSoftBusList();
  26.         if (g_tcpConnInfoList == NULL) {
  27.             SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Create tcpConnInfoList failed.");
  28.             SoftBusFree(interface);
  29.             return NULL;
  30.         }
  31.         g_tcpConnInfoList->cnt = 0;
  32.     }
  33.     if (g_tcpListener == NULL) {
  34.         g_tcpListener = (SoftbusBaseListener *)SoftBusCalloc(sizeof(SoftbusBaseListener));
  35.         if (g_tcpListener == NULL) {
  36.             SoftBusFree(interface);
  37.             DestroySoftBusList(g_tcpConnInfoList);
  38.             g_tcpConnInfoList = NULL;
  39.             return NULL;
  40.         }
  41.     }
  42.     g_tcpListener->onConnectEvent = TcpOnConnectEvent;
  43.     g_tcpListener->onDataEvent = TcpOnDataEvent;
  44.     return interface;
  45. }
复制代码


interface 接口为tcp 通信方式的配置,ConnectDevice 连接设备,DisconnectDevice 断开连接,PostBytes 发送数据,GetConnectionInfo 获取设备端信息,StartLocalListening 启动监听,StopLocalListening关闭监听,注意,设备通过g_tcpListener 将设备挂载到软总线(bus)上面。每个设备需要通过不同端口建立起服务端和客服端模式,服务端用于监听数据请求。当有数据到来时,总线上面触发,经过一系列处理,最终通过g_connManagerCb变量获取对应数据。

  1. typedef struct {
  2.     void (*OnConnected)(uint32_t connectionId, const ConnectionInfo *info);
  3.     void (*OnDisconnected)(uint32_t connectionId, const ConnectionInfo *info);
  4.     void (*OnDataReceived)(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int32_t len);
  5. } ConnectCallback;
复制代码

数据接收函数
ConnManagerRecvData
  1. void ConnManagerRecvData(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int32_t len)
  2. {
  3.     ConnListenerNode listener;
  4.     int32_t ret;
  5.     char* pkt = NULL;
  6.     int32_t pktLen;

  7.     if (data == NULL) {
  8.         return;
  9.     }

  10.     if (len <= (int32_t)sizeof(ConnPktHead)) {
  11.         SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "len %d rn", len);
  12.         return;
  13.     }

  14.     ret = GetListenerByModuleId(moduleId, &listener);
  15.     if (ret == SOFTBUS_ERR) {
  16.         SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "GetListenerByModuleId fail moduleId %d rn", moduleId);
  17.         return;
  18.     }

  19.     pktLen = len - sizeof(ConnPktHead);
  20.     pkt = data + sizeof(ConnPktHead);
  21.     listener.callback.OnDataReceived(connectionId, moduleId, seq, pkt, pktLen);
  22.     return;
  23. }
复制代码


软总线通信模块由不同模块组合而成,如发现,认证等,当认证模块通过connect 接入总线时,数据获取流程为:softbus-> ConnManagerRecvData-> listener.callback.OnDataReceived,可以参考总线认证一块测试用例。
当然由于当前软总线功能不完善,部分数据流程存在不完善的情况。


回帖

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
链接复制成功,分享给好友