> 文档中心 > 软总线源码分析8:传输模块

软总线源码分析8:传输模块

前面我们看过了软总线的发现,组网,认证处理,现在我们看一下软总线的传输处理。

创建会话

创建会话的接口如下:

SoftBusServer::CreateSessionServer(const char *pkgName, const char *sessionName)

其直接调用了函数TransCreateSessionServer,其源码如下:

int32_t TransCreateSessionServer(const char *pkgName, const char *sessionName){    if (!IsValidString(pkgName, PKG_NAME_SIZE_MAX) || !IsValidString(sessionName, SESSION_NAME_SIZE_MAX)) { return SOFTBUS_INVALID_PARAM;    }    if (CheckTransPermission(sessionName, pkgName, ACTION_CREATE) pkgName, sizeof(newNode->pkgName), pkgName) != EOK) { SoftBusFree(newNode); return SOFTBUS_ERR;    }    if (strcpy_s(newNode->sessionName, sizeof(newNode->sessionName), sessionName) != EOK) { SoftBusFree(newNode); return SOFTBUS_ERR;    }    newNode->type = SEC_TYPE_CIPHERTEXT;    int ret = TransSessionServerAddItem(newNode);    if (ret != SOFTBUS_OK) { SoftBusFree(newNode); if (ret == SOFTBUS_SERVER_NAME_REPEATED) {     LOG_INFO("SessionServer is already created [%s]", sessionName);     return SOFTBUS_SERVER_NAME_REPEATED; } return ret;    }    LOG_INFO("CreateSessionServer OK, pkg name: [%s], session name: [%s]", pkgName, sessionName);    return SOFTBUS_OK;}

该函数首限创建了一个SessionServer节点,然后将其加入到g_sessionServerList列表中。

打开会话

打开会话的接口如下:

int32_t SoftBusServer::OpenSession(const char *mySessionName, const char *peerSessionName,    const char *peerDeviceId, const char *groupId, int32_t flags)

其调用了函数TransOpenSession,源码如下:

int32_t TransOpenSession(const char *mySessionName, const char *peerSessionName,    const char *peerDeviceId, const char *groupId, int32_t flags){    LOG_INFO("trans server opensession.");    if (!IsValidString(mySessionName, SESSION_NAME_SIZE_MAX) || !IsValidString(peerSessionName, SESSION_NAME_SIZE_MAX) || !IsValidString(peerDeviceId, DEVICE_ID_SIZE_MAX) || !IsValidString(groupId, GROUP_ID_SIZE_MAX)) { return INVALID_CHANNEL_ID;    }    char pkgName[PKG_NAME_SIZE_MAX];    if (TransGetPkgNameBySessionName(mySessionName, pkgName, PKG_NAME_SIZE_MAX) != SOFTBUS_OK) { LOG_ERR("TransGetPkgNameBySessionName failed"); return SOFTBUS_ERR;    }    if (CheckTransPermission(mySessionName, pkgName, ACTION_OPEN) < SOFTBUS_OK) { LOG_ERR("TransOpenSession no permission!"); return SOFTBUS_PERMISSION_DENIED;    }    if (!TransSessionServerIsExist(mySessionName)) { LOG_ERR("session server invalid"); return INVALID_CHANNEL_ID;    }    return TransOpenChannel(mySessionName, peerSessionName, peerDeviceId, groupId, flags);}

该函数对入参进行校验之后,便调用TransOpenChannel进行处理,该函数源码如下:

