nRF5 IoT SDK  v0.9.0
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
LWM2M

LWM2M and IPSO

Note
The OMA Lightweight M2M (LWM2M) defines service architecture for IoT devices and the protocol for device management. Constrained Application Protocol (CoAP) is used as a framework for service definitions and device management procedures. The examples and libraries provided in this SDK demonstrate how you can build an LWM2M type of application. Before building your own product using LWM2M, you should consider the license terms of OMA.
The IPSO Smart Objects specified by the Internet Protocol for Smart Objects (IPSO) Alliance provides object definitions for common sensor and actuator types. The object definitions reuse the LWM2M service architecture, therefore enabling existing LWM2M libraries and software to be used as infrastructure. The examples and libraries provided in this SDK demonstrate how you can build an IPSO Smart Object type of application. Before building your own product using IPSO Smart Objects, you should consider the license terms of the IPSO Alliance.

Nordic's LWM2M library supports the LWM2M Client role.

Objects

The LWM2M library included in the SDK improves the memory footprint by using statically assigned object instances to handle requests to an object. There is a separate callback for requests going to the root object.

The Figure 1 below demonstrates how the IPSO digital output object is configured using the lwm2m_object_prototype_t, in order to act as an object handler for this object type.

lwm2m_resource_object.svg
Figure 1. The LWM2M object structure

Instances and resources

The library structures the CoAP resources differently from that of Nordic's CoAP library (see Nordic's CoAP) in order to improve the memory RAM footprint. The difference in the two structures lies in defining a common callback for all object instances of an object rather than one dedicated callback for each resource. Depending on the URI path for the object instance provided in the callback on request notification, the application is able to distinguish whether the request is for the instance or a specific resource.

Each LWM2M object instance definition consists of :

  1. lwm2m_instance_prototype_t containing object identification, instance identification, and files needed for managing the resource structure
  2. object and instance specific data fields unique to the object and the instance, for example, state information, sensor values etc.

In order to maintain resource definitions and access permissions in an object, additional information called operations and resources_ids is included in each object. These fields are indices to lists that maintain the information for all the objects and their data members.

Figure 2 demonstrates how an IPSO digital output object instance is configured to act as an object instance handler.

lwm2m_resource_instance.svg
Figure 2. The LWM2M instance/resource structure

Disable Resource ID

In order to disable a data member from the struct, a NONE permission could be entered in the operations list of that object. This will disable the resource from being accessed. The CoAP request matching will also be disabled for this resource if attempted to be accessed, and the instance callback will not be called. On the other hand, a CoAP error code "Not Found" will be returned by the LWM2M CoAP middleware automatically.

LWM2M CoAP integration

Each request will be forwarded to the appropriate handler based on the URI defined in the CoAP request. The instance or resource that exist in the system determines what callback LWM2M will choose. Below there is a diagram showing how different scenarios are mapped to the two prototype forms which exist in the system.

The first image shows a DELETE request to a root object. This is forwarded to the callback of the registered object. Second there is a DELETE request to a specific instance in the system. This cannot be handled by the instance handler itself and needs to be handled by the object handler. The instance id used to manipulate is passed as a parameter to the object callback function. As shown in the third diagram, a PUT request is done as an instance URI. This is forwarded to the instance handler which has that instance id. Forth, there is a PUT request on a resource contained in the object instance. This is forwarded to the instance handler and provides the resource id of the resource to be manipulated.

lwm2m_resource_callback.svg
Figure 1. The LWM2M callback mapping

LWM2M API

Initialization

This API shall be called before using any other APIs of the module. If this API fails, none of the module APIs shall be used by the application. Prior to calling the LWM2M initialization function, coap needs to be initialized, along with its port configuration. This is described in Initialization.

Example demonstrating how to initialize the LWM2M module.

// CoAP has been initialized.
...
uint32_t err_code = lwm2m_init();
APP_ERROR_CHECK(err_code);

Notifications

Note
This is an interface function which means it has to be implemented by the application. It does not have any registration function, and will be expected to be present during compilation of an application.

