OpenHarmony之分布式软总线discovery_service.c(一)

100 篇文章 1 订阅
100 篇文章 0 订阅

往期知识点记录:

前言

在上篇博客中已经分析了discovery_service.h头文件,在这个头文件中声明了与设备服务发布相关功能和数据结构。

服务发布

discovery_service.c实现了轻量级设备端的服务发布功能。 首先它的入口函数为PublishService,这个函数实现服务发布的总流程。 服务发布函数关系已经在 discover_service.c函数调用关系 给出了图示。

首先介绍发布模块的结构信息,它包含服务模块的属性:

/*
  发布模块结构
  publishId : 服务发布ID
  medium : 服务发布的媒介(wifi 蓝牙..)
  capabilityBitmap : 对应的功能位图
  capabilityData : 服务发布的功能数据
  dataLength : 数据长度
*/
typedef struct {
  char package[MAX_PACKAGE_NAME];
  int publishId;
  unsigned short medium;
  unsigned short capabilityBitmap;
  char *capabilityData;
  unsigned short dataLength;
  unsigned short used;
} PublishModule;

下面从入口函数开始分析代码 PublishService

/*
    函数功能: 发布服务
    函数参数: 
            moduleName : 
            info : 发布的服务信息
            IPublishCallback: 服务发布成功或者失败的回调函数 发布成功后会创建会话,等待发现端连接
    函数返回值: 成功返回0,否则返回非零
    详细:  
            1.检查权限和参数是否满足条件
            2.检查moduleName和发布信息中id 和数据长度是否满足条件
            3.如果上述条件不满足条件,调用发布失败回调函数
            4.初始化发布锁, 之后的任何失败都会调用发布失败的回调函数,并且打印失败信息
            5.加锁, 因为发布过程中的会改变很多共享变量,如:g_publishModule 所以需要保持发布的互斥性。使得服务只能一个一个的先后发布
            6.初始化服务,这个过程初始化发布服务所需的功能,比如为发布模块,发布服务数据,coap初始化等
            7.添加发布模块,所有的已发布服务的信息都存储在g_publishModule,所以需要判断能否添加一个服务模块
            8.注册服务,如果没有提供详细的服务, 就注册默认服务,否则注册提供的服务
            9.释放锁
            10.注册成功就调用发布成功的回调函数
*/
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;
    }
    //检查moduleName和发布信息中id和数据长度是否满足条件
    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;
    }
    //当前media只支持WIFI -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;
    }
}

UnPublishService实现了取消已经发布的服务的功能。 与发布服务函数是discovery_service.c两个主要的函数:

/*
        函数功能:取消已经发布的服务
        函数参数:
                moduleName : 模块名
                publishId  : 发布id
        函数返回值: 成功返回0,否则非零
        详细: 
                1.检查权限和发布id,模块名,发布锁参数
                2.加锁,与发布服务一样,同样保持互斥性
                3. 通过moduleName,publishId找到相应的模块
                4. 释放存储功能数据的空间,并且将相应的发布模块属性置为0
                5. 删除之后,重新注册服务,更新提供的服务 
                5.释放锁
*/
int UnPublishService(const char* moduleName, int publishId)
{
    //检查权限
    if (SoftBusCheckPermission(SOFTBUS_PERMISSION) != 0) {
        SOFTBUS_PRINT("[DISCOVERY] No permission\n");
        return ERROR_FAIL;
    }
    //检查各参数
    if (moduleName == NULL || publishId <= 0 || g_discoveryMutex == NULL) {
        SOFTBUS_PRINT("[DISCOVERY] UnPublishService invliad para\n");
        return ERROR_INVALID;
    }
    MutexLock(g_discoveryMutex); //加锁
    //返回要找的模块
    PublishModule *findModule = FindExistModule(moduleName, publishId);
    //如果没有相应的服务模块
    if (findModule == NULL) {
        SOFTBUS_PRINT("[DISCOVERY] UnPublishService get module fail\n");
        MutexUnlock(g_discoveryMutex);
        return ERROR_NONEXIST;
    }
    //释放存储功能服务数据的空间
    if (findModule->capabilityData != NULL) {
        free(findModule->capabilityData);
    }
    //将该服务模块重置为0 ,used = 0
    unsigned short medium = findModule->medium;
    memset_s(findModule, sizeof(PublishModule), 0, sizeof(PublishModule));
    //删除之后,重新注册服务,更新了提供的服务
    int ret = DoRegistService(medium);
    if (ret != ERROR_SUCCESS) {
        SOFTBUS_PRINT("[DISCOVERY] UnPublishService DoRegistService fail, error =  %d\n", ret);
        MutexUnlock(g_discoveryMutex);
        return ret;
    }
    MutexUnlock(g_discoveryMutex);
    SOFTBUS_PRINT("[DISCOVERY] UnPublishService ok\n");
    return ret;
}

总结

本文分析了发布服务函数和取消已发布服务函数,它们所调用其他功能函数在之后进行分析。

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请看下图提示:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值