openharmony软总线之--连接模块分析 原创 精华

挖墙脚的农民工
发布于 2022-1-10 11:43
浏览
10收藏

@[toc](openharmony软总线之–连接模块分析

软总线介绍

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

connection模块

connection 包含的文件类型如下:

 connection
  │
  ├── ble        #低功耗蓝牙
  ├── br         #蓝牙
  ├── common      
  ├── interface  #外部调用接口
  ├── manager    #设备模块接入、启停管理
  └── tcp        #tcp 

当前设备需要支持的蓝牙/wifi/网口通信(目前蓝牙应该没有完善),其他网口和wifi 都基于tcp协议。蓝牙BLE/BR 基于蓝牙协议,因此当设备A与设备B(wifi)tcp通信时,设备A与设备c(蓝牙)同时需要具备有蓝牙通信能力。
openharmony软总线之--连接模块分析-鸿蒙开发者社区

g_connManager

ConnectFuncInterface *g_connManager[CONNECT_TYPE_MAX] = {0};

g_connManager 用于管理不同类型设备通信功能。其中支持的类似有CONNECT_TCP、CONNECT_BR及CONNECT_BLE。

typedef enum {
    CONNECT_TCP = 1,
    CONNECT_BR,
    CONNECT_BLE,
    CONNECT_TYPE_MAX
} ConnectType;

由于不同设备通信存在差异,需要通过回调来实现通信方式的配置,通信接口如下:

typedef struct {
    int32_t (*ConnectDevice)(const ConnectOption *option, uint32_t requestId, const ConnectResult *result);
    int32_t (*PostBytes)(uint32_t connectionId, const char *data, int32_t len, int32_t pid, int32_t flag);
    int32_t (*DisconnectDevice)(uint32_t connectionId);
    int32_t (*DisconnectDeviceNow)(const ConnectOption *option);
    int32_t (*GetConnectionInfo)(uint32_t connectionId, ConnectionInfo *info);
    int32_t (*StartLocalListening)(const LocalListenerInfo *info);
    int32_t (*StopLocalListening)(const LocalListenerInfo *info);
} ConnectFuncInterface;

设备启动时通ConnServerInit 函数进行初始化。ConnInitTcp、ConnInitBr、ConnInitBle 分别对应3种通信设备类型的初始化

ConnectFuncInterface *ConnInitTcp(const ConnectCallback *callback)
{
    if (callback == NULL) {
        SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "ConnectCallback is NULL.");
        return NULL;
    }
    if (InitProperty() != SOFTBUS_OK) {
        SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Can not InitProperty");
        return NULL;
    }
    ConnectFuncInterface *interface = SoftBusCalloc(sizeof(ConnectFuncInterface));
    if (interface == NULL) {
        SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "InitTcp failed.");
        return NULL;
    }
    interface->ConnectDevice = TcpConnectDevice;
    interface->DisconnectDevice = TcpDisconnectDevice;
    interface->DisconnectDeviceNow = TcpDisconnectDeviceNow;
    interface->PostBytes = TcpPostBytes;
    interface->GetConnectionInfo = TcpGetConnectionInfo;
    interface->StartLocalListening = TcpStartListening;
    interface->StopLocalListening = TcpStopListening;
    g_tcpConnCallback = callback;

    if (g_tcpConnInfoList == NULL) {
        g_tcpConnInfoList = CreateSoftBusList();
        if (g_tcpConnInfoList == NULL) {
            SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "Create tcpConnInfoList failed.");
            SoftBusFree(interface);
            return NULL;
        }
        g_tcpConnInfoList->cnt = 0;
    }
    if (g_tcpListener == NULL) {
        g_tcpListener = (SoftbusBaseListener *)SoftBusCalloc(sizeof(SoftbusBaseListener));
        if (g_tcpListener == NULL) {
            SoftBusFree(interface);
            DestroySoftBusList(g_tcpConnInfoList);
            g_tcpConnInfoList = NULL;
            return NULL;
        }
    }
    g_tcpListener->onConnectEvent = TcpOnConnectEvent;
    g_tcpListener->onDataEvent = TcpOnDataEvent;
    return interface;
}

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

typedef struct {
    void (*OnConnected)(uint32_t connectionId, const ConnectionInfo *info);
    void (*OnDisconnected)(uint32_t connectionId, const ConnectionInfo *info);
    void (*OnDataReceived)(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int32_t len);
} ConnectCallback;

数据接收函数
ConnManagerRecvData

void ConnManagerRecvData(uint32_t connectionId, ConnModule moduleId, int64_t seq, char *data, int32_t len)
{
    ConnListenerNode listener;
    int32_t ret;
    char* pkt = NULL;
    int32_t pktLen;

    if (data == NULL) {
        return;
    }

    if (len <= (int32_t)sizeof(ConnPktHead)) {
        SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "len %d \r\n", len);
        return;
    }

    ret = GetListenerByModuleId(moduleId, &listener);
    if (ret == SOFTBUS_ERR) {
        SoftBusLog(SOFTBUS_LOG_CONN, SOFTBUS_LOG_ERROR, "GetListenerByModuleId fail moduleId %d \r\n", moduleId);
        return;
    }

    pktLen = len - sizeof(ConnPktHead);
    pkt = data + sizeof(ConnPktHead);
    listener.callback.OnDataReceived(connectionId, moduleId, seq, pkt, pktLen);
    return;
}

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

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-1-11 10:03:19修改
13
收藏 10
回复
举报
5条回复
按时间正序
/
按时间倒序
物联风景
物联风景

好贴,感谢感谢

回复
2022-1-11 09:20:38
科技维度
科技维度

内容不错。点赞

1
回复
2022-1-11 16:02:48
碼磚民工
碼磚民工

点赞666

1
回复
2022-2-11 15:25:34
民之码农
民之码农

666

回复
2022-2-21 11:23:23
杀手来过
杀手来过

请问这是标准系统的软总线吗?还不完善?

回复
2022-3-3 13:55:36
回复
    相关推荐