Notifications from LWM2M could come asyncronously from the LWM2M module. The notification type will indicate the source of the notification event. For example an event could come if registration has been issued and the server is acknowleding the request.

The example below demonstrates how to catch a notification from the register interface.

lwm2m_remote_t * p_remote,
uint8_t coap_code)
{
{
...
// Do some action based on the CoAP code if needed.
}
return NRF_SUCCESS;
}

Root handler

Note
This is an interface function which means it has to be implemented by the application. It does not have any registration function, and will be expected to be present during compilation of an application.

Since the library does not provide any object or entry for the root, any requests to the "/" object will be propagated to the lwm2m_coap_handler_root API function. For example, this could be called during Bootstrap, when the bootstrap server issues a delete request on the root. As no object or instance has been registered to handle this, a callback to this function is done, providing the original CoAP request and the parsed LWM2M operation code. The application will have to do an appropriate action upon such request.

The example below shows an implemented handler that only responds to a DELETE operation request without doing any further action.

uint32_t lwm2m_coap_handler_root(uint8_t op_code, coap_message_t * p_request)
{
{
// Delete any existing objects or instances if needed.
...
uint32_t err_code = lwm2m_respond_with_code(COAP_CODE_202_DELETED, p_request);
APP_ERROR_CHECK(err_code);
}
return NRF_SUCCESS;
}

Object initialization

Any object which will be registered in the library to handle LWM2M requests has to be initialized. The base of any object is a lwm2m_object_prototype_t structure. Since there is only one object for a given object ID in the system at a time, there is no need to run an additional initialization function (like for instances) other than populating the structure.

The lwm2m_object_prototype_t has two fields that need to be populated. One is the Object Identfier and the second is the callback function which is called upon to send a request message to the object.

A set of OMA LWM2M object identifier definitions can be found in OMA LWM2M objects definititions and types. For IPSO Smart Objects, a set of object identifier definitions can be found in IPSO Smart Object definititions and types.

Note
It is not required to register an object in order to register object instances of the same type (equal Object Identifier). However, if a request comes attempting to find the root object of the instance, a CoAP response message with error code "404 Not Found" will be sent automatically.

The code below demonstrates how a security object instance could be populated to act as the parent of all the instances with a corresponding Object ID.

uint32_t security_object_callback(lwm2m_object_prototype_t * p_object,
uint16_t instance_id,
uint8_t op_code,
coap_message_t * p_request)
{
// Operation to be done on a request to "/0".
...
}
...
lwm2m_object_prototype_t security_object;
// Initialize the object.
security_object.object_id = LWM2M_OBJ_SECURITY;
security_object.callback = security_object_callback;
// Register the security object.
uint32_t err_code = lwm2m_coap_handler_object_add(&security_object);
APP_ERROR_CHECK(err_code);

Instance initialization

Any object instance registered in the library to handle LWM2M requests has to be initialized.

The base of any object is a lwm2m_instance_prototype_t structure which is referred to as the proto field in each object structure definition. A set of OMA LWM2M object definition structures can be found in OMA LWM2M objects definititions and types. For IPSO Smart Objects, a set of object definition structures can be found in IPSO Smart Object definititions and types. The proto fields have to be populated after the strucuture has been initialized. This is done by passing the pointer to the object type structure into a corresponding init function for the object type.

A set of OMA LWM2M object initialization functions for the object structures can be found in OMA LWM2M objects definititions and types. For IPSO Smart Objects, a set of initialization functions for the object structures can be found in IPSO Smart Object definititions and types.

After initializing the structure, the proto member of the structure has 3 fields that needs to be populated. The first is the Object Identifier which connects the instance to a parent object, the second is the Instance Identfier which is the instance number in the application, and the third is the callback function which is called upon the request message to the object.

Note
The application is responsible for populating the correct instance id because the library does not keep track of how many instances have been added or deleted.

The code below demonstrates how an object instance can be initilized and populated.

