LwM2M Protocol Gateway

Protocol Introduction

LwM2M (Lightweight Machine-To-Machine) is a protocol from the Open Mobile Alliance (OMA) for machine to machine (M2M) or Internet of things device (IoT), it provides device management and communication functions, especially suitable for terminal devices with limited resources.

For more information, see OMA SpecWorksLwM2M gateway - 图1 (opens new window)

LwM2M is built on Constrained Application ProtocolLwM2M gateway - 图2 (opens new window) (CoAP), carried over UDP or SMS, based on REST architecture, so the message structure is simple and compact to worker better in environments where network resources are limited and the device is not always online.

There are two roles in the LwM2M protocol:

  • LwM2M Server

    LwM2M has two kind services:

    1. LwM2M bootstrap server. The emqx-lwm2m plugin does not implement this server.
    2. LwM2M server. The emqx-lwm2m plugin implement it over UDP/DTLS (but not over TCP/TLS, nor over SMS).
  • LwM2M Client

    An LwM2M client is deployed on an LwM2M device which connects to the server for machine to machine communication.

Between LwM2M Server and LwM2M Client, the LwM2M protocol defines 4 interfaces.

  1. Bootstrap interface

    This interface is to provide the client with necessary server information (such as server access point) for it to register to the server. The client also makes use of this interface to provide information (such as supported resources) to the server.

  2. Client Registration Interface

    The client registers itself to the server, and the server stores the information about the connection for future use. Communication between client and server is only possible after registration is completed.

  3. Device management and service implementation interface

    Allows the server to access and modify LwM2M client object instances and resources.

  4. Information reporting interface

    Allows the server to subscribe resource information to the client, and the client reports its resource changes to the server in agreed mode.

LwM2M abstracts the services on the device as Objects and Resources, and defines the attributes and functionalities of various objects in XML files. See HereLwM2M gateway - 图3 (opens new window) for details.

The LwM2M protocol predefines 8 kinds of objects, namely:

  • Security object
  • Server object
  • Access Control access control object
  • Device object
  • Connectivity Monitoring Connectivity monitoring object
  • Firmware firmware object
  • Location object
  • Connectivity Statistics Connectivity statistics object

Quick Start

Open EMQX DashboardLwM2M gateway - 图4 (opens new window), click the Modules tab on the left, and choose to add:

image-20200927213049265

Select the LwM2M Gateway

image-20200927213049265

Configure basic parameters:

image-20200927213049265

Add a listener:

image-20200927213049265

Configure listener parameters:

image-20200927213049265

Click confirm to enter the configuration parameter page:

image-20200927213049265

After clicking Add, the module is added: image-20200927213049265

EMQX-LwM2M is a gateway module of EMQX server, it implements most of the functionalities of LwM2M. MQTT client can access LwM2M-enabled devices through EMQX-LWM2M and devices can also report notification to EMQX-LwM2M for data collection and integration over MQTT protocol.

Configuration parameters

ConfigurationDescription
Minimum LifetimeMinimum lifetime allowed to be set for registration/update, in seconds
Maximum LifetimeMaximum lifetime allowed to be set for registration/update, in seconds
QMode Time WindowQMode time window, indicating how long the downstream command sent to the client will be cached, in seconds
Auto ObserveAfter successful registration, whether to automatically observe the objectlist
Mountpointtopic Prefix
Command TopicDownlink command topic, %e means endpoint name
Response TopicUplink response topic, %e means endpoint name
Register TopicRegister message topic, %e means endpoint name
Notify TopicUplink notification topic, %e means endpoint name
Update TopicUpdate message topic, %e means endpoint name
XML DirectoryThe directory of the LwM2M schema files which define LwM2M objects’ schema

MQTT and LwM2M conversion

With emqx_lwm2m, user is able to send LwM2M commands(READ/WRITE/EXECUTE/…) and get LwM2M response in MQTT way. emqx_lwm2m transforms data between MQTT and LwM2M protocol.

emqx_lwm2m needs object definitions to parse data from lwm2m devices. Object definitions are declared by organizations in XML format, you could find those XMLs from LwM2MRegistryLwM2M gateway - 图12 (opens new window), download and put them into the directory specified by lwm2m.xml_dir. If no associated object definition is found, response from device will be discarded and report an error message in log.

