LWM2M开源协议栈——wakaama源代码分析

LWM2M开源协议栈——wakaama源代码分析

本文主要分析liblwm2m.h文件中非DEBUG状态下的代码,其他代码见后续文章

概述

wakaama呈现形式并不是一个C的库文件,而是以源代码的形式,直接和项目代码联合编译。编译模式分为:LWM2M_SERVER_MODELWM2M_CLIENT_MODELWM2M_BOOTSTRAP_SERVER_MODE三种,分别对应此次编译产生的是服务器、客户端还是启动服务器。

分析顺序遵循,lwm2m.h文件从上到下的顺序,按照功能划分对函数原型和功能进行分析。

若有特殊情况,如上下代码关联,必须一起介绍的情况,会有特殊说明

如何编译

wakaama项目采用cmake作为项目构建工具,如何引用项目的CMakeLists.txt,可以参照在/example下的各个项目的CMakeLists.txt是如何编写的。需要注意的是,为了不破坏原有的项目结构,推荐采用外部构建的方式,即:

# 在wakaama之外新建你自己的项目目录,假设为project
cd project
# 注意替换变量为wakaama项目的所在位置,以编译server为例
# 将会在project目录下生成中间文件
cmake ${wakaama_base_dir}/example/server
make
# 产生的二进制文件名,可以参看example/server/CMakeLists.txt的PROJECT指令的参数
./lwm2mserver

你自己的项目可以参看例子的写法。

内存管理类API

void * lwm2m_malloc(size_t s);
void * lwm2m_free(void * p);
char * lwm2m_strdup(const char * str);
int lwm2m_strncmp(const char * s1, const char * s2, size_t n);

没有需要特别说明的函数,跟UNIX标准函数工作方式类似。

第三个函数作用是产生一个能放入str的内存空间,并将str的内容复制(duplicate)其中。

时间类API

time_t lwm2m_gettime(void);

返回距离上一次调用该函数时所流逝(elapse)的时间。根据POSIX规范,time_t是一个有符号整数。错误时返回负数。

辅助功能类API

typedef struct _lwm2m_list_t
{
    struct _lwm2m_list_t * next;
    uint16_t    id;
} lwm2m_list_t;

lwm2m_list_t * lwm2m_list_add(lwm2m_list_t * head, lwm2m_list_t * node);
lwm2m_list_t * lwm2m_list_find(lwm2m_list_t * head, uint16_t id);
lwm2m_list_t * lwm2m_list_remove(lwm2m_list_t * head, uint16_t id, lwm2m_list_t ** nodeP);
uint16_t lwm2m_list_newId(lwm2m_list_t * head);
void lwm2m_list_free(lwm2m_list_t * head);

#define LWM2M_LIST_ADD(H,N) lwm2m_list_add((lwm2m_list_t *)H, (lwm2m_list_t *)N);
#define LWM2M_LIST_RM(H,I,N) lwm2m_list_remove((lwm2m_list_t *)H, I, (lwm2m_list_t **)N);
#define LWM2M_LIST_FIND(H,I) lwm2m_list_find((lwm2m_list_t *)H, I)
#define LWM2M_LIST_FREE(H) lwm2m_list_free((lwm2m_list_t *)H)

提供了链表操作及其简化写法的宏。链表操作使用方式顾名思义。

lwm2m_list_newId函数返回指定链表内未被使用的最小id。

lwm2m_list_free函数工作方式是:仅对每个节点调用lwm2m_free

URI类API

LWM2M实体的抽象表示

对于LWM2M实体(比如一个支持LWM2M协议的设备),可访问服务被抽象为一个一个对象,每一个对象局有三种层次,分别是:Object,Object-Instance,Resource。举例来说,一个LWM2M实体上包含若干提供不同功能的对象(比如说若干种不同的传感器),而每一种功能有可能由多个对象实例提供(比如多个温度传感器,都提供温度读取的功能),这些对象实例实际所能完成的功能被称为资源。(比如温度传感器提供的数据,摄像机拍摄的影像等)。每一个层次在对应的层级上有着独立的ID,分别称为Object ID,Object Instance ID,Resource ID。OMA定义了一些标准的ID,例如:Object ID中的LWM2M_SECURITY_OBJECT_ID为0,这一对象用于为节点间的通信提供安全功能。 而security object对象中包含一些标准化的资源,比如,LWM2M_PUBLIC_KEY_ID标识了security object中的公钥资源。Object Instance ID主要用于唯一标识不同的对象实例,一般来说是在设备启动和对象实例化的时候,动态分配(依次从0增长,每一种对象有着不同的实例ID序列)的。

通过URI访问LWM2M实体

在LWM2M中,合法的URI应当像如下格式(注意,不能以/结尾):

/<object id>[/<object instance id>][/<resource id>]

# legal example
/0
/0/0
/0/1
/0/1/1

URI分别标识了访问资源的object id、object instance id、resource id,后两个id是可选的。

在源代码中体现

#define LWM2M_MAX_ID   ((uint16_t)0xFFFF)

#define LWM2M_URI_FLAG_OBJECT_ID    (uint8_t)0x04
#define LWM2M_URI_FLAG_INSTANCE_ID  (uint8_t)0x02
#define LWM2M_URI_FLAG_RESOURCE_ID  (uint8_t)0x01

#define LWM2M_URI_IS_SET_INSTANCE(uri) (((uri)->flag & LWM2M_URI_FLAG_INSTANCE_ID) != 0)
#define LWM2M_URI_IS_SET_RESOURCE(uri) (((uri)->flag & LWM2M_URI_FLAG_RESOURCE_ID) != 0)

typedef struct
{
    uint8_t     flag;           // indicates which segments are set
    uint16_t    objectId;
    uint16_t    instanceId;
    uint16_t    resourceId;
} lwm2m_uri_t;


#define LWM2M_STRING_ID_MAX_LEN 6

// Parse an URI in LWM2M format and fill the lwm2m_uri_t.
// Return the number of characters read from buffer or 0 in case of error.
// Valid URIs: /1, /1/, /1/2, /1/2/, /1/2/3
// Invalid URIs: /, //, //2, /1//, /1//3, /1/2/3/, /1/2/3/4
int lwm2m_stringToUri(const char * buffer, size_t buffer_len, lwm2m_uri_t * uriP);

lwm2m.h通过lwm2m_stringToUri函数,来将URI字符串转化为lwm2m_uri_t结构。我们可以通过两个预定义的宏LWM2M_URI_IS_SET_INSTANCELWM2M_URI_IS_SET_RESOURCE来判断URI中后两个ID是否被设置。

常量宏

常量宏定义大约在源代码的135行左右,定义了CoAP Error Code、标准对象ID、一部分标准资源的ID。

LWM2M数据类API

概述

LWM2M协议定义一种标准的数据类型lwm2m_data_t,用于存储各种协议中可能用到的数据。

数据结构和常量

typedef enum
{
    LWM2M_TYPE_UNDEFINED = 0,
    LWM2M_TYPE_OBJECT,
    LWM2M_TYPE_OBJECT_INSTANCE,
    LWM2M_TYPE_MULTIPLE_RESOURCE,

    LWM2M_TYPE_STRING,
    LWM2
  • 12
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值