OpenHarmony之分布式软总线nstackx_common.c分析

69 阅读4分钟

前言

上篇coap_service.c代码中基本上每个接口函数都调用了nstackx_common.c中的接口,最终nstackx_common.c中的接口函数再调用coap_discover.c中的接口函数。所以coap_service.c中的接口函数是对外提供的顶层接口,分析过程也是从顶层宏观调用到下层实现细节。

nstackx_common.c分析

首先,初始过程中有三种状态:初始化开始,初始化进行中,初始化完成。

enum {
  NSTACKX_INIT_STATE_START = 0,
  NSTACKX_INIT_STATE_ONGOING,
  NSTACKX_INIT_STATE_DONE,
};

其中使用一个8位无符号数来表示初始化过程中状态的变化static uint8_t g_nstackInitState = NSTACKX_INIT_STATE_START;

初始化函数NSTACKX_Init

/*
    函数功能: 为coao发现前期初始化
    函数参数: 无
    函数返回值: 成功或者已经初始化返回0,否则返回非零
    详细:
        1.首先设置初始化状态为初始化正在进行
        2.调用cJSON_InitHooks为cJSON提供malloc, realloc和free函数(使用默认malloc,free)
        3.调用CoapInitDiscovery,初始化coap发现的参数和结构(coap socket  g_serverFd  message id,coap wifi 事件,消息队列线程,coap监听线程)
        4.上述过程成功之后,要将初始状态设置初始化完成,否则就需要调用NSTACKX_Deinit恢复为原始状态
*/
int NSTACKX_Init()
{
    int ret;
    if (g_nstackInitState != NSTACKX_INIT_STATE_START) {
        return NSTACKX_EOK;
    }
    g_nstackInitState = NSTACKX_INIT_STATE_ONGOING;
    //为cJSON提供malloc, realloc和free函数
    cJSON_InitHooks(NULL);
    ret = CoapInitDiscovery();
    if (ret != NSTACKX_EOK) {
        goto L_ERR_INIT;
    }
    g_nstackInitState = NSTACKX_INIT_STATE_DONE;
    return NSTACKX_EOK;
//如果上述一步出错那么就需要恢复为原始状态
L_ERR_INIT:
    ret = NSTACKX_Deinit();
    if (ret != NSTACKX_EOK) {
        SOFTBUS_PRINT("[DISCOVERY] deinit fail\n");
    }
    return NSTACKX_EFAILED;
}

DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到以下知识点。

`欢迎大家关注公众号<程序猿百晓生>,可以了解到以下知识点。`
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......

反初始化NSTACKX_Deinit

/*
    函数功能: 反初始化,释放各种资源和数据
    函数参数: 无
    函数返回值:成功返回0,否则返回非零
    详细:
        1. 首先先判断初始状态g_nstackInitState,如果为NSTACKX_INIT_STATE_START,表示根本没有初始化过
        2. 调用CoapDeinitDiscovery,释放Coap发现所分配的资源和数据(关闭coap监听线程,销毁wifi事件,释放socket套接字)
        3. 清除本地信息(本地设备信息,网络接口信息,网络类型)
        4. 最后所有资源数据释放之后,将初始化状态设置为原始状态NSTACKX_INIT_STATE_START
*/
int NSTACKX_Deinit(void)
{
    if (g_nstackInitState == NSTACKX_INIT_STATE_START) {
        return NSTACKX_EOK;
    }
    int ret = CoapDeinitDiscovery();
    if (ret != NSTACKX_EOK) {
        return ret;
    }
    ClearLocalData();
    g_nstackInitState = NSTACKX_INIT_STATE_START;
    return NSTACKX_EOK;
}

/*
    函数功能: 注册设备
    函数参数: 
            1.localDeviceInfo: 本地设备信息
            2. deviceHash : 设备hash
    函数返回值: 成功返回0,否则非零
    详细:
        1. 判断是否已经初始化完毕了
        2、 判断本地设备信息是否为空
        3、 使用localDeviceInfo配置本地设备信息g_localDeviceInfo
        4、 设置设备Hash
*/
int NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo *localDeviceInfo, uint64_t deviceHash)
{
    //如果还没初始化完成
    if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
        return NSTACKX_EFAILED;
    }
    //本地设备信息为空
    if (localDeviceInfo == NULL) {
        return NSTACKX_EINVAL;
    }
    //配置本地设备信息
    if (ConfigureLocalDeviceInfo(localDeviceInfo) != NSTACKX_EOK) {
        return NSTACKX_EINVAL;
    }
    //设置设备的哈希值
    SetDeviceHash(deviceHash);
    return NSTACKX_EOK;
}

/*
    函数功能: 初始化之后需要去设置设备功能
    函数参数: 
            1.capabilityBitmapNum : 功能数量
            2. capabilityBitmap : 保存了功能位图
    函数返回值: 成功返回0,否则返回非零
    详细 : 
            1. 判断是否已经初始化完毕了
            2. 判断功能数量是否大于设备所可以拥有的最大功能数量
            3. 调用RegisterCapability,去设置设备功能
*/
int NSTACKX_RegisterCapability(uint32_t capabilityBitmapNum, const uint32_t capabilityBitmap[])
{
    if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
        return NSTACKX_EFAILED;
    }
    if (capabilityBitmapNum > NSTACKX_MAX_CAPABILITY_NUM) {
        return NSTACKX_EINVAL;
    }
    if (RegisterCapability(capabilityBitmapNum, capabilityBitmap) != NSTACKX_EOK) {
        return NSTACKX_EINVAL;
    }
    return NSTACKX_EOK;
}

/*
    函数功能:设置设备服务数据
    函数参数: 
            serviceData: 服务数据
    函数返回值: 成功返回0,否则返回非零
    详细:
        1. 检查服务数据是否为空
        2. 检查设备是否已经初始化完毕
        3. 检查服务数据长度是否大于最大服务数据长度
        4. 调用RegisterServiceData,设置g_localDeviceInfo中的serviceData
*/
int NSTACKX_RegisterServiceData(const char* serviceData)
{
    if (serviceData == NULL) {
        return NSTACKX_EINVAL;
    }
    //如果设备初始化过了
    if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
        return NSTACKX_EFAILED;
    }
    //服务数据长度
    unsigned int serviceLen = strlen(serviceData);
    if (serviceLen >= NSTACKX_MAX_SERVICE_DATA_LEN) {
        return NSTACKX_EINVAL;
    }
    if (RegisterServiceData(serviceData, serviceLen + 1) != NSTACKX_EOK) {
        return NSTACKX_EINVAL;
    }
    return NSTACKX_EOK;
}