int32_t TransOpenChannel(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId,    const char *groupId, int32_t flags){    int32_t channelId = INVALID_CHANNEL_ID;    if (!IsValidString(mySessionName, SESSION_NAME_SIZE_MAX) || !IsValidString(peerSessionName, SESSION_NAME_SIZE_MAX) || !IsValidString(peerDeviceId, DEVICE_ID_SIZE_MAX) || !IsValidString(groupId, GROUP_ID_SIZE_MAX)) { return channelId;    }    ConnectOption connOpt = {0};    AppInfo *appInfo = GetAppInfo(mySessionName, peerSessionName, peerDeviceId, groupId, flags);    if (appInfo == NULL) { LOG_ERR("get app info err"); return channelId;    }    int type = TransGetChannelType();    switch (type) { case CHANNEL_TYPE_PROXY:     if (GetConnectOptionBr(peerDeviceId, &connOpt) != SOFTBUS_OK) {  LOG_ERR("get connection opt err");  break;     }     if (TransProxyOpenProxyChannel(appInfo, &connOpt, &channelId) != SOFTBUS_OK) {  LOG_ERR("open proxy channel err");  channelId = INVALID_CHANNEL_ID;     }     break;#ifndef SOFTBUS_WATCH case CHANNEL_TYPE_TCP_DIRECT:     if (GetConnectOptionTcp(peerDeviceId, &connOpt) != SOFTBUS_OK) {  LOG_ERR("get connection opt err");  break;     }     if (TransOpenTcpDirectChannel(appInfo, &connOpt, &channelId) != SOFTBUS_OK) {  LOG_ERR("open direct channel err");  channelId = INVALID_CHANNEL_ID;     }     break;#endif default:     break;    }    SoftBusFree(appInfo);    return channelId;}

该函数分为2步:

  1. 调用GetAppInfo创建了一个新的appInfo
  2. 然后根据ChannelType的类型,选择对应的处理。

第2步以CHANNEL_TYPE_TCP_DIRECT为例,该场景下:

  1. 调用GetConnectOptionTcp获取对端的IP地址和Port号,并保存在connOpt中。
  2. 调用TransOpenTcpDirectChannel进行处理。

TransOpenTcpDirectChannel的源码如下:

int32_t TransOpenTcpDirectChannel(AppInfo *appInfo, const ConnectOption *connInfo, int *fd){    if (appInfo == NULL || connInfo == NULL || fd == NULL) { LOG_ERR("param is invalid."); return SOFTBUS_INVALID_PARAM;    }    char *ip = (char*)connInfo->info.ipOption.ip;    int sessionPort = connInfo->info.ipOption.port;    appInfo->routeType = WIFI_STA;    SessionConn *newConn = (SessionConn*)SoftBusMalloc(sizeof(SessionConn));    if (newConn == NULL) { LOG_ERR("Malloc err."); return SOFTBUS_ERR;    }    if (memcpy_s(&newConn->appInfo, sizeof(AppInfo), appInfo, sizeof(AppInfo)) != EOK) { SoftBusFree(newConn); LOG_ERR("Memcpy ip err."); return SOFTBUS_ERR;    }    newConn->appInfo.fd = -1;    newConn->serverSide = false;    newConn->channelId = INVALID_CHANNEL_ID;    if (strcpy_s(newConn->appInfo.peerData.ip, IP_LEN, ip) != EOK) { SoftBusFree(newConn); LOG_ERR("strcpy_s err."); return SOFTBUS_ERR;    }    newConn->appInfo.peerData.port = sessionPort;    newConn->status = TCP_DIRECT_CHANNEL_STATUS_HANDSHAKING;    newConn->timeout = 0;    if (InitTdcInfo(newConn) != SOFTBUS_OK) { SoftBusFree(newConn); return SOFTBUS_ERR;    }    *fd = OpenConnTcp(appInfo, connInfo);    if (*fd channelId); SoftBusFree(newConn); LOG_ERR("OpenConnTcp err."); return SOFTBUS_ERR;    }    newConn->appInfo.fd = *fd;    newConn->channelId = *fd;    if (AddTrigger(DIRECT_CHANNEL_SERVER, newConn->appInfo.fd, RW_TRIGGER) != SOFTBUS_OK) { TransCloseDirectChannel(newConn->channelId); SoftBusFree(newConn); LOG_ERR("AddTrigger failed"); return SOFTBUS_ERR;    }    return SOFTBUS_OK;}

该函数分为4步:

  1. 创建了一个SessionConn节点,并对其进行赋值操作。
  2. 调用InitTdcInfo对创建的SessionConn节点进行初始化。
  3. 调用OpenConnTcp,根据对端的IP和端口号建议Socket连接
  4. 调用AddTrigger将socket描述符添加到g_listenerList里面DIRECT_CHANNEL_SERVER模块对应的的info中。

这里整体代码比较简单,因此不展开。