Register/Update (LwM2M Client Registration Interface)

  • LwM2M Register and Update message will be converted to following MQTT message:

    • Method: PUBLISH
    • Topic: lwm2m/{?EndpointName}/up/resp (configurable, Mountpoint + Register/Update Topic. The same rules apply to other conversion topics)
    • Payload:

      • MsgType register and update:

        1. {
        2. "msgType": {?MsgType},
        3. "data": {
        4. "ep": {?EndpointName},
        5. "lt": {?LifeTime},
        6. "sms": {?MSISDN},
        7. "lwm2m": {?Lwm2mVersion},
        8. "b": {?Binding},
        9. "alternatePath": {?AlternatePath},
        10. "objectList": {?ObjectList}
        11. }
        12. }
        • {?EndpointName}: String, the endpoint name of the LwM2M client
        • {?MsgType}: String, could be:
          • “register”: LwM2M Register
          • “update”: LwM2M Update
        • “data” contains the query options and the object-list of the register message
        • The update message is only published if the object-list changed.
  • To send a downlink command to device, publish following MQTT message:

    • Method: PUBLISH
    • Topic: lwm2m/{?EndpointName}/dn
    • Request Payload:

      1. {
      2. "reqID": {?ReqID},
      3. "msgType": {?MsgType},
      4. "data": {?Data}
      5. }
      • {?ReqID}: Integer, request-id, used for matching the response to the request
      • {?MsgType}: String, can be one of the following:
        • “read”: LwM2M Read
        • “discover”: LwM2M Discover
        • “write”: LwM2M Write
        • “write-attr”: LwM2M Write Attributes
        • “execute”: LwM2M Execute
        • “create”: LwM2M Create
        • “delete”: LwM2M Delete
      • {?Data}: Json Object, its value depends on the {?MsgType}:

        • If {?MsgType} = “read” or “discover”:

          1. {
          2. "path": {?ResourcePath}
          3. }
          • {?ResourcePath}: String, LwM2M full resource path. e.g. “3/0”, “/3/0/0”, “/3/0/6/0”
        • If {?MsgType} = “write” (single write):

          1. {
          2. "path": {?ResourcePath},
          3. "type": {?ValueType},
          4. "value": {?Value}
          5. }
          • {?ValueType}: String, can be: “Time”, “String”, “Integer”, “Float”, “Boolean”, “Opaque”, “Objlnk”
          • {?Value}: Value of the resource, depends on “type”.
        • If {?MsgType} = “write” (batch write):

          1. {
          2. "basePath": {?BasePath},
          3. "content": [
          4. {
          5. "path": {?ResourcePath},
          6. "type": {?ValueType},
          7. "value": {?Value}
          8. }
          9. ]
          10. }
          • The full path is concatenation of “basePath” and “path”.
        • If {?MsgType} = “write-attr”:

          1. {
          2. "path": {?ResourcePath},
          3. "pmin": {?PeriodMin},
          4. "pmax": {?PeriodMax},
          5. "gt": {?GreaterThan},
          6. "lt": {?LessThan},
          7. "st": {?Step}
          8. }
          • {?PeriodMin}: Number, LwM2M Notification Class Attribute - Minimum Period.
          • {?PeriodMax}: Number, LwM2M Notification Class Attribute - Maximum Period.
          • {?GreaterThan}: Number, LwM2M Notification Class Attribute - Greater Than.
          • {?LessThan}: Number, LwM2M Notification Class Attribute - Less Than.
          • {?Step}: Number, LwM2M Notification Class Attribute - Step.
        • If {?MsgType} = “execute”:

          1. {
          2. "path": {?ResourcePath},
          3. "args": {?Arguments}
          4. }
          • {?Arguments}: String, LwM2M Execute Arguments.
        • If {?MsgType} = “create”:

          1. {
          2. "basePath": "/{?ObjectID}",
          3. "content": [
          4. {
          5. "path": {?ResourcePath},
          6. "type": {?ValueType},
          7. "value": {?Value}
          8. }
          9. ]
          10. }
          • {?ObjectID}: Integer, LwM2M Object ID
        • If {?MsgType} = “delete”:

          1. {
          2. "path": "{?ObjectID}/{?ObjectInstanceID}"
          3. }
          • {?ObjectInstanceID}: Integer, LwM2M Object Instance ID
  • The response of LwM2M will be converted to following MQTT message:

    • Method: PUBLISH
    • Topic: "lwm2m/{?EndpointName}/up/resp"
    • Response Payload:
    1. {
    2. "reqID": {?ReqID},
    3. "imei": {?IMEI},
    4. "imsi": {?IMSI},
    5. "msgType": {?MsgType},
    6. "data": {?Data}
    7. }
    • {?MsgType}: String, can be:
      • “read”: LwM2M Read
      • “discover”: LwM2M Discover
      • “write”: LwM2M Write
      • “write-attr”: LwM2M Write Attributes
      • “execute”: LwM2M Execute
      • “create”: LwM2M Create
      • “delete”: LwM2M Delete
      • “ack”: CoAP Empty ACKLwM2M gateway - 图13 (opens new window)
    • {?Data}: Json Object, its value depends on {?MsgType}:

      • If {?MsgType} = “write”, “write-attr”, “execute”, “create”, “delete”, or “read”(when response without content):

        1. {
        2. "code": {?StatusCode},
        3. "codeMsg": {?CodeMsg},
        4. "reqPath": {?RequestPath}
        5. }
        • {?StatusCode}: String, LwM2M status code, e.g. “2.01”, “4.00”, etc.
        • {?CodeMsg}: String, LwM2M response message, e.g. “content”, “bad_request”
        • {?RequestPath}: String, the requested “path” or “basePath”
      • If {?MsgType} = “discover”:

        1. {
        2. "code": {?StatusCode},
        3. "codeMsg": {?CodeMsg},
        4. "reqPath": {?RequestPath},
        5. "content": [
        6. {?Link},
        7. ...
        8. ]
        9. }
        • {?Link}: String(LwM2M link format) e.g. "</3>", "<3/0/1>;dim=8"
      • If {?MsgType} = “read”(when response with content):

        1. {
        2. "code": {?StatusCode},
        3. "codeMsg": {?CodeMsg},
        4. "content": {?Content}
        5. }
        • {?Content}

          1. [
          2. {
          3. "path": {?ResourcePath},
          4. "value": {?Value}
          5. }
          6. ]
      • If {?MsgType} = “ack”, “data” does not exists

