LiteOS之Lwm2m对接华为云流程分析(上)

星辰27 发表于 2021/02/04 11:02:10 2021/02/04
【摘要】 本文主要分析了一下LiteOS中使用LWm2m协议对接华为云的流程,为保证流程完整性部分内容有所参考于其他博文,希望对你有所帮助。

声明:为使得开发者便于阅读完整对接流程,部分内容参考于该文https://bbs.huaweicloud.com/blogs/149354 其中1-2的大多数摘录于该文章。

1 概述

       为了适应各种使用lwm2m接入华为OC的模式,特采用该架构接口,对上提供应用所需的接口,对下允许接入方式的灵活适应。oc_lwm2m_al是处理使用lwm2m协议对接华为OC的流程摘要对于应用程序开发者而言,无需关注对接流程的实现细节,只需需要该模块提供的API就可以.OClwm2m AL层,允许使用流程进行对接,也可以使用NB芯片内置的流程进行对接。API接口声明在<oc_lwm2m_al.h>中,使用相关的接口需要包含该头文件。

2 配置并连接相关结构体介绍

        对接服务器的所有信息保存在结构体oc_config_param_t中,其定义在oc_lwm2m_al.h中,如下:

typedef struct
{
    en_oc_boot_strap_mode_tboot_mode;       ///< bootmode,if boot client_initialize, then the bs must be set
    oc_server_tboot_server;     ///< which will be used by the bootstrap, if not, set NULL here
    oc_server_tapp_server;      ///< if factory or smart boot, must be set here 
    fn_oc_lwm2m_msg_dealrcv_func;        ///< receive function caller here
    void *usr_data;        ///< used for the user
}oc_config_param_t;
        其中boot_mode是对接模式,对应华为平台的三种模式,具体如下:

typedef enum
{
    en_oc_boot_strap_mode_factory = 0,
    en_oc_boot_strap_mode_client_initialize,
    en_oc_boot_strap_mode_sequence,
} en_oc_boot_strap_mode_t;
        app_server参数是服务器信息,参数中包括设备标识符,服务器地址,端口,psk_id:DTLS使用,不用为null。具体定义如下:

typedef struct
{
    char *ep_id;                  ///< endpoint identifier, which could be recognized by the server
    char *address;                ///< server address,maybe domain name
    char *port;                   ///< server port
    char *psk_id;                 ///< server encode by psk, if not set NULL here
    char *psk;
    int   psk_len;
} oc_server_t;

         rcv_func是某些函数的函数指针,当设备接收到lwm2m消息后回调:


typedef int (*fn_oc_lwm2m_msg_deal)(void *usr_data, en_oc_lwm2m_msg_t type, void *msg, int len);

        在配置结构体完成之后,调用配置函数进行配置并连接,API如下:

/**
 * @brief the application use this function to configure the lwm2m agent
 * @param[in] param, refer to oc_config_param_t
 * @return  the context, while NULL means failed
 */
void* oc_lwm2m_config(oc_config_param_t *param);
        函数参数很清楚,将存放对接信息的结构体指针对准即可,其中handle是oc lwm2m handle指针,后续使用。

int oc_lwm2m_config( oc_config_param_t *param)  //xingli 配置函数进行配置并链接
{
    int ret = (int)en_oc_lwm2m_err_system;
    if ((NULL != s_oc_lwm2m_ops.opt) && (NULL != s_oc_lwm2m_ops.opt->config))
    {
        if(NULL != param)
        {
            ret = s_oc_lwm2m_ops.opt->config(param);
        }
        else
        {
            ret = (int)en_oc_lwm2m_err_parafmt;
        }
    }
    return ret;
}

       当确定运行到oc_lwm2m_config函数之后进入进行配置,首先确定en_oc_lwm2m_err_system,系统植入是否存在错误,可能未安装。然后确定lwM2M实现方法指针是否为空,查看配置信息是否为空,就会走到结构体oc_config_param_t ;里面包括一些诸如对接模式以及服务器的相关信息,如果他不为空,则使用其进行配置。

        接下来的上报数据,首先依旧是检查系统是否存在问题,接下来接下来判断lwM2M实现方法指针是否为空,接下来检查上报数据函数是否为空。

int oc_lwm2m_report(char  *buf, int len, int timeout)
{
    int ret = (int)en_oc_lwm2m_err_system;

    if ((NULL != s_oc_lwm2m_ops.opt) && (NULL != s_oc_lwm2m_ops.opt->report))
    {
        ret = s_oc_lwm2m_ops.opt->report(buf, len, timeout);
    }
    return ret;
}

3 lwm2m对接流程开发

        关于开发基于lwm2m的对接OC的流程,应该实现三个基本功能:config 、report、deconfig。配置完成和服务器之间的握手(OC称为设备上线);报告使用上报应用程序的数据; deconfig开发人员调用oc_lwm2m_register将相关的方法注册到oc_lwm2m_agent,供应用程序开发者调用。相关的使用说明参考oc_lwm2m_al.h文件;具体实现可以参考boudica150_oc.c文件关于boudica150的相关实现。

对接华为云平台可以分为两种方式,可以在文件夹iot_link-> oc-> oc_lwm2m下的oc_lwm2m.mk中进行宏定义开关使能决定对接方式。具体如下:

