往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- OpenHarmony之分布式软总线coap头文件& coap组包分析
- OpenHarmony之分布式软总线discovery/coap/source/coap_socket.c
- OpenHarmony之分布式软总线nstackx_device.c(一)
- OpenHarmony之分布式软总线nstackx_device.c(二)
- OpenHarmony之分布式软总线discovery_service.h头文件
- OpenHarmony之分布式软总线discovery_service.c(一)
- OpenHarmony之分布式软总线discovery_service.c(二)
- OpenHarmony之分布式软总线discovery_service.c(三)
- OpenHarmony之分布式软总线discovery_service.c(四)
- OpenHarmony之分布式软总线discovery_service.c(五)
- 持续更新中……
/*
函数功能: 添加发布模块
函数参数:
packageName:
info : 待发布信息
函数返回值: 添加成功返回添加之后相应g_publishModule中模块, 否则返回NULL
详细:
1.检查packageName,g_publishModule,info参数
2. 检查发布信息datalen是否大于最大数据长度
3.查找已存在的服务模块,如果服务已经发布,那么返回NULL
4.查找第一个未使用的
5.第一个 used ==0 设置功能对应的位图
6.将此标记used设置为1,代表已经被使用
7.分配存储功能数据的空间,并初始化为1
8.分配不成功,全部设置为0,并返回。
9.设置功能数据长度,并将待发布的功能信息添加到发布模块中
10.添加失败,是否分配的数据空间,并将参数重置(设为0)
11.设置发布模块中媒介,发布id,package名,失败需要释放之前分配的空间,并且将g_publishModule[i]每一项设置为0恢复状态, g_publishModule[i].capabilityData = NULL 防止产生野指针
*/
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;
}
//查找已存在的服务模块,如果服务已经发布,那么返回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;
}
//第一个 used ==0 设置功能对应的位图
if (ParseCapability(info->capability, &g_publishModule[i].capabilityBitmap)) {
return NULL;
}
//将此标记used设置为1,代表已被使用
g_publishModule[i].used = 1;
//分配存储功能数据的空间,并初始化为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;
}
//设置发布模块中媒介,发布id,package名
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));
//失败需要释放之前分配的空间,并且将g_publishModule[i]每一项设置为0恢复状态
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;
}
/*
函数功能:获取功能和功能数据
函数参数:
capabilityBitmap : 用来存储获取到的功能位图
capabilityData: 用来存储获取到的功能数据
datalen : 数据长度
函数返回值: 成功返回0, 否则返回非零
详细:
1.检查各个参数
2.获取设备信息
3.sprintf_s 设备接口 写入 字符串,返回字符串长度 "port:{local->devicePort}"存到capabilityData
4.遍历g_publishModule,如果已经使用那么就获取该模块功能和数据
5.左移相应位数 :"hicall"、"profile"、"castPlus"、"homevisionPic"、"aaCapability"、"dvKit"、"ddmpCapability
6.使用的模块加一
7.将缓冲区指针向前+len,datalen-len, "port:{local->devicePort}g_publishModule[i].capabilityData" 存入capabilityData
*/
int GetCapablityAndData(unsigned int capabilityBitmap[], char* capabilityData, int dataLen)
{
if (g_publishModule == NULL || capabilityBitmap == NULL || capabilityData == NULL) {
return ERROR_INVALID;
}
//总长度
int len = 0;
//获取设备信息
DeviceInfo *local = GetCommonDeviceInfo();
if (local == NULL) {
return ERROR_FAIL;
}
//设备接口 写入 字符串,返回字符串长度 "port:{local->devicePort}" 存到capabilityData
int ret = sprintf_s(capabilityData, dataLen, "port:%d,", local->devicePort);
if (ret == -1) {
return ERROR_FAIL;
}
//长度+ret
len += ret;
int moduleUsed = 0; //记录使用模块的个数
//遍历g_publishModule,如果已经使用那么就获取该模块功能和数据
for (int i = 0; i < MAX_MODULE_COUNT; i++) {
if (g_publishModule[i].used == 0) {
continue;
}
#ifdef COAP_DEBUG
SOFTBUS_PRINT("[DISCOVERY] Module[%d].capabilityBitmap = %d, capabilityData = %s\n", i,
g_publishModule[i].capabilityBitmap, g_publishModule[i].capabilityData);
#endif
//左移相应位数 :"hicall"、"profile"、"castPlus"、"homevisionPic"、"aaCapability"、"dvKit"、"ddmpCapability"
capabilityBitmap[0] |= (0x1 << g_publishModule[i].capabilityBitmap);
//使用的模块加一
moduleUsed++;
//该功能没有数据
if (g_publishModule[i].capabilityData == NULL) {
continue;
}
//moduleUsed == 最大模块数 ???
if (moduleUsed == MAX_MODULE_COUNT) {
//将缓冲区指针向前+len,datalen-len, "port:{local->devicePort}g_publishModule[i].capabilityData" 存入capabilityData
ret = sprintf_s(capabilityData + len, dataLen - len, "%s",
g_publishModule[i].capabilityData);
} else {
ret = sprintf_s(capabilityData + len, dataLen - len, "%s,",
g_publishModule[i].capabilityData);
}
if (ret == -1) {
return ERROR_FAIL;
}
//加上长度
len += ret;
}
return ERROR_SUCCESS;
}
*
函数功能:服务发布成功或失败调用回调函数
函数参数:
publishId: 服务发布id
result: 服务发布结果(成功或失败)
findModule:
IPublishCallback: 服务发布回调函数
函数返回值:无
详细:
1.如果结果是发布成功,那么调用服务发布成功的回调函数
2.发布失败先释放已经分配的资源,接着调用发布失败的回调函数
*/
void PublishCallback(int publishId, int result,
PublishModule *findModule, const IPublishCallback *cb)
{
SOFTBUS_PRINT("[DISCOVERY] PublishCallback publishId=%d, result=%d\n", publishId, result);
//如果结果是发布成功,那么调用服务发布成功的回调函数
if (result == ERROR_SUCCESS) {
if (cb->onPublishSuccess != NULL) {
cb->onPublishSuccess(publishId);
}
//发布失败
} else {
if (findModule != NULL) {
if (findModule->capabilityData != NULL) {
free(findModule->capabilityData);
findModule->capabilityData = NULL;
}
memset_s(findModule, sizeof(PublishModule), 0, sizeof(PublishModule));
}
//调用服务发布失败的回调函数
if (cb->onPublishFail != NULL) {
cb->onPublishFail(publishId, result);
}
}
}
/*
函数功能: 注册服务
函数参数 :
medium : 媒介(wifi)
*/
int DoRegistService(int medium)
{
//功能数据不为空,分配相应空间
if (g_capabilityData != NULL) {
memset_s(g_capabilityData, MAX_SERVICE_DATA_LEN, 0, MAX_SERVICE_DATA_LEN);
} else {
return ERROR_NOMEMORY;
}
//功能位图
unsigned int capabilityBitmap[MAX_CAPABILITY_NUM] = {0};
//获取功能和功能数据capabilityBitmap ,capabilityBitmap
if (GetCapablityAndData(capabilityBitmap, capabilityBitmap, MAX_SERVICE_DATA_LEN) != ERROR_SUCCESS) {
SOFTBUS_PRINT("[DISCOVERY] DoRegistService GetCapablityAndData fail\n");
return ERROR_CAPABLITY_FAIL;
}
int ret;
switch (medium) {
case COAP:
//注册服务
ret = CoapRegistService(capabilityBitmap, MAX_CAPABILITY_NUM, g_capabilityData);
break;
default:
ret = ERROR_NOT_SUPPORT_MEDIUM;
break;
}
return ret;
}
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请看下图提示: