源码目录:
authmanager
【提供设备认证机制和设备知识库管理】
discovery
【提供基于
coap
协议的设备发现机制】
os_adapter
【操作系统适配层】
trans_service
【提供认证和数据传输通道】
一、如何初始化软总线
一、被发现端,发布服务。【
discovery
目录】
1.
初始化
InitService()
发现服务
1.1.
初始化
g_deviceInfo
结构体
1.2.
初始化全局
g_publishModule
和
g_capabilityData
1.3.
初始化
COAP
协议服务
a.COAP
初始化
Socket
b.COAP
初始化
wifi
事件
c.
创建
COAP
监听线程
, HandleReadEvent()
2.
模块增加到
g_publishModule
3.CoapRegisterDefualtService()
总结:
二、当接入网络,触发
WifiEventTrigger()
,开启软总线
1.
获取本设备
ip
2.BusManager()
启动软总线
2.1.
启动监听
,StartListener(),
监听与发现端建立连接
2.2.
启动会话
,StartSession()
总结:
三、当发现端(比如手机)发送广播
1.
当检测到局域网内
UDP
广播包
,HandleReadEvent()
2.
当检测到新连接
,ProcessAuthData()
2.1
当建立新连接
,OnConnectEvent()
2.2
当接收到新数据
,OnDataEvent()
auth.
设备认证机制
authmanager
【提供设备认证机制和设备知识库管理】
reference
:
源码目录:
主目录
\foundation\communication\softbus_lite
authmanager
【提供设备认证机制和设备知识库管理】
├── authmanager
【提供设备认证机制和设备知识库管理】
├── discovery
【提供基于
coap
协议的设备发现机制】
├── interfaces
├── os_adapter
【操作系统适配层】
├── trans_service
【提供认证和数据传输通道】
└── BUILD.gn
通过
BUILD.gn
的分析,我们知道整个
softbus_lite
目录下的所有源码文件将被编译到一个动态库中。
其他依赖软总线的模块在编译的时候加上这个动态库的依赖就可以了。
例如:分布式调度子系统所在的
foundation
这个
bin
文件的编译就依赖这个动态库。
discovery
【提供基于
coap
协议的设备发现机制】
当发现有请求时,调用
ProcessDataEvent
函数,收包,检验包头,根据数据包的类型确定不同的处理方式。
类型主要包括以下三种:
MODULE_AUTH_SDK
加密数据类型
MODULE_TRUST_ENGINE
可信类型,直接进行数据传输
MODULE_CONNECTION
进行
ip
及设备认证
├── BUILD.gn
├── include
│ ├── auth_conn.h
│ ├── auth_interface.h
│ ├── bus_manager.h
│ ├── msg_get_deviceid.h
│ └── wifi_auth_manager.h
└── source
├── auth_conn.c
【提供发送、接收、认证、获取秘钥功能】
├── auth_interface.c
【管理各个会话节点、各个链接节点、各个秘钥节点,提供包括增删改查等功
能】
├── bus_manager.c
【主要通过
deviceIp
创建两个不同的
listen
,主要用来监听系统上有哪些
device
及新的
device
节点的创建
;
其中有两个回调函数
OnConnectEvent
和
OnDataEvent,
分别是用来处理
设备节点的基本操作及节点数据的处理】
├── msg_get_deviceid.c
【提供以
cJSON
格式获取各个设备的信息,包括设备
id
、链接信息、设备
名、设备类型等】
└── wifi_auth_manager.c
【主要实现了连接管理和数据接收功能。连接管理包括连接的建立、断开
及连接的查找。数据接收包括数据获取、包头及包长等的校验,并且为了简化包头数据读取,单独实现了对一
个
int
型和一个
long
型数据的接收函数】
├── BUILD.gn
├── coap
【目录主要是负责
COAP
协议的部分】
│ ├── include
│ │ ├── coap_adapter.h
│ │ ├── coap_def.h
│ │ ├── coap_discover.h
│ │ ├── coap_socket.h
│ │ ├── json_payload.h
│ │ ├── nstackx_common.h
│ │ ├── nstackx_database.h
│ │ ├── nstackx_device.h
│ │ ├── nstackx_error.h
│ │ └── nstackx.h
│ └── source
│ ├── coap_adapter.c
│ ├── coap_discover.c
【实现了基于
COAP
的设备发现功能】
│ ├── coap_socket.c
│ ├── json_payload.c
│ ├── nstackx_common.c
│ └── nstackx_device.c
└── discovery_service
【基于
coap
协议实现了轻量设备端的服务发布的能力】
├── include
│ ├── coap_service.h
│ ├── common_info_manager.h
│ └── discovery_error.h
└── source
├── coap_service.c
├── common_info_manager.c
└── discovery_service.c
os_adapter
【操作系统适配层】
trans_service
【提供认证和数据传输通道】
一、如何初始化软总线
调用软总线模块并不复杂,需要准备
2
个结构体就可以召唤神龙,简称
StartBus()
。以下我们以
Hi3861
为
例写一个简单的例子。
discovery
的实现前提是确保发现端设备与接收端设备在同一个局域网内且能互相收到对方的报文。大致流程
是:
发现端设备,使用
coap
协议在局域网内发送广播;
接收端设备使用
PublishService
接口发布服务,接收端收到广播后,发送
coap
协议单播给发现端;
发现端设备收到报文会更新设备信息。
├── include
│ └── os_adapter.h
└── source
├── L0
│ └── os_adapter.c
└── L1
└── os_adapter.c
它主要封装了
socket
、
cJSON
、线程锁接口,实现了用户的创建、监听、会话管理,以及设备、指令、数据等
信息的获取,最终提供加密和解密传输两种传输通道。
├── BUILD.gn
├── include
│ ├── libdistbus
│ │ ├── auth_conn_manager.h
│ │ └── tcp_session_manager.h
│ └── utils
│ ├── aes_gcm.h
│ ├── comm_defs.h
│ ├── data_bus_error.h
│ ├── message.h
│ └── tcp_socket.h
└── source
├── libdistbus
│ ├── auth_conn_manager.c
【用户创建,监听,连接等服务管理】
│ ├── tcp_session.c
【会话管理】
│ ├── tcp_session.h
│ ├── tcp_session_manager.c
│ ├── trans_lock.c
【互斥锁初始化以及互斥锁资源获取与释放】
│ └── trans_lock.h
└── utils
├── aes_gcm.c
【提供加密传输和解密传输接口】
├── message.c
【用于获取以
cJSON
格式管理的设备(包括设备名、设备类型、设备
ID
等
)
、指令、数据、会话(包括用户端口、会话端口等
)
等信息】
└── tcp_socket.c
【端口号管理以及数据传输管理】
static
void
InitSoftbus
(
void
)
{
printf
(
">>>>>%s:%d:%s()\n"
,
__FILE__
,
__LINE__
,
__FUNCTION__
);
一、被发现端,发布服务。【
discovery
目
录】
在分布式软总线子系统中,设备分为发现端和被发现端。这里我们使用手机作为发现端,
Hi3861
开发板
发布服务,作为被发现端。
发布服务主要是通过
PublishService()
这个函数,相关的代码在:主目录
\foundation\communication\softbus_lite\discovery_service
文件夹下。
如果设备要发布软总线服务,就需要调用下面这个函数。
static
PublishInfo g_publishInfo
=
{
.
capabilityData
=
(
unsigned char *
)
"1"
,
.
capability
=
"ddmpCapability"
,
.
dataLen
=
1
,
.
publishId
=
1
,
.
mode
=
DISCOVER_MODE_ACTIVE
,
.
medium
=
COAP
,
.
freq
=
MID
,
};
static
IPublishCallback g_publishCallback
=
{
.
onPublishSuccess
=
OnSuccess
,
.
onPublishFail
=
OnFail
,
};
int
ret
=
PublishService
(
g_demoModuleName
,
&
g_publishInfo
,
&
g_publishCallback
);
if
(
ret
!=
0
) {
printf
(
"PublishService err\n"
);
}
sleep
(
5
);
ret
=
CreateSessionServer
(
g_demoModuleName
,
g_demoSessionName
,
&
g_sessionCallback
);
if
(
ret
!=
0
) {
printf
(
"CreateSessionServer err\n"
);
}
printf
(
"InitSoftbus ok\n"
);
}
//moduleName
:调用模块名
//info
:
PublishInfo
结构体
//cb
:发布成功或者失败的回调函数
int
PublishService
(
const
char *
moduleName
,
const struct
PublishInfo
*
info
,
const
struct
IPublishCallback
*
cb
)
{
printf
(
">>>>>%s:%d:%s()[soft bus init
start]\n"
,
__FILE__
,
__LINE__
,
__FUNCTION__
);
//
许可检查,首先将检查是否有发布权限。这里调用的
os_adapter
【操作系统适配层】相关部分。
if
(
SoftBusCheckPermission
(
SOFTBUS_PERMISSION
)
!=
0
||
info
==
NULL
||
cb
==
NULL
) {
SOFTBUS_PRINT
(
"[DISCOVERY] PublishService invalid para(info or cb)\n"
);
return
ERROR_INVALID
;
}
//
参数有效性检查,检查了一些发布参数的合法性,其次确认发布协议是不是
COAP
。
if
(
moduleName
==
NULL
||
strlen
(
moduleName
)
>=
MAX_PACKAGE_NAME
||
info
-
>
publishId
<=
0
||
info
->
dataLen
>
MAX_CAPABILITY_DATA_LEN
) {
SOFTBUS_PRINT
(
"[DISCOVERY] PublishService invliad para\n"
);
PublishCallback
(
info
->
publishId
,
PUBLISH_FAIL_REASON_PARAMETER_INVALID
,
NULL
,
cb
);
return
ERROR_INVALID
;
}
//
如果参数检查失败,调用
PublishCallback()
来回调
cb
里面的失败回调函数
if
(
info
->
medium
!=
COAP
) {
PublishCallback
(
info
->
publishId
,
PUBLISH_FAIL_REASON_NOT_SUPPORT_MEDIUM
,
NULL
,
cb
);
return
ERROR_INVALID
;
}
//
用
g_discoveryMutex
防止多个设备对外发布服务产生的冲突
if
(
g_discoveryMutex
==
NULL
) {
g_discoveryMutex
=
MutexInit
();
if
(
g_discoveryMutex
==
NULL
) {
PublishCallback
(
info
->
publishId
,
PUBLISH_FAIL_REASON_UNKNOWN
,
NULL
,
cb
);
return
ERROR_FAIL
;
}
}
MutexLock
(
g_discoveryMutex
);
//
解除互斥锁
//InitService()
这个函数比较重要。参考
1.
初始化
InitService()
发现服务
if
(
InitService
()
!=
ERROR_SUCCESS
) {
SOFTBUS_PRINT
(
"[DISCOVERY] PublishService InitService fail\n"
);
PublishCallback
(
info
->
publishId
,
PUBLISH_FAIL_REASON_UNKNOWN
,
NULL
,
cb
);
MutexUnlock
(
g_discoveryMutex
);
return
ERROR_FAIL
;
}
//AddPublishModule()
函数,参考
2.
模块增加到
g_publishModule
PublishModule
*
findModule
=
AddPublishModule
(
moduleName
,
info
);
if
(
findModule
==
NULL
) {
SOFTBUS_PRINT
(
"[DISCOVERY] PublishService AddPublishModule fail\n"
);
PublishCallback
(
info
->
publishId
,
PUBLISH_FAIL_REASON_UNKNOWN
,
NULL
,
cb
);
MutexUnlock
(
g_discoveryMutex
);
return
ERROR_FAIL
;
}
//
注册
COAP
服务,参考
3.CoapRegisterDefualtService()
int
ret
=
ERROR_SUCCESS
;
if
(
info
->
capability
==
NULL
||
info
->
capabilityData
==
NULL
) {
(
void
)
CoapRegisterDefualtService
();
}
else
{
ret
=
DoRegistService
(
info
->
medium
);
}
MutexUnlock
(
g_discoveryMutex
);
//
这个
PublishCallback()
就很简单了,上面出现好多次了,初始化成功或者失败的回调函数。
if
(
ret
!=
ERROR_SUCCESS
) {
PublishCallback
(
info
->
publishId
,
PUBLISH_FAIL_REASON_UNKNOWN
,
findModule
,
cb
);
return
ERROR_FAIL
;
}
else
{
PublishCallback
(
info
->
publishId
,
ERROR_SUCCESS
,
findModule
,
cb
);
return
ERROR_SUCCESS
;
1.
初始化
InitService()
发现服务
}
}
Z
:
\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\
source\discovery_service
.
c
int
InitService
(
void
)
{
if
(
g_isServiceInit
!=
0
) {
//
全局变量
g_isServiceInit
:确认服务是否启动。如果其他模
块启动过,那么直接返回成功。
return
ERROR_SUCCESS
;
}
//
初始化
g_deviceInfo
结构体。参考
1.1.
初始化
g_deviceInfo
结构体,相关文件
【
common_info_manager.c
】
if
(
InitCommonManager
()
!=
0
) {
SOFTBUS_PRINT
(
"[DISCOVERY] InitService InitCommonManager fail\n"
);
DeinitService
();
return
ERROR_FAIL
;
}
//
分配内存,参考:
1.2.
初始化全局
g_publishModule
和
g_capabilityData
g_publishModule
=
calloc
(
1
,
sizeof
(
PublishModule
)
*
MAX_MODULE_COUNT
);
if
(
g_publishModule
==
NULL
) {
DeinitService
();
return
ERROR_NOMEMORY
;
}
g_capabilityData
=
calloc
(
1
,
MAX_SERVICE_DATA_LEN
);
if
(
g_capabilityData
==
NULL
) {
DeinitService
();
return
ERROR_NOMEMORY
;
}
//
软总线注册第一个监听函数
WifiEventTrigger()
,当接入网络时
trigger
//
注册
wifi Callback
,将
WifiEventTrigger()↓
函数,赋值给全局变量
g_wifiCallback
,参考
b.COAP
初始化
wifi
事件
RegisterWifiCallback
(
WifiEventTrigger
);
//COAP
初始化。参考
1.3.
初始化
COAP
协议服务,相关文件【
coap_service.c
】
int
ret
=
CoapInit
();
if
(
ret
!=
ERROR_SUCCESS
) {
SOFTBUS_PRINT
(
"[DISCOVERY] InitService CoapInit fail\n"
);
DeinitService
();
return
ret
;
}
printf
(
">>>>>%s:%d[Register WifiEventTring()]\n"
,
__FILE__
,
__LINE__
);
//
添加打
印调试
//COAP
写入消息队列,这样会触发上面
↑
消息回调函数,
WifiEventTrigger()
,这个函数比较重要,
TODO 1.4.
CoapWriteMsgQueue
(
UPDATE_IP_EVENT
);
//COAP
注册设备信息
ret
=
CoapRegisterDeviceInfo
();
if
(
ret
!=
ERROR_SUCCESS
) {
SOFTBUS_PRINT
(
"[DISCOVERY] InitService CoapRegisterDeviceInfo fail\n"
);
DeinitService
();
return
ret
;
1.1.
初始化
g_deviceInfo
结构体
}
g_isServiceInit
=
1
;
SOFTBUS_PRINT
(
"[DISCOVERY] InitService ok\n"
);
return
ERROR_SUCCESS
;
}
Z
:
\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\
source\common_info_manager
.
c
int
InitCommonManager
(
void
)
{
if
(
InitLocalDeviceInfo
()
!=
0
) {
//
初始化本地设备信息
SOFTBUS_PRINT
(
"[DISCOVERY] InitCommonManager fail\n"
);
return
ERROR_FAIL
;
}
return
ERROR_SUCCESS
;
}
================================================================================
================
int
InitLocalDeviceInfo
(
void
)
//
初始化本地设备信息
{
char
deviceId
[
DEVICEID_MAX_NUM
]
=
{
0
};
if
(
g_deviceInfo
!=
NULL
) {
//
初始化一个
g_deviceInfo
的结构体。包含本地设备的各种信
息。
memset_s
(
g_deviceInfo
,
sizeof
(
DeviceInfo
),
0
,
sizeof
(
DeviceInfo
));
}
else
{
g_deviceInfo
=
(
DeviceInfo
*
)
calloc
(
1
,
sizeof
(
DeviceInfo
));
if
(
g_deviceInfo
==
NULL
) {
return
ERROR_FAIL
;
}
}
g_deviceInfo
->
devicePort
= -
1
;
//
默认,
g_deviceInfo.
设备端口
-1
g_deviceInfo
->
isAccountTrusted
=
1
;
//
默认,
g_deviceInfo.
账户是可信的
unsigned int
ret
;
//
从文件获取设备
id
,这个函数还有好几层,就不继续深挖了。大体就是从
DEVICE_ID_FILE
文件中读
取。
//#define DEVICE_ID_FILE "/storage/data/softbus/deviceid"
ret
=
GetDeviceIdFromFile
(
deviceId
,
MAX_VALUE_SIZE
);
if
(
ret
!=
ERROR_SUCCESS
) {
SOFTBUS_PRINT
(
"[DISCOVERY] Get device fail\n"
);
return
ERROR_FAIL
;
}
#if defined(__LITEOS_M__) || defined(__LITEOS_RISCV__)
//g_deviceInfo.
设备的类型,
目前分为
L0
和
L1
g_deviceInfo
->
deviceType
=
L0
;
ret
=
(
unsigned int
)
strcpy_s
(
g_deviceInfo
->
deviceName
,
sizeof
(
g_deviceInfo
-
>
deviceName
),
L0_DEVICE_NAME
);
#else
g_deviceInfo
->
deviceType
=
L1
;
1.2.
初始化全局
g_publishModule
和
g_capabilityData
1.3.
初始化
COAP
协议服务
ret
=
(
unsigned int
)
strcpy_s
(
g_deviceInfo
->
deviceName
,
sizeof
(
g_deviceInfo
-
>
deviceName
),
L1_DEVICE_NAME
);
#endif
ret
|=
(
unsigned int
)
strcpy_s
(
g_deviceInfo
->
deviceId
,
sizeof
(
g_deviceInfo
-
>
deviceId
),
deviceId
);
//g_deviceInfo.
设备
id
ret
|=
(
unsigned int
)
strcpy_s
(
g_deviceInfo
->
version
,
sizeof
(
g_deviceInfo
-
>
version
),
"1.0.0"
);
//g_deviceInfo.
版本号
if
(
ret
!=
0
) {
return
ERROR_FAIL
;
}
SOFTBUS_PRINT
(
"[DISCOVERY] InitLocalDeviceInfo ok\n"
);
return
ERROR_SUCCESS
;
}
Z
:
\harmony110\foundation\communication\softbus_lite\discovery\discovery_service\
source\discovery_service
.
c
//
首先,
discovery_service.c
开头定义了这两个全局变量。
PublishModule
*
g_publishModule
=
NULL
;
//
存放发布的模块
char *
g_capabilityData
=
NULL