Observe (Information Reporting Interface - Observe/Cancel-Observe)

  • To observe/cancel-observe LwM2M client, send following MQTT PUBLISH:

    • Method: PUBLISH
    • Topic: lwm2m/{?EndpointName}/dn
    • Request Payload:

      1. {
      2. "reqID": {?ReqID},
      3. "msgType": {?MsgType},
      4. "data": {
      5. "path": {?ResourcePath}
      6. }
      7. }
      • {?ResourcePath}: String, the LwM2M resource to be observed/cancel-observed.
      • {?MsgType}: String, can be:
        • “observe”: LwM2M Observe
        • “cancel-observe”: LwM2M Cancel Observe
      • {?ReqID}: Integer, request-id, is the {?ReqID} in the request
  • Responses will be converted to following MQTT message:

    • Method: PUBLISH
    • Topic: lwm2m/{?EndpointName}/up/resp
    • Response Payload:

      1. {
      2. "reqID": {?ReqID},
      3. "msgType": {?MsgType},
      4. "data": {
      5. "code": {?StatusCode},
      6. "codeMsg": {?CodeMsg},
      7. "reqPath": {?RequestPath},
      8. "content": [
      9. {
      10. "path": {?ResourcePath},
      11. "value": {?Value}
      12. }
      13. ]
      14. }
      15. }

Notification (Information Reporting Interface - Notify)

  • The notifications from LwM2M clients will be converted to MQTT PUBLISH:

    • Method: PUBLISH
    • Topic: lwm2m/{?EndpiontName}/up/notify
    • Notification Payload:

      1. {
      2. "reqID": {?ReqID},
      3. "msgType": {?MsgType},
      4. "seqNum": {?ObserveSeqNum},
      5. "data": {
      6. "code": {?StatusCode},
      7. "codeMsg": {?CodeMsg},
      8. "reqPath": {?RequestPath},
      9. "content": [
      10. {
      11. "path": {?ResourcePath},
      12. "value": {?Value}
      13. }
      14. ]
      15. }
      16. }
      • {?MsgType}: String, must be “notify”
      • {?ObserveSeqNum}: Number, value of “Observe” option in CoAP message
      • “content”: same to the “content” field contains in the response of “read” command

MQTT and LwM2M conversion

From the MQTT client, you can send Command to the LwM2M device. The command from MQTT to LwM2M uses the following topic

  1. "lwm2m/{?device_end_point_name}/command".

The MQTT Payload is a string in json format, which specifies the command to be sent. For more details, please refer to the emqx-lwm2m documentation.

The reply of the LwM2M device is sent with the following topic

  1. "lwm2m/{?device_end_point_name}/response".

MQTT Payload is also a string in json format. For more details, please refer to the documentation of emqx-lwm2m.

WARING

The EMQX LwM2M gateway only supports the following content-formats in the CoAP messages:

  • “text/plain”
  • “application/octet-stream”
  • “application/vnd.oma.lwm2m+tlv”
  • “application/vnd.oma.lwm2m+json”