// Initialize a security object instance.
lwm2m_security_t security_object_instance;
lwm2m_instance_security_init(&security_object_instance);
// Set the application generated instance id.
security_object_instance.proto.instance_id = 0;
// Set the object identifier.
security_object_instance.proto.object_id = LWM2M_OBJ_SECURITY;
// Assign a callback function for the instance.
security_object_instance.proto.callback = security_instance_callback;
// Register the security object instance.
uint32_t err_code = lwm2m_coap_handler_instance_add(&security_object_instance);
APP_ERROR_CHECK(err_code);

Named Objects

The library assumes that the resources use an object identifier, instance identifier, and resource identifier of uint16_t type. In some special cases it is necessary to create objects with a different identifier. For this case a special object type can be defined. If the object's object_id field is set to to LWM2M_NAMED_OBJECT it will be handled as a Named Object. The alias name has to be provided which is done by setting the p_alias_name field of the object.

If registered using the lwm2m_coap_handler_object_add any request to the object will be resolved. However, the named objects will be rendered as part of the device when generating the Link Format string using the lwm2m_coap_handler_gen_link_format.

The example below demonstrates how an object named "bs" can be created in order to handle a request to a CoAP request with URI-path "/bs".

uint32_t name_object_object_callback(lwm2m_object_prototype_t * p_object,
uint16_t instance_id,
uint8_t op_code,
coap_message_t * p_request)
{
// Operation to be done on a request to "/bs".
...
}
...
char alias_name[] = "bs";
// Initialize the named object.
static lwm2m_object_prototype_t named_object;
named_object.callback = name_object_object_callback;
named_object.p_alias_name = alias_name;
// Register the object in order to forward requests to the named object handler.
uint32_t err_code = lwm2m_coap_handler_object_add(&named_object);
APP_ERROR_CHECK(err_code);

Add an object

Enabling an object to handle requests requires that it is added to the CoAP handler in the library by calling the lwm2m_coap_handler_object_add API function. This will register the object in an internal CoAP resource handler list. Upon requests, the URI paths of the request will be parsed and checked against the object list. If a match exists, the callback function defined by the matching object will be issued.

The code below demonstrates how to add an object to the library's CoAP request handler.

// Initialize the object.
...
// Add the object to the library's internal CoAP handler list.
uint32_t err_code = lwm2m_coap_handler_object_add(&m_object_security);
APP_ERROR_CHECK(err_code);

Delete an object

To disable an object from handling requests it has to be removed from the CoAP handler in the library by calling the lwm2m_coap_handler_object_delete API function.

This will deregister the object from the internal CoAP resource handler list. Once the object is removed, if a request is sent to the object, the library will respond with a 404 Not Found error.

The code below demonstrates how to delete an object from the library's CoAP request handler.

// Initialized object to be removed.
...
// Delete the object from the library's internal CoAP handler list.
uint32_t err_code = lwm2m_coap_handler_object_delete(&m_object_security);
APP_ERROR_CHECK(err_code);

Add an instance

To enable an object instance to handle requests, it has be added to the CoAP handler in the library by calling the lwm2m_coap_handler_instance_add API function. This will register the object instance in an internal CoAP resource handler list. Upon requests, the URI paths of the request will be parsed and checked against the object instance list. If a match exists, the callback function defined by the matching object instance will be issued.

By adding an object instance, the library will also automatically try to match all resource IDs within the instance.

The code below demonstrates how to add an object instance and belonging resources to the library's CoAP request handler.

lwm2m_security_t security_object_instance;
// Initialize the object instance.
...
// Add the object to the library's internal CoAP handler list.
uint32_t err_code = lwm2m_coap_handler_instance_add(&security_object_instance);
APP_ERROR_CHECK(err_code);

Delete an instance

In order to disable an object instance from handling requests it has to be removed from the CoAP handler in the library by calling the lwm2m_coap_handler_instance_delete API function.

This will deregister the object and all associated resources from the internal CoAP resource handler list. Once the object and its resources are removed, if a request is sent to the object, the library will respond with a 404 Not Found error.

The code below demonstrates how to delete an object instance from the library's CoAP request handler.