ifeq ($(CONFIG_OCLWM2M_ENABLE), y)
    C_SOURCES += $(iot_link_root)/oc/oc_lwm2m/oc_lwm2m_al/oc_lwm2m_al.c             
    C_INCLUDES += -I $(iot_link_root)/oc/oc_lwm2m/oc_lwm2m_al
    ifeq ($(CONFIG_OCLWM2MTINY_ENABLE), y)
        include $(iot_link_root)/oc/oc_lwm2m/atiny_lwm2m/atiny_lwm2m.mk
    else ifeq ($(CONFIG_BOUDICA150_ENABLE),y)
        include $(iot_link_root)/oc/oc_lwm2m/boudica150_oc/boudica150_oc.mk            
    endif
    
    ifeq ($(CONFIG_OCLWM2M_DEMO_DTLS_ENABLE),y)
        C_SOURCES += $(iot_link_root)/oc/oc_lwm2m/oc_lwm2m_al/oc_dtls_lwm2m_demo.c     
    else ifeq ($(CONFIG_OCLWM2M_DEMO_ENABLE),y)
        C_SOURCES += $(iot_link_root)/oc/oc_lwm2m/oc_lwm2m_al/oc_lwm2m_demo.c                  
    endif
        
endif
         首先来看一下函数整体的调用关系,主要分为两部分,初始化以及用户调用API上传数据。
1.png
        在植入传感器的博文中讲过,当点击开发板重置按键之后,从操作系统LiteOS启动文件开始执行,调用main函数,main函数中会执行link_test函数,其入口函数为link_main,如下所示。

int link_main(void *args)
{
    ///< install the RTOS kernel for the link
    if(s_link_start)
    {
       return -1;
    }
    s_link_start =1;
    (void)osal_init();
    LINK_LOG_DEBUG("linkmain:%s",linkmain_version());
#ifdef CONFIG_STIMER_ENABLE
    #include <stimer.h>
    stimer_init();
#endif
#ifdef CONFIG_SHELL_ENABLE
    #include <shell.h>
    shell_init();
#endif
    /* add loader code here */
#ifdef CONFIG_OTA_ENABLE
    #include <ota_init.h>
    ota_init();
#endif
///< install the driver framework
#ifdef CONFIG_DRIVER_ENABLE
    #include <driver.h>
    ///< install the driver framework for the link
    (void)los_driv_init();
#endif
///< install the at framework
#ifdef CONFIG_AT_ENABLE
    #include <at.h>
    (void)at_init();
#endif
///< install the cJSON, for the oc mqtt agent need the cJSON
#ifdef CONFIG_CJSON_ENABLE
    #include <cJSON.h>
    cJSON_Hooks  hook;
    hook.free_fn = osal_free;
    hook.malloc_fn = osal_malloc;
    cJSON_InitHooks(&hook);
#endif
//////////////////////////  TCPIP PROTOCOL /////////////////////////////////////
#ifdef CONFIG_TCPIP_AL_ENABLE
    #include <sal.h>
    (void)link_tcpip_init();
#endif
//////////////////////////  DTLS PROTOCOL  /////////////////////////////////////
#ifdef CONFIG_DTLS_AL_ENABLE
    #include <dtls_al.h>
    (void)dtls_al_init();
#endif
//////////////////////////  MQTT PROTOCOL  /////////////////////////////////////
#ifdef CONFIG_MQTT_AL_ENABLE
    #include <mqtt_al.h>
    mqtt_al_init();
#endif
//////////////////////////  COAP PROTOCOL  /////////////////////////////////
#ifdef CONFIG_COAP_AL_ENABLE
    #include <coap_al.h>
    (void)coap_al_init();
#endif
//////////////////////////  LWM2M PROTOCOL  /////////////////////////////////
#ifdef CONFIG_LWM2M_AL_ENABLE
    #include <lwm2m_al.h>
    (void)lwm2m_al_init();
#endif
//////////////////////////  OC MQTT  //////////////////////////////////
#ifdef CONFIG_OCMQTT_ENABLE
    #include <oc_mqtt_al.h>
    (void)oc_mqtt_init();
#endif
////////////////////////////  OC LWM2M /////////////////////////////////////////
#ifdef CONFIG_OCLWM2M_ENABLE
    #include <oc_lwm2m_al.h>
    oc_lwm2m_init();
#endif
////////////////////////////  OC COAP //////////////////////////////////////////
#ifdef CONFIG_OCCOAP_ENABLE
    #include <oc_coap_al.h>
    oc_coap_init();
#endif
#ifdef CONFIG_AUTO_TEST
    #include <test_case.h>
    autotest_start();
#endif
#ifdef CONFIG_LINKDEMO_ENABLE
    extern int standard_app_demo_main(void);
    (void) standard_app_demo_main();
#endif
    return 0;
}

        该函数会根据iot_config.h文件中的宏定义取值决定什么组件进行初始化操作,初始化时,当使能OC_LWM2M_ENABLE时,会执行oc_lwm2m_init(),进行lwm2m相关初始化操作,会调用oc_lwm2m_al.c文件中的oc_lwm2m_init()函数, oc_lwm2m_al是处理使用lwm2m协议对接华为OC的流程抽象层,允许使用流程进行对接,也允许使用NB芯片内置的流程进行对接。对于lwm2m协议的对接流程的具体实现开发者(基于lwm2m协议或基于支持lwm2m协议的模块,或者以及内置对接华为OC流程的模块),只需接下来,oc_lwm2m_init()函数会调用oc_lwm2m_imp_init()函数,这个OC层的实现可以分为两个不同的场景,一种使用NB进行对接即boudica150,其内部包含lwm2m协议栈。第二种是使用agent_lwm2m.c中实现对应的config,report,deconfig函数进行流程对接。

2.png

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。