软总线源码分析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) < SOFTBUS_OK) {LOG_ERR("TransCreateSessionServer no permission!\n");return SOFTBUS_PERMISSION_DENIED;}SessionServer *newNode = (SessionServer *)SoftBusCalloc(sizeof(SessionServer));if (newNode == NULL) {return SOFTBUS_ERR;}if (strcpy_s(newNode->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_WATCHcase 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;
#endifdefault:break;}SoftBusFree(appInfo);return channelId;
}
该函数分为2步:
- 调用GetAppInfo创建了一个新的appInfo
- 然后根据ChannelType的类型,选择对应的处理。
第2步以CHANNEL_TYPE_TCP_DIRECT为例,该场景下:
- 调用GetConnectOptionTcp获取对端的IP地址和Port号,并保存在connOpt中。
- 调用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 <= 0) {TransCloseDirectChannel(newConn->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步:
- 创建了一个SessionConn节点,并对其进行赋值操作。
- 调用InitTdcInfo对创建的SessionConn节点进行初始化。
- 调用OpenConnTcp,根据对端的IP和端口号建议Socket连接
- 调用AddTrigger将socket描述符添加到g_listenerList里面DIRECT_CHANNEL_SERVER模块对应的的info中。
这里整体代码比较简单,因此不展开。
软总线源码分析8:传输模块相关推荐
- FFmpeg简述,源码分析,录制/压缩/水印/剪切/旋转/滤镜/美颜/上传视频等(CPU软编码和解码)
> ffmpeg源码分析 ffmpeg源码简析(一)结构总览- https://blog.csdn.net/Louis_815/article/details/79621056 FFmpeg的库 ...
- v66.07 鸿蒙内核源码分析(根文件系统) | 谁先挂到/谁就是根总 | 百篇博客分析OpenHarmony源码
季康子问政于孔子.孔子对曰:"政者,正也.子帅以正,孰敢不正?" <论语>:颜渊篇 百篇博客系列篇.本篇为: v66.xx 鸿蒙内核源码分析(根文件系统) | 谁先挂到 ...
- 实际测试例子+源码分析的方式解剖MyBatis缓存的概念
前言: 前方高能! 本文内容有点多,通过实际测试例子+源码分析的方式解剖MyBatis缓存的概念,对这方面有兴趣的小伙伴请继续看下去~ 欢迎工作一到五年的Java工程师朋友们加入Java架构开发:79 ...
- Android 源码分析之 EventBus 的源码解析
1.EventBus 的使用 1.1 EventBus 简介 EventBus 是一款用于 Android 的事件发布-订阅总线,由 GreenRobot 开发,Gihub 地址是:EventBus. ...
- 通过源码分析MyBatis的缓存
前方高能! 本文内容有点多,通过实际测试例子+源码分析的方式解剖MyBatis缓存的概念,对这方面有兴趣的小伙伴请继续看下去~ MyBatis缓存介绍 首先看一段wiki上关于MyBatis缓存的介绍 ...
- 【深入浅出MyBatis系列十一】缓存源码分析
为什么80%的码农都做不了架构师?>>> #0 系列目录# 深入浅出MyBatis系列 [深入浅出MyBatis系列一]MyBatis入门 [深入浅出MyBatis系列二]配置 ...
- 【作者面对面问答】包邮送《Redis 5设计与源码分析》5本
墨墨导读:本文节选自<Redis 5设计与源码分析>,主要为读者分析Redis高性能内幕,重点从源码层次讲解了Redis事件模型,网络IO事件重在使用IO复用模型,时间事件重在限制最大执行 ...
- android源码分析
01_Android系统概述 02_Android系统的开发综述 03_Android的Linux内核与驱动程序 04_Android的底层库和程序 05_Android的JAVA虚拟机和JAVA环境 ...
- MyBatis学习笔记-源码分析篇
引言 SQL 语句的执行涉及多个组件,其中比较重要的是 Executor. StatementHandler. ParameterHandler 和 ResultSetHandler. Executo ...
最新文章
- 线性回归、逻辑回归、损失函数
- 单机、集群与分布式的概念(转)
- 十六、python沉淀之路--迭代器
- 更新wpscan_wpscan扫描工具
- android执行命令行取得结果,Android调用shell脚本并取得输出
- 电磁冷坩埚行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
- Dubbo即将毕业,晋升为Apache顶级项目?
- redhat as4 上安装 MySQL5
- 清除eclipse当前登录的SVN账户
- jQuery 的 ajax 请求方法
- CMFCMenuBar 的另类动态修改
- 从这三个维度说一说,如何做一名具有产品思维的UI设计师?
- 日期转换和日历的使用方法
- 定点 浮点 神经网络 量化_定点量化
- 感恩工作平台心得体会_感恩工作心得体会
- 苹果审核Metadata Rejected解决
- 三十.什么是vm和vc?
- cad动态块制作翻转_CAD创建动态块实例教程:旋转参数和动作的应用 - CAD自学网...
- Python 将MP3音频文件转换成MIDI乐谱文件
- 360T7路由器进行WiFi无线中继教程
热门文章
- 查询一年1、1-2月、1-3~一直到1-12月
- 数据结构-图-知识点总结
- 三种css垂直居中方案
- 永不言弃,希望就在前方
- 韦东山 android 淘宝,韦东山-android音频子系统中audio_policy.conf的usb声卡理解 - 百问网嵌入式问答社区...
- 宝塔免费ssl证书是什么
- 历届试题 矩阵翻硬币 蓝桥杯 大数开方 大数相乘
- python实现K-means多维数据聚类代码
- 在商城项目开发中怎么保证促销商品不会超卖
- 计算机应用程序无响应,Win7系统运行Word文档提示“应用程序没有响应”怎么办...