// Initialized object instance to be removed.
lwm2m_security_t security_object_instance; my_object;
...
// Delete the object instance from the library's internal CoAP handler list.
uint32_t err_code = lwm2m_coap_handler_instance_delete(&security_object_instance);
APP_ERROR_CHECK(err_code);

Generate a Link Format string

Upon registration with a LWM2M server you must supply a Link Format string describing the objects and instances that are enabled in the client. To simplify this process, the library provides an API to traverse the objects and instances registered.

The lwm2m_coap_handler_gen_link_format takes in a buffer and a the length of the buffer. It can be dry-runned by supplying a NULL pointer as buffer and returning the length of the required memory in bytes, which is required to render the string.

The example below shows how a dry-run could be performed, followed by a memory allocation to the nrf_mem_reserve, and finally issue a call to the function again to generate the string into the provided memory.

// Create some variables to hold the Link Format string and length.
uint8_t * p_link_format_string = NULL;
uint16_t link_format_string_len = 0;
// Dry-run the Link Format generation, to check how much memory that is needed.
err_code = lwm2m_coap_handler_gen_link_format(NULL, (uint16_t *)&link_format_string_len);
APP_ERROR_CHECK(err_code);
// Allocate the needed amount of memory.
err_code = nrf_mem_reserve(&p_link_format_string, &link_format_string_len);
APP_ERROR_CHECK(err_code);
// Render the link format string.
err_code = lwm2m_coap_handler_gen_link_format(p_link_format_string, &link_format_string_len);
APP_ERROR_CHECK(err_code);

Encoding TLV

The library provides some functions for encoding OMA LWM2M/IPSO object instances from the structure holding the resource values into a corresponding TLV format.

The encoding API functions for OMA LWM2M objects can be found in OMA LWM2M object TLV encoder and decoder API. The encoding API functions for IPSO Smart Object objects can be found in IPSO Smart Object TLV encoder and decoder API.

The encoding functions expect that the object instance has been initialized as described in Instance initialization.

Below there is an example that demonstrates encoding of an IPSO digital output Smart Object object instance into TLV encoded format.

char app_type[] = "LED4";
// Initialize and populate the IPSO digital output object instance.
static ipso_digital_output_t instance_digital_out;
ipso_instance_digital_output_init(&m_instance_digital_out);
m_instance_digital_out.proto.instance_id = 1;
m_instance_digital_out.digital_output_state = false;
m_instance_digital_out.digital_output_polarity = IPSO_RR_ID_DIGITAL_OUTPUT_POLARITY_NORMAL;
m_instance_digital_out.application_type.p_val = app_type;
m_instance_digital_out.application_type.len = strlen(app_type);
...
uint8_t buffer[100];
uint32_t buffer_size = sizeof(buffer);
uint32_t err_code = ipso_tlv_ipso_digital_output_encode(buffer, &buffer_size, &instance_digital_out);
APP_ERROR_CHECK(err_code);

Decoding TLV

The library provides some functions for decoding OMA LWM2M/IPSO object instances from TLV format into a corresponding structure holding the resource values.

The decoding API functions for OMA LWM2M objects can be found in OMA LWM2M object TLV encoder and decoder API. The decoding API functions for IPSO Smart Object objects can be found in IPSO Smart Object TLV encoder and decoder API.

The decoding functions expect that the object instance has been initialized as described in Instance initialization.

Note
It is important to copy all strings and opaque data types from the decoded structure to persistent memory. The decoding API function will only point relative into the packet buffer of the received request. After returning from the packet handling function the buffer will be freed.

Below there is an example that demonstrates decoding of a security object instance in TLV format into lwm2m_security_t structure assuming a write request has been issued to the security instance.

