• lwm2m协议


    开源代码:wakaama

    1. LWM2M for IoT
    LWM2M(Light Weight Machine-to-Machine)轻量型的通信协议
    IoT(Internet of Things)物联网。装置与互联网形成的网络
    LWM2M是专门为物联网设备之间提供的轻量型通信协议

    2. 特点

    • C/S结构
    • REST架构
    • CoAP协议

    3. REST
    主要用于web服务,使设计更简洁
    REST是设计风格而不是标准
    宗旨是所有的事物都有唯一的标识

    但是物联网中的很多设备都是资源受限型的,即只有少量的内存空间和有限的计算能力,所以传统的HTTP协议应用在物联网上就显得过于庞大而不适用。所以有了基于REST架构的CoAP协议

    4. CoAP
    CoAP(Constrained Application Protocol)
    CoAP是6LowPAN协议栈中的应用层协议
    CoAP是超轻量型协议
    CoAP的默认UDP端口号为5683

    CoAP详见http://blog.csdn.net/zhangxuechao_/article/details/70331928

    5. HTTP资源类

    class Resource {
        Resource(URI u);
        Response get();
        Response post(Request r);
        Response put(Request r);
        Response delete();
    }

    GET方法检索一个资源的描述
    PUT更新资源数据,如果资源不存在的话,则根据此URI创建一个新的资源
    DELETE删除资源(包括不存在的)
    POST创建一个新资源

    6. 数据管理
    Object/Instance/Resource

    7. object
    描述

    S.No Resource ID Description Type Access
    1 5851 Dimmer Integer 0 -100 R,W
    2 5850 On/Off Boolean R,W

    举例
    object

    8. lwm2m
    lwm2m应用了CoAP协议的思想,并且做了一些修改。下面对代码一些介绍
    lwm2m
    command_desc_t

    typedef struct
    {
        char *            name; //cmd name
        char *            shortDesc; //description
        char *            longDesc; //long description
        command_handler_t callback;
        void *            userData;
    } command_desc_t;

    这个结构体的功能是处理命令行的操作。当命令行输入命令时,callback被调用。命令和功能根据个人需求添加修改。最终这些信息都会保存到lwm2m_context_t结构体中

    typedef struct
    {
    #ifdef LWM2M_CLIENT_MODE
        lwm2m_client_state_t state;
        char *               endpointName;
        char *               msisdn;
        char *               altPath;
        lwm2m_server_t *     bootstrapServerList;
        lwm2m_server_t *     serverList;
        lwm2m_object_t *     objectList;
        lwm2m_observed_t *   observedList;
    #endif
    #ifdef LWM2M_SERVER_MODE
        lwm2m_client_t *        clientList;
        lwm2m_result_callback_t monitorCallback;
        void *                  monitor;
    #endif
    #ifdef LWM2M_BOOTSTRAP_SERVER_MODE
        lwm2m_bootstrap_callback_t bootstrapCallback;
        void *                     bootstrap;
    #endif
        uint16_t                nextMID;
        lwm2m_transaction_t *   transactionList;
        void *                  userData;
    } lwm2m_context_t;

    bootstrapServerList:当前代理服务器列表
    serverList:当前连接服务器列表
    objectList:当前object列表,所有管理数据
    observedList:当前observed列表
    clientList:所有连接客户端列表
    monitorCallback:打印当前状态
    monitor:指向lwm2m_context_t
    nextMID:监视Resource用
    transactionList:代理服务器用到

    observed
    observed本身是一种状态。当server开启observed,client会开启定时上报功能。如果object数据有更新,client就会主动上报给sever
    observed内还有time属性。如果time属性设置了,object更新会在设置时间内上报给server,上报间隔不会大于超时时间
    observed
    objArray
    main函数会默认添加一些object

    struct _lwm2m_object_t
    {
        struct _lwm2m_object_t * next;           // for internal use only.
        uint16_t       objID;
        lwm2m_list_t * instanceList;
        lwm2m_read_callback_t     readFunc;
        lwm2m_write_callback_t    writeFunc;
        lwm2m_execute_callback_t  executeFunc;
        lwm2m_create_callback_t   createFunc;
        lwm2m_delete_callback_t   deleteFunc;
        lwm2m_discover_callback_t discoverFunc;
        void * userData;
    };

    userData:object相关数据
    这些object通过lwm2m_configure函数添加到objectList中,这些callback是当object改变时触发

    lwm2m_step
    不管是文件描述符状态变化,还是有命令行操作,或者是超时时间到了。都会导致while循环走到这里,每次必然要做如下操作:

    • 当前维护时间更新
    • 代理服务器状态更新
    • 服务器状态更新
    • Resource监视的状态更新

    lwm2m_handle_packet
    客户端收到的包,在这里做进一步处理

    coap_parse_message
    解析出coap消息。这和标准的coap消息还是有区别的

    typedef struct {
      uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory to serialize packet */
    
      uint8_t version;
      coap_message_type_t type;
      uint8_t code;
      uint16_t mid;
    
      uint8_t options[COAP_OPTION_PROXY_URI / OPTION_MAP_SIZE + 1]; /* Bitmap to check if option is set */
    
      coap_content_type_t content_type; /* Parse options once and store; allows setting options in random order  */
      uint32_t max_age;
      size_t proxy_uri_len;
      const uint8_t *proxy_uri;
      uint8_t etag_len;
      uint8_t etag[COAP_ETAG_LEN];
      size_t uri_host_len;
      const uint8_t *uri_host;
      multi_option_t *location_path;
      uint16_t uri_port;
      size_t location_query_len;
      uint8_t *location_query;
      multi_option_t *uri_path;
      uint32_t observe;
      uint8_t token_len;
      uint8_t token[COAP_TOKEN_LEN];
      uint8_t accept_num;
      uint16_t accept[COAP_MAX_ACCEPT_NUM];
      uint8_t if_match_len;
      uint8_t if_match[COAP_ETAG_LEN];
      uint32_t block2_num;
      uint8_t block2_more;
      uint16_t block2_size;
      uint32_t block2_offset;
      uint32_t block1_num;
      uint8_t block1_more;
      uint16_t block1_size;
      uint32_t block1_offset;
      uint32_t size;
      multi_option_t *uri_query;
      uint8_t if_none_match;
    
      uint16_t payload_len;
      uint8_t *payload;
    
    } coap_packet_t;

    handle_request

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

    根据lwm2m消息管理模式”Object/Instance/Resource”,把uri_path解析到lwm2m_uri_t中
    根据flag做相应的操作

    dm_handleRequest
    请求消息中code有如下四种类型(类似于上面提到的HTTP资源类),object根据类型做相应的操作,刚刚在object中注册的回调将在这里被触发

    /* CoAP request method codes */
    typedef enum {
      COAP_GET = 1,
      COAP_POST,
      COAP_PUT,
      COAP_DELETE
    } coap_method_t;

    lwm2m_data_serialize
    当object回调完成了,需要处理的也在callback处理完了。如果response消息有payload数据。payload封装方式有很多种,lwm2m默认采用的JSON。lwm2m中JSON的数据格式详见internals.h

    typedef enum
    {
        LWM2M_CONTENT_TEXT      = 0,        // Also used as undefined
        LWM2M_CONTENT_LINK      = 40,
        LWM2M_CONTENT_OPAQUE    = 42,
        LWM2M_CONTENT_TLV_OLD   = 1542,     // Keep old value for backward-compatibility
        LWM2M_CONTENT_TLV       = 11542,
        LWM2M_CONTENT_JSON_OLD  = 1543,     // Keep old value for backward-compatibility
        LWM2M_CONTENT_JSON      = 11543
    } lwm2m_media_type_t;

    JSON详见http://blog.csdn.net/zhangxuechao_/article/details/70227888

    9. 添加一个object流程
    应用lwm2m协议完成你个人的需求,实际就是添加一个object,实际就是完善read/write/execute/create/delete/discover回调函数

    1. 添加object_objectname.c文件,根据源码风格
    2. 添加objectname_data_t结构体到.c
    3. 添加prv_res2tlv函数.c
    4. 添加prv_objectname_read/write/execute/create/delete/discover函数到.c,供server回调使用(根据个人需求)
    5. 添加display_object_objectname函数,供打印使用
    6. 添加get_object_objectname函数,供userData初始化
      设置一个LWM2M_objectname_OBJECT_ID宏,每个object唯一的ID(REST架构思想)
    7. 添加free_object_objectname函数,供userData释放
    8. 添加objArray[LWM2M_objectname_OBJECT_ID]到main函数
    9. 添加free_object_objectname函数到main函数
    10. 添加display_object_objectname函数到prv_display_objects函数
    11. 添加函数声明到lwm2mclient.h中
    12. 添加object_objectname.c到CMakeLists SOURCES变量中
  • 相关阅读:
    Linux学习笔记总结--CentOS 设置静态IP
    LAMP环境部署总结
    expect批量分发公钥
    CentOS6.5一键安装MySQL5.5.32(源码编译)
    CentOS6.5 一键部署运行环境shell脚本
    CentOS 更新yum源
    centos 6.6编译安装nginx
    安装Oracle数据库和PLSQL连接数据库
    ABAP 取字段的简短描述
    ABAP OLE常用方法和属性
  • 原文地址:https://www.cnblogs.com/zhangxuechao/p/11709731.html
Copyright © 2020-2023  润新知