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🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请看下图提示:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值