// Initialized security object instance.
lwm2m_security_t m_security_object_instance;
// Placeholder for the application allocated memory for the URI.
static char m_security_server_uri[32] = {""};
...
uint32_t security_instance_callback(lwm2m_instance_prototype_t * p_instance,
uint16_t resource_id,
uint8_t op_code,
coap_message_t * p_request)
{
{
uint16_t instance_id = p_instance->instance_id;
// Decode the TLV format string into a lwm2m_security_t structure.
uint32_t err_code = lwm2m_tlv_security_decode(&m_security_object_instance,
p_request->p_payload,
p_request->payload_len);
APP_ERROR_CHECK(err_code);
// Remember to make a copy of lwm2m_string_t and lwm2m_opaque_t you want to keep.
// They will be freed after this callback.
// Copy the URI. Can be changed to handle all resources in the instance.
if (m_security_object_instance.server_uri.len < SECURITY_SERVER_URI_SIZE_MAX)
{
// Copy the lwm2m_string_t server_uri into a application allocated memory space
// and point to that one.
memset(m_security_server_uri, 0, SECURITY_SERVER_URI_SIZE_MAX);
memcpy(m_security_server_uri,
m_security_object_instance.server_uri.p_val,
m_security_object_instance.server_uri.len);
m_security_object_instance.server_uri.p_val = \
(char *)m_security_server_uri;
APP_ERROR_CHECK(err_code);
}
else
{
// URI was to long to be copied.
APP_ERROR_CHECK(err_code);
}
}
return NRF_SUCCESS;
}

Respond with payload

The library provides an API function lwm2m_respond_with_payload which generates a CoAP response message based on the original request. The function takes in a payload and length of the payload in addition to the original request, and populates the CoAP message to be sent. After creating the message, it will send it to the transport layer. The CoAP message code used will always be COAP_CODE_205_CONTENT.

The example below demonstrates how to send a response message with a payload using the API.

// Original CoAP request message from the peer.
coap_message_t * p_original_request;
...
uint8_t data[] = "Some data";
uint16_t data_len = strlen(data);
// Send a response to the peer with payload.
uint32_t err_code = lwm2m_respond_with_payload(data,
data_len,
p_original_request);
APP_ERROR_CHECK(err_code);

Respond with code

The library provides an API function lwm2m_respond_with_code which generates a CoAP response message based on the original request adding a custom CoAP message code to it. After creating the message, it will send it to the transport layer.

The example below demonstrates how to send a response message with a custom CoAP message code using the API.

// Original CoAP request message from the peer.
coap_message_t * p_original_request;
...
// Send a response to the peer with custom CoAP message code.
uint32_t err_code = lwm2m_respond_with_code(COAP_CODE_204_CHANGED, p_original_request);
APP_ERROR_CHECK(err_code);

Initiate bootstrap

Before initating bootstrap, a named object has to be set up in order to handle the bootstrap complete event from the bootstrap server. This is not a normal LWM2M object or instance using numbers as a URI path, but a text string. This needs to be handled by registering a named object "/bs" with its belonging object callback function.

When calling the lwm2m_bootstrap API, a client initiated boostrap is triggered. Upon the acknowledgement of the registration request, a notification will be given to the application through the lwm2m_notification callback function. The bootstrap will continue, and finish by a write to the bootstrap object.

If secure mode is enabled for the bootstrap server remote, write attempts might fail if issued during the handshake of DTLS or if the credentials where mismatching. If the write is failing, bootstrap might be re-attempted immediately, but it is recommended to wait a few seconds if the handshake is still in progress.

The example below demonstrates what would be needed to initiate a bootstrap from the client.

