分布式软总线/discovery/discovery_service.c代码解读

知识总结

  1. 互斥锁: 用于保证共享数据操作的完整性,用于标记任意时刻,只有一个线程能够访问该对象,对该对象进行修改
    在修改或创建关键数据时,我们常常申请互斥锁来保护数据的一致性,保证功能的正常运行如函数PublishService()函数中对数据进行操作时先申请的互斥锁,修改完毕后释放

总体概述

同样是顶层模块的封装函数调用函数,通过函数PublishService函数来发现外部设备将发布模式写入本地;还有服务的初始化和删除模块;重要的WiFi接入时的触发函数模块;一系列信息的转移和安全赋值模块

代码详解

  1. ConfigDeviceInfo结构体用于存储基本设置所需的信息
    在这里插入图片描述
  2. 发布模式的结构体包括id和包裹等信息
    在这里插入图片描述
  3. 获取设备的类型(在g_devMap中)
    在这里插入图片描述
  4. 两个函数将deviceInfo中的信息存储到Info(ConfiDevice)中
    这里两个函数的作用一样但是参数的位置和名字不一样,应该是在不同的地方发挥作用,一个是阻塞状态下,一个是服务开启失败后的数据恢复
    在这里插入图片描述
    在这里插入图片描述
  5. 设置通用设备信息
    首先调用函数查看软总线是否允许接入->将deviceInfo.key对应不同的value存入localDev中–>成功则更新CommonDeviceInfo否则调用RecoverCommonDeviceInfo函数进行信息还原
    在这里插入图片描述
  6. 重要函数WiFi接入的触发函数
    函数的主要功能:获取IP地址并完成信息登记和软总线服务的初始和启动
    在这里插入图片描述
  7. 初始化服务的结束与开启函数
//结束初始化服务
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;
}
  1. 查询包裹名和发布id对应的g_publishModule
    在这里插入图片描述
  2. 解析capability函数
    在这里插入图片描述
  3. 添加新的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;
}

  1. 开启登记服务将信息存入g_capabilityData中
    在这里插入图片描述
  2. 重要函数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;
    }
}

感谢大家的阅读点赞和评论!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

国家一级假勤奋研究牲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值