一、软总线连接设备数量限制
1.1 社区维护的开发人员解释
openharmony 4.0 与5.0-Beta1版本 连接数量对比:
软总线4.0 最大10个 session ,sa 是 100个,链路层 4个
sa:
网络协议栈侧定义为: 最多100个
./components/nstackx/nstackx_ctrl/interface/nstackx.h
#define NSTACKX_MAX_ADVERTISE_COUNT 100
./sdk/transmission/session/src/client_trans_session_service.c
SESSION_STATUS_CHECK_MAX_NUM 100
软总线5.0 最大32个 session ,sa 是 100个,链路层 4个
在代码注释中也有写32个 非 社区维护人员说的 20个(我已经在gitee 提issues交流下)
openharmony 4.0 :core/common/include/softbus_def.h:71:#define MAX_SESSION_SERVER_NUMBER 10
openharmony 5.0 :core/common/include/softbus_def.h:71:#define MAX_SESSION_SERVER_NUMBER 32
链路层 4个
core/connection/wifi_direct/wifi_direct_decision_center.h:24:#define MAX_CONNECTED_DEVICE_COUNT 4
1.2 源码解析
代码目录解释:
├── adapter //适配层
│ ├── BUILD.gn
│ ├── common //适配层管理,网络适配,协议适配等
│ └── default_config //适配层配置
├── BUILD.gn
├── bundle.json
├── check_sub_module.py
├── components //依赖组件
│ ├── mbedtls //开源ssl库,在三方库里
│ └── nstackx //tcp/ip协议管理模块
├── config.py
├── core //核心层
│ ├── adapter //适配接口
│ ├── authentication //认证接口
│ ├── BUILD.gn
│ ├── bus_center //组网代码
│ ├── common //通用代码
│ ├── connection //连接代码
│ ├── discovery //发现代码
│ ├── frame
│ └── transmission //传输代码
├── dsoftbus.gni
├── figures
│ ├── dsoftbus-architecture.png
│ └── dsoftbus-architecture_zh.png
├── hisysevent.yaml
├── interfaces //对外头文件
│ ├── inner_kits
│ └── kits
├── Kconfig
├── LICENSE
├── OAT.xml
├── README.md
├── README_zh.md
├── sdk
│ ├── BUILD.gn
│ ├── bus_center //组网
│ ├── discovery //发现
│ ├── frame
│ └── transmission //传输
├── tests
│ ├── adapter
│ ├── BUILD.gn
│ ├── core
│ ├── include
│ └── sdk
└── tools //测试工具
├── BUILD.gn
└── device_info
主要这四个部分:
adapter:适配层,可以裁剪软总线的功能,如再:adapter/default_config/feature_config/standard
authentication:提供设备认证机制和设备管理功能
discovery:基于coap协议的设备发现机制
transmission:基于协议栈提供传输功能
1.2.1源码解析 软总线4.0 :最大10个 session ,sa 是 100个,链路层 4个
最大10个 session
#define MAX_SESSION_SERVER_NUMBER =10
int32_t ClientAddSessionServer(SoftBusSecType type, const char *pkgName, const char *sessionName,
const ISessionListener *listener)
{
if (pkgName == NULL || sessionName == NULL || listener == NULL) {
return SOFTBUS_INVALID_PARAM;
}
if (g_clientSessionServerList == NULL) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "not init");
return SOFTBUS_TRANS_SESSION_SERVER_NOINIT;
}
if (SoftBusMutexLock(&(g_clientSessionServerList->lock)) != 0) {
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "lock failed");
return SOFTBUS_LOCK_ERR;
}
if (SessionServerIsExist(sessionName)) {
(void)SoftBusMutexUnlock(&g_clientSessionServerList->lock);
return SOFTBUS_SERVER_NAME_REPEATED;
}
/* 这里判断client session 最大 不超过 10个 */
if (g_clientSessionServerList->cnt >= MAX_SESSION_SERVER_NUMBER) {
(void)SoftBusMutexUnlock(&(g_clientSessionServerList->lock));
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "server num reach max");
return SOFTBUS_INVALID_NUM;
}
ClientSessionServer *server = GetNewSessionServer(type, sessionName, pkgName, listener);
if (server == NULL) {
(void)SoftBusMutexUnlock(&(g_clientSessionServerList->lock));
return SOFTBUS_MEM_ERR;
}
server->permissionState = true;
ListAdd(&g_clientSessionServerList->list, &server->node);
g_clientSessionServerList->cnt++;
/* 日志中打印 session与pkg 名字 */
(void)SoftBusMutexUnlock(&g_clientSessionServerList->lock);
SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "session name [%s], pkg name [%s]",
server->sessionName, server->pkgName);
return SOFTBUS_OK;
}
根据两台设备连接过程的hilog日志来分析调用流程如下
memberFuncMap 会根据 event 的 id 从 memberFuncMap_拿到对应的 memberFunc,然后进入对应的处理函数
/*SAID: 4700*/
enum SoftBusFuncId {
MANAGE_REGISTER_SERVICE = 0,
SERVER_PUBLISH_SERVICE = 128,
SERVER_UNPUBLISH_SERVICE,
SERVER_CREATE_SESSION_SERVER, // 130 CreateSessionServer 的 event ID
SERVER_REMOVE_SESSION_SERVER,
函数调用关系如下如下:
|--OnRemoteRequest
|--CreateSessionServerInner
|--OnRemoteRequest
I-- CreateSessionServer
|--ClientAddSessionServer
sa 是 100
nstack: 是软总线网络协议栈的部分
#define NSTACKX_MAX_ADVERTISE_COUNT 100
static int32_t CheckDiscoverySettings(const NSTACKX_DiscoverySettings *discoverySettings)
{
if (discoverySettings == NULL) {
DFINDER_LOGE(TAG, "Invalid discoverySettings info");
return NSTACKX_EINVAL;
}
if ((discoverySettings->businessData == NULL) && (discoverySettings->length != 0)) {
DFINDER_LOGE(TAG, "Invalid discoverySettings bData info");
return NSTACKX_EINVAL;
}
if (discoverySettings->length >= NSTACKX_MAX_BUSINESS_DATA_LEN) {
DFINDER_LOGE(TAG, "businessData length is too long");
return NSTACKX_EINVAL;
}
uint32_t advertiseCount = discoverySettings->advertiseCount;
uint32_t advertiseDuration = discoverySettings->advertiseDuration;
if ((advertiseCount == 0) && (advertiseDuration == 0)) {
return NSTACKX_EOK;
} /* 发现设备的数量小于 100 */
if ((advertiseCount < NSTACKX_MIN_ADVERTISE_COUNT) || (advertiseCount > NSTACKX_MAX_ADVERTISE_COUNT) ||
(advertiseDuration < NSTACKX_MIN_ADVERTISE_DURATION) || (advertiseDuration > NSTACKX_MAX_ADVERTISE_DURATION)) {
DFINDER_LOGE(TAG, "Invalid discoverySettings advertise info");
return NSTACKX_EINVAL;
}
return NSTACKX_EOK;
}
根据两台设备连接过程的hilog日志来分析调用流程如下:
函数调用关系如下如下:
|--CoapPublish
|--DiscCoapStartDiscovery
|--NSTACKX_StartDeviceDiscovery
|--CheckDiscoverySettings
物理链路上,最大支持同时连接四台设备
#define MAX_CONNECTED_DEVICE_COUNT 4
static void UpdateInnerLink(struct WifiDirectP2pGroupInfo *groupInfo)
{
struct InterfaceInfo *localInfo = GetResourceManager()->getInterfaceInfo(IF_NAME_P2P);
struct WifiDirectIpv4Info *localIpv4 = localInfo->getRawData(localInfo, II_KEY_IPV4, NULL, NULL);
if (!groupInfo->isGroupOwner) {
CLOGI(LOG_LABEL "not group owner");
char groupOwnerMac[MAC_ADDR_STR_LEN] = {0};
int32_t ret = GetWifiDirectNetWorkUtils()->macArrayToString(groupInfo->groupOwner.address, MAC_ADDR_ARRAY_SIZE,
groupOwnerMac, sizeof(groupOwnerMac));
CONN_CHECK_AND_RETURN_LOG(ret == SOFTBUS_OK, LOG_LABEL "convert mac to string failed");
CLOGI(LOG_LABEL "groupOwnerMac=%s", WifiDirectAnonymizeMac(groupOwnerMac));
struct InnerLink link;
InnerLinkConstructorWithArgs(&link, WIFI_DIRECT_CONNECT_TYPE_P2P, true, IF_NAME_P2P, groupOwnerMac);
link.putInt(&link, IL_KEY_STATE, INNER_LINK_STATE_CONNECTED);
link.putInt(&link, IL_KEY_FREQUENCY, groupInfo->frequency);
GetLinkManager()->notifyLinkChange(&link);
InnerLinkDestructor(&link);
return;
}
/* MAX_CONNECTED_DEVICE_COUNT=4 */
char clientDevicesBuf[MAX_CONNECTED_DEVICE_COUNT][MAC_ADDR_STR_LEN] = {0};
/* clientDeviceSize 判断是否小于4 */
char *clientDevices[MAX_CONNECTED_DEVICE_COUNT] = {NULL};
int32_t clientDeviceSize = MIN(groupInfo->clientDeviceSize, MAX_CONNECTED_DEVICE_COUNT);
CLOGI(LOG_LABEL "local is group owner, clientDeviceSize=%d", clientDeviceSize);
for (int32_t i = 0; i < clientDeviceSize; i++) {
clientDevices[i] = clientDevicesBuf[i];
GetWifiDirectNetWorkUtils()->macArrayToString(groupInfo->clientDevices[i].address, MAC_ADDR_ARRAY_SIZE,
clientDevices[i], MAC_ADDR_STR_LEN);
CLOGI(LOG_LABEL "remoteMac=%s", WifiDirectAnonymizeMac(clientDevices[i]));
struct InnerLink newLink;
InnerLinkConstructorWithArgs(&newLink, WIFI_DIRECT_CONNECT_TYPE_P2P, false, IF_NAME_P2P, clientDevices[i]);
newLink.putInt(&newLink, IL_KEY_STATE, INNER_LINK_STATE_CONNECTED);
newLink.putRawData(&newLink, IL_KEY_LOCAL_IPV4, localIpv4, sizeof(*localIpv4));
newLink.putInt(&newLink, IL_KEY_FREQUENCY, groupInfo->frequency);
GetLinkManager()->notifyLinkChange(&newLink);
InnerLinkDestructor(&newLink);
}
GetLinkManager()->refreshLinks(WIFI_DIRECT_CONNECT_TYPE_P2P, clientDeviceSize, clientDevices);
}
根据两台设备连接过程的hilog日志来分析调用流程如下:
函数调用关系如下如下:
|--BroadcastHandlerInit
|--Listener
|--P2pEntityBroadcastHandler
|--HandleP2pConnectionChanged
|--UpdateInnerLink