uint32_t bootstrap_object_callback(lwm2m_object_prototype_t * p_object,
uint16_t instance_id,
uint8_t op_code,
coap_message_t * p_request)
{
uint32_t err_code = lwm2m_respond_with_code(COAP_CODE_201_CREATED, p_request);
APP_ERROR_CHECK(err_code);
return NRF_SUCCESS;
}
...
// Set up a name object to represent the "/bs" bootstrap object on the client.
char bootstrap_object_alias_name[] = "bs";
lwm2m_object_prototype_t m_bootstrap_server;
m_bootstrap_server.object_id = LWM2M_NAMED_OBJECT;
m_bootstrap_server.callback = bootstrap_object_callback;
m_bootstrap_server.p_alias_name = m_bootstrap_object_alias_name;
// Register the object in order to forward requests to the bootstrap object handler.
uint32_t err_code = lwm2m_coap_handler_object_add(&m_bootstrap_server);
APP_ERROR_CHECK(err_code);
...
// Set the remote bootstrap server.
lwm2m_remote_t bootstrap_remote;
bootstrap_remote.addr = ...
bootstrap_remote.port.port_num = ...
// Set client ID.
lwm2m_client_identity_t client_id;
memcpy(&m_client_id.value.uuid[0], "0a18de70-0ce0-4570-bce9-7f5895db6c70", LWM2M_CLIENT_ID_TYPE_UUID);
client_id.type = LWM2M_CLIENT_ID_TYPE_UUID;
// Set the local port number to be used to send out the request.
uint16_t local_port_number = 5683;
// Initiate bootstrap request towards the bootstrap server identified by the given remote.
uint32_t err_code = lwm2m_bootstrap(&bootstrap_remote,
&client_id,
local_port_number);
// Check if DTLS handshake is in progress.
if (err_code == NRF_TLS_HANDSHAKE_IN_PROGRESS)
{
// Delay lwm2m bootstrapping, DTLS session is not be up running yet.
// Try again later.
}
else
{
APP_ERROR_CHECK(err_code);
}

Register

When calling the lwm2m_register API, a registration request to the given server is triggered. When the registration request is acknowledged, a notification is sent to the application through the lwm2m_notification callback function.

If secure mode is enabled for the LWM2M server remote, write attempts might fail if issued during the DTLS handshake or if the credentials are mismatching. If the write is failing, bootstrap might be re-attempted immediatly, but it is recommended to wait a few seconds if handshake is still in progress.

The example below demonstrates what is needed to initiate a registration request to a given server.

// Set the remote server.
lwm2m_remote_t remote_server;
remote_server.addr = ...
remote_server.port.port_num = ...
// Set client ID.
lwm2m_client_identity_t client_id;
memcpy(&m_client_id.value.uuid[0], "0a18de70-0ce0-4570-bce9-7f5895db6c70", LWM2M_CLIENT_ID_TYPE_UUID);
client_id.type = LWM2M_CLIENT_ID_TYPE_UUID;
// Initialize server configuration structure.
lwm2m_server_config_t server_config;
memset(&server_conf, 0, sizeof(lwm2m_server_config_t));
server_conf.lifetime = 1000;
// Create some variables to hold the Link Format string and length.
uint8_t * p_link_format_string = NULL;
uint16_t link_format_string_len = 0;
// Dry run the link format generation to check how much memory is needed.
err_code = lwm2m_coap_handler_gen_link_format(NULL, (uint16_t *)&link_format_string_len);
APP_ERROR_CHECK(err_code);
// Allocate the needed amount of memory.
err_code = nrf_mem_reserve(&p_link_format_string, &link_format_string_len);
APP_ERROR_CHECK(err_code);
// Render the link format string.
err_code = lwm2m_coap_handler_gen_link_format(p_link_format_string, (uint16_t *)&link_format_string_len);
APP_ERROR_CHECK(err_code);
// Set the local port number to used to send out the request.
uint16_t local_port_number = 5683;
// Initiate a server registration request towards the server identified by the given remote.
err_code = lwm2m_register(&remote_server,
&client_id,
&server_conf,
local_port_number,
p_link_format_string,
link_format_string_len);
// Check if DTLS handshake is in progress.
if (err_code == NRF_TLS_HANDSHAKE_IN_PROGRESS)
{
// Delay lwm2m server registration, DTLS session is not up and running yet.
// Try again later.
}
else
{
APP_ERROR_CHECK(err_code);
}

Registration update

If you need to update the Server configuration towards a registered server, a call to the lwm2m_update API can be issued. The function will automatically look up the "Registration ID" provided by the server during registration, and send a registration update request to the server. The lookup will be based on the remote address and port of the peer server, meaning the lwm2m_remote_t structure has to be provided along with the server configuration for the update. The local port needs to be supplied as well to identify which local port is going to be used to transmit the registration update request. When the registration request is acknowledged, a notification will be sent to the application through the @ c lwm2m_notification callback function.

