知识总结
- 互斥锁: 用于保证共享数据操作的完整性,用于标记任意时刻,只有一个线程能够访问该对象,对该对象进行修改
在修改或创建关键数据时,我们常常申请互斥锁来保护数据的一致性,保证功能的正常运行如函数PublishService()函数中对数据进行操作时先申请的互斥锁,修改完毕后释放
总体概述
同样是顶层模块的封装函数调用函数,通过函数PublishService函数来发现外部设备将发布模式写入本地;还有服务的初始化和删除模块;重要的WiFi接入时的触发函数模块;一系列信息的转移和安全赋值模块
代码详解
- ConfigDeviceInfo结构体用于存储基本设置所需的信息
- 发布模式的结构体包括id和包裹等信息
- 获取设备的类型(在g_devMap中)
- 两个函数将deviceInfo中的信息存储到Info(ConfiDevice)中
这里两个函数的作用一样但是参数的位置和名字不一样,应该是在不同的地方发挥作用,一个是阻塞状态下,一个是服务开启失败后的数据恢复
- 设置通用设备信息
首先调用函数查看软总线是否允许接入->将deviceInfo.key对应不同的value存入localDev中–>成功则更新CommonDeviceInfo否则调用RecoverCommonDeviceInfo函数进行信息还原
- 重要函数WiFi接入的触发函数
函数的主要功能:获取IP地址并完成信息登记和软总线服务的初始和启动
- 初始化服务的结束与开启函数
//结束初始化服务
int DeinitService(void)
{
//传入flag=0停止软总线的工作StopBus()
int ret = BusManager(0);
if (ret != ERROR_SUCCESS) {
SOFTBUS_PRINT("[DISCOVERY] DeinitService BusManager(0) fail\n");
}
//将赋过值的全局标识进行复原
if (g_publishModule) {
free(g_publishModule);
g_publishModule = NULL;
}
if (g_capabilityData) {
free(g_capabilityData);
g_capabilityData = NULL;
}
//清除本地数据关闭服务
ret = CoapDeinit();
if (ret != ERROR_SUCCESS) {
SOFTBUS_PRINT("[DISCOVERY] DeinitService CoapDeinit fail\n");
}
RegisterWifiCallback(NULL);//g_wifiCallback = callback;
DeinitCommonManager();//free(g_deviceInfo);
g_isServiceInit = 0;//是否初始化的标识置为0
return ERROR_SUCCESS;
}
//初始化服务包括初始化通用管理器,WiFi服务的监听和启动,coap服务的初始化
int InitService(void)
{
if (g_isServiceInit != 0) {
return ERROR_SUCCESS;
}
if (InitCommonManager() != 0) {
SOFTBUS_PRINT("[DISCOVERY] InitService InitCommonManager fail\n");
DeinitService();
return ERROR_FAIL;
}
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函数指针得到其值作为参数传入
//获取IP地址并完成登记和软总线的启动
RegisterWifiCallback(WifiEventTrigger);
//coap协议服务初始化
int ret = CoapInit();
if (ret != ERROR_SUCCESS) {
SOFTBUS_PRINT("[DISCOVERY] InitService CoapInit fail\n");
DeinitService();
return ret;
}
//将消息写入队列中
CoapWriteMsgQueue(UPDATE_IP_EVENT);
ret = CoapRegisterDeviceInfo();
if (ret != ERROR_SUCCESS) {
SOFTBUS_PRINT("[DISCOVERY] InitService CoapRegisterDeviceInfo fail\n");
DeinitService();
return ret;
}
g_isServiceInit = 1;
SOFTBUS_PRINT("[DISCOVERY] InitService ok\n");
return ERROR_SUCCESS;
}
- 查询包裹名和发布id对应的g_publishModule
- 解析capability函数
- 添加新的g_publishModule并返回对应的结构体指针的函数
具体流程:
a. 根据packageName和publishId返回本地存储好的g_publishModule
b. 根据函数FindModule判断是否还有空余的结点有则往下,没有则返回NULL
c. 将参数info通过memset_s和memcpy_s写入g_publishModule结构体中并返回
//添加新的g_publishModule并返回对应的结构体指针
PublishModule *AddPublishModule(const char *packageName, const PublishInfo *info)
{
if (packageName == NULL || g_publishModule == NULL || info == NULL) {
return NULL;
}
if (info->dataLen > MAX_SERVICE_DATA_LEN) {
return NULL;
}
if (FindExistModule(packageName, info->publishId) != NULL) {
return NULL;
}
if (FindFreeModule() == NULL) {
return NULL;
}
int ret;
for (int i = 0; i < MAX_MODULE_COUNT; i++) {
if (g_publishModule[i].used == 1) {
continue;
}
if (ParseCapability(info->capability, &g_publishModule[i].capabilityBitmap)) {
return NULL;
}
g_publishModule[i].used = 1;
g_publishModule[i].capabilityData = calloc(1, info->dataLen + 1);
if (g_publishModule[i].capabilityData == NULL) {
memset_s(&g_publishModule[i], sizeof(g_publishModule[i]), 0, sizeof(g_publishModule[i]));
return NULL;
}
g_publishModule[i].dataLength = info->dataLen + 1;
ret = memcpy_s(g_publishModule[i].capabilityData,
g_publishModule[i].dataLength,
info->capabilityData, info->dataLen);
if (ret != 0) {
free(g_publishModule[i].capabilityData);
g_publishModule[i].capabilityData = NULL;
memset_s(&g_publishModule[i], sizeof(g_publishModule[i]), 0, sizeof(g_publishModule[i]));
return NULL;
}
g_publishModule[i].medium = info->medium;
g_publishModule[i].publishId = info->publishId;
ret = memcpy_s(g_publishModule[i].package, MAX_PACKAGE_NAME, packageName, strlen(packageName));
if (ret != 0) {
free(g_publishModule[i].capabilityData);
g_publishModule[i].capabilityData = NULL;
memset_s(&g_publishModule[i], sizeof(g_publishModule[i]), 0, sizeof(g_publishModule[i]));
return NULL;
}
return &g_publishModule[i];
}
return NULL;
}
- 开启登记服务将信息存入g_capabilityData中
- 重要函数PublishService
函数作用: 发现外部设备并准备进行连接和通讯服务
具体方式: 首先调用函数SoftBusCheckPermission查看是否有软总线的许可权限,然后检查各种参数的正确,再申请互斥锁保证数据的同步,申请成功后通过函数AddPublishModule将发布模式添加到g_PublishModule中,最后调用回调函数PublishCallback返回成功信息
//discovery通过该函数来发现外部设备
int PublishService(const char *moduleName, const struct PublishInfo *info, const struct IPublishCallback *cb)
{
//权限检查
if (SoftBusCheckPermission(SOFTBUS_PERMISSION) != 0 || info == NULL || cb == NULL) {
SOFTBUS_PRINT("[DISCOVERY] PublishService invalid para(info or cb)\n");
return ERROR_INVALID;
}
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;
}
//是否为COAP协议
if (info->medium != COAP) {
PublishCallback(info->publishId, PUBLISH_FAIL_REASON_NOT_SUPPORT_MEDIUM, NULL, cb);
return ERROR_INVALID;
}
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);
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;
}
//添加新的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;
}
int ret = ERROR_SUCCESS;
if (info->capability == NULL || info->capabilityData == NULL) {
(void)CoapRegisterDefualtService();
} else {
ret = DoRegistService(info->medium);
}
//释放互斥锁
MutexUnlock(g_discoveryMutex);
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;
}
}
感谢大家的阅读点赞和评论!