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;
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;
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);
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
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函数进行流程对接。
- 点赞
- 收藏
- 关注作者
评论(0)