Below is an example demonstrating how a registration update request could be sent from the application.

// Set the remote server.
lwm2m_remote_t remote_server;
remote_server.addr = ...
remote_server.port.port_num = ...
...
// Initialize the server configuration structure to be used in the update request.
lwm2m_server_config_t server_config;
memset(&server_conf, 0, sizeof(lwm2m_server_config_t));
server_conf.lifetime = 1000;
// Set the local port number to used to send out the request.
uint16_t local_port_number = 5683;
// Initiate a server registration update request towards the server identified by the given remote.
uint32_t err_code = lwm2m_update(remote_server, &server_config, local_port_number);
APP_ERROR_CHECK(err_code);

Deregister

To disconnect from a server that the application is registered with, the lwm2m_deregister API can be used. The function will automatically look up the Registration ID provided by the server during registration, and send a deregistration request to the server. The lookup will be based on the remote address and port of the peer server, meaning the lwm2m_remote_t structure has to be provided. The local port needs to be supplied to identify which port is going to transmit the deregistration request. Upon the acknowledgement of the registration request, a notification will be given to the application through the lwm2m_notification callback function.

Below is an example demonstrating how a deregistration request can be sent from the application.

// Set the remote server.
lwm2m_remote_t remote_server;
remote_server.addr = ...
remote_server.port.port_num = ...
...
// Set the local port number used to send out the request.
uint16_t local_port_number = 5683;
// Initiate a server registration update request towards the server identified by the given remote.
uint32_t err_code = lwm2m_deregister(remote_server, local_port_number);
APP_ERROR_CHECK(err_code);

Features

  • Client initiated boostrap.
  • Server registration/deregistration/update.
  • Object and Instance creation of a subset of OMA LWM2M and IPSO Smart Objects objects.
  • LWM2M TLV encoder/decoder.
  • Link Format string generation of registred objects and object instances.
  • DTLS support.

Configuration parameters

The following configuration parameters should be defined in sdk_config.h.

LWM2M_DISABLE_LOGS

Disables debug tracing in the module. To enable tracing, this flag must be set to 0 and ENABLE_DEBUG_LOG_SUPPORT must be set to 1.

Description Value
Enable debug trace 0
Disable debug trace 1
Dependencies ENABLE_DEBUG_LOG_SUPPORT

LWM2M_DISABLE_API_PARAM_CHECK

Disables API parameter checks in the module. Set this define to 1 to disable checks on API parameters in the module.

API parameter checks are added to ensure that the correct parameters are passed to the module. These checks are useful during development phase, but they might be redundant when the application is finalized. Disabling these checks might improve performance.

Description Value
Enable API parameters check 0
Disable API parameters check 1
Dependencies None

LWM2M_MAX_SERVERS

Maximum number of LWM2M servers to connect to.

As boostrap server is not counted as a server in this sense; the number should reflect how many servers the device registers with.

Restriction Value
Minimum value 1
Maximum value 65535
Dependencies None

LWM2M_COAP_HANDLER_MAX_OBJECTS

Maximum number of objects supported by the device.

As objects are default resource handler for the LWM2M instances when no instance is registered, this has to be defined to set of memory for the objects that are going to be registered as handlers.

Restriction Value
Minimum value 1
Maximum value 65535
Dependencies None

LWM2M_COAP_HANDLER_MAX_INSTANCES

Maximum number of object instance supported by the device.

Maximum number of object instances. Objects are not included as an instance as the handlers are kept in a separate buffer.

Restriction Value
Minimum value 1
Maximum value 65535
Dependencies None

LWM2M_REGISTER_MAX_LOCATION_LEN

Max number of bytes allocated for location string from remote server.

Upon registration the device will get a location string to be used as an identifier for later communication with the server it is registered to. This setting defines the maximun length of the location string a server can return upon registration with a server.

Restriction Value
Minimum value 1
Maximum value 255
Dependencies None