Chapter 3 Functional Description of LWM2M Client
This chapter contains a functional description of LWM2M Client.
LWM2M Client Initialization
The LWM2M Client is initialized by calling nx_lwm2m_client_create service. The LWM2M Client runs in its own thread and can report some events to the application through the use of callbacks, or by calling methods of the custom objects implemented by the application.
In addition, LWM2M Client Sessions must be created by calling nx_lwm2m_client_session_create for enabling communication with one or more servers. A session can communicate with two different types of servers: a Bootstrap Server or a LWM2M Server (Device Management).
Bootstrap Server Session
A communication session with a Bootstrap Server is used to provision essential information into the LWM2M Client to enable the LWM2M Client to perform the operation “Register” with one or more LWM2M Servers. This type of server is used during the Client Initiated and Server Initiated Bootstrap modes.
The application can start a Bootstrap session by calling nx_lwm2m_client_session_bootstrap or nx_lwm2m_client_session_bootstrap_dtls, it must provide the IP address and port number of the server, and an optional Security Object Instance ID. The nx_lwm2m_client_session_bootstrap function uses insecure communication, whereas nx_lwm2m_client_session_bootstrap_dtls establishes a secure DTLS connection with the server.
If the Bootstrap operation is successful, the Bootstrap server should have created Security Object Instance(s) for the Bootstrap and LWM2M Servers, and Server Object Instance(s) for the LWM2M Servers. The application can call nx_lwm2m_client_session_register_info_get to get LWM2M Server(s) information and use this information for establishing a session with the LWM2M Server(s).
The Bootstrap data should be saved to non-volatile memory by the application to configure the LWM2M Client at the next reboot of the device.
LWM2M Server Session
A communication session with a LWM2M Server is used for Registration, Device Management and Service Enablement.
The application can register the LWM2M Client to a server by calling nx_lwm2m_client_session_register or nx_lwm2m_client_session_register_dtls, it must provide the IP address and port number of the server, and the Short Server ID which corresponds to an existing Server Object Instance. The nx_lwm2m_client_session_register function uses insecure communication, whereas nx_lwm2m_client_session_register_dtls establishes a secure DTLS connection with the server.
The application can de-register the LWM2M Client by calling nx_lwm2m_client_session_deregister, and ask the client to send an ‘Update’ message by calling nx_lwm2m_client_session_update.
Session State Callback
The application registers a callback at creation of a session which is called when the state of the session is updated, the callback function NX_LWM2M_CLIENT_SESSION_STATE_CALLBACK has the following prototype.
typedef VOID (*NX_LWM2M_CLIENT_SESSION_STATE_CALLBACK)(NX_LWM2M_CLIENT_SESSION *session_ptr,UINT state);
The following states are defined.
| Session State | Description |
|---|---|
| NX_LWM2M_CLIENT_SESSION_INIT | The initial state after session creation. |
| NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_WAITING | The client is waiting for the expiration of the ‘Hold Off’ timer or Server Initiated Bootstrap. |
| NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_REQUESTING | The client has sent a ‘Request’ message to the Bootstrap Server (Client Initiated Bootstrap). |
| NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_INITIATED | The client is receiving data from the Bootstrap Server. |
| NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_FINISHED | The Bootstrap Server has sent a ‘Finished’ message. |
| NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_ERROR | The bootstrap session has failed. |
| NX_LWM2M_CLIENT_SESSION_REGISTERING | The client has sent a ‘Register’ message to the LWM2M Server. |
| NX_LWM2M_CLIENT_SESSION_REGISTERED | The client is registered to the LWM2M Server. |
| NX_LWM2M_CLIENT_SESSION_UPDATING | The client has sent an ‘Update’ message to the LWM2M Server. |
| NX_LWM2M_CLIENT_SESSION_DEREGISTERING | The client has sent an ‘De-register’ message to the LWM2M Server. |
| NX_LWM2M_CLIENT_SESSION_DEREGISTERED | The client is de-registered from the LWM2M Server. |
| NX_LWM2M_CLIENT_SESSION_DISABLED | The LWM2M Server is disabled. A ‘Register’ will be sent after the expiration of the disable timer. |
| NX_LWM2M_CLIENT_SESSION_ERROR | The registration or update operation to the LWM2M Server has failed. |
| NX_LWM2M_CLIENT_SESSION_DELETED | The Server Object Instance corresponding to the LWM2M Server has been deleted. |
In case of error the application can retrieve the cause of the error by calling nx_lwm2m_client_session_error_get.
Local Device Management
The application can access the Objects of the LWM2M Client by using the local device management functions. The following functions are provided.
| Function Name | Description |
|---|---|
| nx_lwm2m_client_object_read | Read resources from an Object Instance. |
| nx_lwm2m_client_object_discover | Get the list of the resources of an Object Instance. |
| nx_lwm2m_client_object_write | Write resources to an Object Instance. |
| nx_lwm2m_client_object_execute | Perform the Execute operation on a resource of an Object Instance. |
| nx_lwm2m_client_object_create | Create a new Object Instance. |
| nx_lwm2m_client_object_delete | Delete an existing Object Instance. |
| nx_lwm2m_client_object_next_get | Get the next Object ID by the LWM2M Client. |
| nx_lwm2m_client_object_instance_next_get | Get the next Instance of an Object. |
Resource Information
When reading from and writing to Objects a Resource is represented by the NX_LWM2M_CLIENT_RESOURCE structure. This structure contains the ID of the Resource/Instance and its value.
The following functions are provided for setting resource info and value.
| Function Name | Description |
|---|---|
| nx_lwm2m_client_resource_info_set | Set resource info: resource id and operation: READ, WRITE, EXECUTABLE. |
| nx_lwm2m_client_resource_string_set | Set the resource value as string. |
| nx_lwm2m_client_resource_integer32_set | Set the resource value as 32-Bit integer. |
| nx_lwm2m_client_resource_integer64_set | Set the resource value as 64-Bit integer. |
| nx_lwm2m_client_resource_float32_set | Set the resource value as 32-Bit float. |
| nx_lwm2m_client_resource_float64_set | Set the resource value as 64-Bit float. |
| nx_lwm2m_client_resource_boolean_set | Set the resource value as boolean. |
| nx_lwm2m_client_resource_objlnk_set | Set the resource value as object link. |
| nx_lwm2m_client_resource_opaque_set | Set the resource value as opaque. |
| nx_lwm2m_client_resource_instance_set | Set the resource value as instance for multiple resource. |
| nx_lwm2m_client_resource_dim_set | Set the resource dimension for multiple resource for discover. |
The following functions are provided for getting resource info and value.
| Function Name | Description |
|---|---|
| nx_lwm2m_client_resource_info_get | Get resource info: resource id and operation: READ, WRITE, EXECUTABLE. |
| nx_lwm2m_client_resource_string_get | Get the value of a string resource. |
| nx_lwm2m_client_resource_integer32_get | Get the value of a 32-Bit integer resource. |
| nx_lwm2m_client_resource_integer64_get | Get the value of a b4-Bit integer resource. |
| nx_lwm2m_client_resource_float32_get | Get the value of a 32-Bit float resource. |
| nx_lwm2m_client_resource_float64_get | Get the value of a 64-Bit float resource. |
| nx_lwm2m_client_resource_boolean_get | Get the value of a Boolean resource. |
| nx_lwm2m_client_resource_objlnk_get | Get the value of an object link resource. |
| nx_lwm2m_client_resource_opaque_get | Get the value of an opaque resource. |
| nx_lwm2m_client_resource_instance_get | Get the resource instance for multiple resource. |
| nx_lwm2m_client_resource_dim_get | Get the resource dimension for multiple resource. |
Object Implementation
The LWM2M Client implements the mandatory OMA LWM2M Objects: Security (0), Server (1), Access Control (2) and Device (3). Other device specific objects must be implemented by the application.
Two data structures are used to define an Object: the NX_LWM2M_CLIENT_OBJECT structure defines the Object implementation, including the Object ID and the object methods, and the NX_LWM2M_CLIENT_OBJECT_INSTANCE structure contains the data of an Object Instance.
The following functions are provided.
| Function Name | Description |
|---|---|
| nx_lwm2m_client_object_add | Add object implementation to the LwM2M Client. |
| nx_lwm2m_client_object_remove | Remove object implementation from the LwM2M Client. |
| nx_lwm2m_client_object_instance_add | Add object instance to the Object. |
| nx_lwm2m_client_object_instance_remove | Remove object instance from the Object. |
The object method callback function has signature shown below.
typedef UINT (*NX_LWM2M_CLIENT_OBJECT_OPERATION_CALLBACK)(
UINT operation,
NX_LWM2M_CLIENT_OBJECT *object_ptr,
NX_LWM2M_CLIENT_OBJECT_INSTANCE *object_instance_ptr,
NX_LWM2M_CLIENT_RESOURCE *resource,
UINT *resource_count,
VOID *args_ptr,
UINT args_length);
The ‘Read’ Method
The ‘Read’ method is used to read Resource values from an Object Instance. The parameters are defined as follows.
| Parameter | Description |
|---|---|
| operation | NX_LWM2M_CLIENT_OBJECT_READ |
| object_ptr | Pointer to the Object implementation. |
| instance_ptr | Pointer to the Object Instance. |
| resource | Pointer to an array of NX_LWM2M_CLIENT_RESOURCE containing the IDs of the resources to read. On return the array is filled with corresponding types and values. |
| resource_count | Pointer to the number of resources to read. |
| args_ptr | Unused parameter for read. |
| args_length | Unused parameter for read. |
The ‘Discover’ Method
The ‘Discover’ method is used to retrieve the list of all Resources implemented by an Object. The parameters are defined as follows.
| Parameter | Description |
|---|---|
| operation | NX_LWM2M_CLIENT_OBJECT_DISCOVER |
| object_ptr | Pointer to the Object implementation. |
| instance_ptr | Pointer to the Object Instance. |
| resource | Pointer to an array of NX_LWM2M_CLIENT_RESOURCE. On return the array is filled with corresponding resource info. |
| resource_count | Pointer to the number of resources to discover. On return this parameter must be updated as the true value. |
| args_ptr | Unused parameter for discover. |
| args_length | Unused parameter for discover. |
The ‘Write’ Method
The ‘Write’ method is used to update or replace resources of an Object Instance. The parameters are defined as follows.
| Parameter | Description |
|---|---|
| operation | NX_LWM2M_CLIENT_OBJECT_WRITE |
| object_ptr | Pointer to the Object implementation. |
| instance_ptr | Pointer to the Object Instance. |
| resource | Pointer to an array of NX_LWM2M_CLIENT_RESOURCE containing the IDs of the resources to read. On return the array is filled with corresponding types and values. |
| resource_count | Pointer to the number of resources to discover. |
| args_ptr | Write flags. |
| args_length | The length of the arguments. |
The following write operations can be specified to the flag parameter.
| Operation | Action | Description |
|---|---|---|
| 0 | Partial Update | Adds or updates Resources provided in the new value and leaves other existing Resources unchanged. |
| NX_LWM2M_CLIENT_OBJECT_WRITE_REPLACE_INSTANCE | Replace Instance | Replaces the Object Instance with the new provided resource values. |
| NX_LWM2M_CLIENT_OBJECT_WRITE_REPLACE_RESOURCE | Replace Resource | Replaces the Resources with the new provided resource values (used to replace Multiple Resources). |
| NX_LWM2M_CLIENT_OBJECT_WRITE_CREATE | Create Instance | Initializes the newly created Object Instance with the provided resource values (called from the nx_lwm2m_object_create method). |
| NX_LWM2M_CLIENT_OBJECT_WRITE_BOOTSTRAP | Bootstrap Write | Called during Bootstrap sequence. |
The ‘Execute’ Method
The ‘Execute’ method implements the execution of an Object Resource.
The input parameters are defined as follows.
| Parameter | Description |
|---|---|
| operation | NX_LWM2M_CLIENT_OBJECT_EXECUTE |
| object_ptr | Pointer to the Object implementation. |
| instance_ptr | Pointer to the Object Instance. |
| resource | Pointer to an array of NX_LWM2M_CLIENT_RESOURCE containing the IDs of the resources to read. On return the array is filled with corresponding types and values. |
| resource_count | Pointer to the number of resources to discover. |
| args_ptr | Pointer to the arguments. |
| args_length | The length of the arguments. |
The function must return NX_LWM2M_CLIENT_NOT_FOUND if the Resource ID doesn’t exist, or NX_LWM2M_CLIENT_METHOD_NOT_ALLOWED if it doesn’t support execution.
The ‘Create’ Method
The ‘Create’ method implements the creation of a new Object Instance.
The input parameters are defined as follows.
| Parameter | Description |
|---|---|
| operation | NX_LWM2M_CLIENT_OBJECT_CREATE |
| object_ptr | Pointer to the Object implementation. |
| instance_ptr | Unused parameter. |
| resource | Pointer to an array of NX_LWM2M_CLIENT_RESOURCE containing the IDs of the resources to read. On return the array is filled with corresponding types and values. |
| resource_count | Pointer to the number of resources to discover. |
| args_ptr | Object instance id. |
| args_length | The length of the arguments. |
The ‘Delete’ Method
The ‘Delete’ method implements the deletion of an object instance, the input parameters are defined as follows.
| Parameter | Description |
|---|---|
| operation | NX_LWM2M_CLIENT_OBJECT_DELETE |
| object_ptr | Pointer to the Object implementation. |
| instance_ptr | Pointer to the Object Instance. |
| resource | Unused parameter. |
| resource_count | Unused parameter. |
| args_ptr | Unused parameter. |
| args_length | Unused parameter. |
On success the Object must release the Object Instance data and any other resource allocated by the instance.
Example of LWM2M Client Application
The following code is an example of a simple LWM2M Client Application which implements a custom device consisting of a temperature sensor and a light switch.
The device allows a server to read the value of the temperature sensor and the boolean state of the light switch, and to set the light switch to on/off.
#include "nx_lwm2m_client.h"
/* Custom Object implementation. */
/* Temperature Object ID and resource IDs. */
#define IPSO_TEMPERATURE_OBJECT_ID 3303
#define IPSO_RESOURCE_MIN_VALUE 5601
#define IPSO_RESOURCE_MAX_VALUE 5602
#define IPSO_RESOURCE_RESET_MINMAX 5605
#define IPSO_RESOURCE_VALUE 5700
#define IPSO_RESOURCE_UNITS 5701
/* Actuation Object ID and resource IDs. */
#define IPSO_ACTUATION_OBJECT_ID 3306
#define IPSO_RESOURCE_ONOFF 5850
/* Define the Temperature Object Instance structure */
typedef struct
{
/* The LWM2M Object Instance */
NX_LWM2M_CLIENT_OBJECT_INSTANCE object_instance;
/* Resources Data */
NX_LWM2M_FLOAT32 temperature;
NX_LWM2M_FLOAT32 min_temperature;
NX_LWM2M_FLOAT32 max_temperature;
} IPSO_TEMPERATURE_INSTANCE;
/* Define the Actuation Object Instance structure */
typedef struct
{
/* The LWM2M Object Instance */
NX_LWM2M_CLIENT_OBJECT_INSTANCE object_instance;
/* Resources Data */
NX_LWM2M_BOOL onoff;
} IPSO_ACTUATION_INSTANCE;
/* IPSO Temperature */
/* Define the 'Read' Method */
UINT ipso_temperature_read(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT resource_count)
{
IPSO_TEMPERATURE_INSTANCE *temp = ((IPSO_TEMPERATURE_INSTANCE *) instance_ptr);
UINT i;
NX_LWM2M_ID resource_id;
for (i = 0 ; i < resource_count; i++)
{
nx_lwm2m_client_resource_info_get(&resource[i], &resource_id, NX_NULL);
switch (resource_id)
{
case IPSO_RESOURCE_MIN_VALUE:
/* return the minimum measured temperature value */
nx_lwm2m_client_resource_float32_set(&resource[i], temp -> min_temperature);
break;
case IPSO_RESOURCE_MAX_VALUE:
/* return the maximum measured temperature value */
nx_lwm2m_client_resource_float32_set(&resource[i], temp -> max_temperature);
break;
case IPSO_RESOURCE_VALUE:
/* return the temperature value */
nx_lwm2m_client_resource_float32_set(&resource[i], temp -> temperature);
break;
case IPSO_RESOURCE_RESET_MINMAX:
/* Not readable */
return(NX_LWM2M_CLIENT_METHOD_NOT_ALLOWED);
case IPSO_RESOURCE_UNITS:
/* return the temperature units */
nx_lwm2m_client_resource_string_set(&resource[i], "Cel", 3);
break;
default:
/* unknown resource ID */
return(NX_LWM2M_CLIENT_NOT_FOUND);
}
}
return(NX_SUCCESS);
}
/* Define the 'Discover' method */
UINT ipso_temperature_discover(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resources, UINT *resource_count)
{
if (*resource_count < 5)
{
return(NX_LWM2M_CLIENT_BUFFER_TOO_SMALL);
}
/* return the list of supported resources IDs */
*resource_count = 5;
nx_lwm2m_client_resource_info_set(&resources[0], IPSO_RESOURCE_MIN_VALUE, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ);
nx_lwm2m_client_resource_info_set(&resources[1], IPSO_RESOURCE_MAX_VALUE, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ);
nx_lwm2m_client_resource_info_set(&resources[2], IPSO_RESOURCE_RESET_MINMAX, NX_LWM2M_CLIENT_RESOURCE_OPERATION_EXECUTABLE);
nx_lwm2m_client_resource_info_set(&resources[3], IPSO_RESOURCE_VALUE, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ);
nx_lwm2m_client_resource_info_set(&resources[4], IPSO_RESOURCE_UNITS, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ);
return(NX_SUCCESS);
}
/* Define the 'Execute' method */
UINT ipso_temperature_execute(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, const CHAR *args_ptr, UINT args_length)
{
IPSO_TEMPERATURE_INSTANCE *temp = ((IPSO_TEMPERATURE_INSTANCE *) instance_ptr);
NX_LWM2M_CLIENT_RESOURCE value;
NX_LWM2M_ID resource_id;
/* Get resource id */
nx_lwm2m_client_resource_info_get(resource, &resource_id, NX_NULL);
switch (resource_id)
{
case IPSO_RESOURCE_MIN_VALUE:
case IPSO_RESOURCE_MAX_VALUE:
case IPSO_RESOURCE_VALUE:
case IPSO_RESOURCE_UNITS:
/* read-only resource */
return(NX_LWM2M_CLIENT_METHOD_NOT_ALLOWED);
case IPSO_RESOURCE_RESET_MINMAX:
/* reset min/max values to current temperature */
nx_lwm2m_client_resource_float32_set(&value, temp -> temperature);
if (temp -> min_temperature != temp -> temperature)
{
temp -> min_temperature = temp -> temperature;
nx_lwm2m_client_resource_info_set(&value, IPSO_RESOURCE_MIN_VALUE, NX_NULL);
nx_lwm2m_client_object_resource_changed(object_ptr, instance_ptr, &value);
}
if (temp -> max_temperature != temp -> temperature)
{
temp -> max_temperature = temp -> temperature;
nx_lwm2m_client_resource_info_set(&value, IPSO_RESOURCE_MAX_VALUE, NX_NULL);
nx_lwm2m_client_object_resource_changed(object_ptr, instance_ptr, &value);
}
break;
default:
/* unknown resource ID */
return(NX_LWM2M_CLIENT_NOT_FOUND);
}
return(NX_SUCCESS);
}
/* Define the operation callback function of Temperature Object */
UINT ipso_temperature_operation(UINT operation, NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *object_instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT *resource_count, VOID *args_ptr, UINT args_length)
{
switch (operation)
{
case NX_LWM2M_CLIENT_OBJECT_READ:
/* Call read function */
return ipso_temperature_read(object_ptr, object_instance_ptr, resource, *resource_count);
case NX_LWM2M_CLIENT_OBJECT_DISCOVER:
/* Call discover function */
return ipso_temperature_discover(object_ptr, object_instance_ptr, resource, resource_count);
case NX_LWM2M_CLIENT_OBJECT_EXECUTE:
/* Call execute function */
return ipso_temperature_execute(object_ptr, object_instance_ptr, resource, args_ptr, args_length);
default:
/*Unsupported operation */
return(NX_LWM2M_CLIENT_NOT_SUPPORTED);
}
}
/* IPSO Actuation */
/* Define the 'Read' Method */
UINT ipso_actuation_read(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT resource_count)
{
IPSO_ACTUATION_INSTANCE *act = ((IPSO_ACTUATION_INSTANCE *) instance_ptr);
UINT i;
NX_LWM2M_ID resource_id;
for (i = 0 ; i < resource_count; i++)
{
nx_lwm2m_client_resource_info_get(&resource[i], &resource_id, NX_NULL);
switch (resource_id)
{
case IPSO_RESOURCE_ONOFF:
/* return the on/off value */
nx_lwm2m_client_resource_boolean_set(&resource[i], act -> onoff);
break;
default:
/* unknown resource ID */
return(NX_LWM2M_CLIENT_NOT_FOUND);
}
}
return(NX_SUCCESS);
}
/* Define the 'Discover' method */
UINT ipso_actuation_discover(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resources, UINT *resource_count)
{
if (*resource_count < 1)
{
return(NX_LWM2M_CLIENT_BUFFER_TOO_SMALL);
}
/* return the list of supported resources IDs */
*resource_count = 1;
nx_lwm2m_client_resource_info_set(&resources[0], IPSO_RESOURCE_ONOFF, NX_LWM2M_CLIENT_RESOURCE_OPERATION_READ_WRITE);
return(NX_SUCCESS);
}
/* Define the 'Write' method */
UINT ipso_actuation_write(NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT resource_count, UINT flags)
{
IPSO_ACTUATION_INSTANCE *act = ((IPSO_ACTUATION_INSTANCE *) instance_ptr);
UINT ret;
NX_LWM2M_BOOL onoff;
UINT i;
NX_LWM2M_ID resource_id;
for (i = 0 ; i < resource_count; i++)
{
nx_lwm2m_client_resource_info_get(&resource[i], &resource_id, NX_NULL);
switch (resource_id)
{
case IPSO_RESOURCE_ONOFF:
/* assign on/off boolean value */
ret = nx_lwm2m_client_resource_boolean_get(&resource[i], &onoff);
if (ret != NX_SUCCESS)
{
/* invalid value type */
return(ret);
}
if (onoff != act->onoff)
{
act->onoff = onoff;
printf("Set actuation switch %s\n", onoff ? "On" : "Off");
}
break;
default:
/* unknown resource ID */
return(NX_LWM2M_CLIENT_NOT_FOUND);
}
}
return(NX_SUCCESS);
}
/* Define the operation callback function of Actuation Object */
UINT ipso_actuation_operation(UINT operation, NX_LWM2M_CLIENT_OBJECT *object_ptr, NX_LWM2M_CLIENT_OBJECT_INSTANCE *object_instance_ptr, NX_LWM2M_CLIENT_RESOURCE *resource, UINT *resource_count, VOID *args_ptr, UINT args_length)
{
UINT write_op;
switch (operation)
{
case NX_LWM2M_CLIENT_OBJECT_READ:
/* Call read function */
return ipso_actuation_read(object_ptr, object_instance_ptr, resource, *resource_count);
case NX_LWM2M_CLIENT_OBJECT_DISCOVER:
/* Call discover function */
return ipso_actuation_discover(object_ptr, object_instance_ptr, resource, resource_count);
case NX_LWM2M_CLIENT_OBJECT_WRITE:
/* Get the type of write operation */
write_op = *(UINT *)args_ptr;
/* Call write function */
return ipso_actuation_write(object_ptr, object_instance_ptr, resource, *resource_count, write_op);
default:
/* Unsupported operation */
return(NX_LWM2M_CLIENT_NOT_SUPPORTED);
}
}
/* NetX data. */
NX_IP ip_0;
NX_PACKET_POOL pool_0;
/* LWM2M Client data. */
NX_LWM2M_CLIENT client;
ULONG client_stack[4096 / sizeof(ULONG)];
NX_LWM2M_CLIENT_SESSION session;
/* Objects and instances. */
NX_LWM2M_CLIENT_OBJECT temperature_object;
NX_LWM2M_CLIENT_OBJECT actuation_object;
IPSO_TEMPERATURE_INSTANCE temperature_instance;
IPSO_ACTUATION_INSTANCE actuation_instance;
/* Define the session state callback */
void session_callback(NX_LWM2M_CLIENT_SESSION *session_ptr, UINT state)
{
printf("LWM2M Callback: -> %d\n", state);
switch (state)
{
case NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_REQUESTING:
printf("Start client initiated bootstrap\n");
break;
case NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_INITIATED:
printf("Got message from boostrap server\n");
break;
case NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_FINISHED:
/* Bootstrap session done, we can register to the LWM2M Server */
printf( "Boostrap finished.\n");
#ifdef BOOTSTRAP
tx_semaphore_put(&semaphore_bootstarp_finish);
#endif
break;
case NX_LWM2M_CLIENT_SESSION_BOOTSTRAP_ERROR:
/* Failed to Bootstrap the LWM2M Client. */
printf( "Failed to boostrap device, error=%02x\n", nx_lwm2m_client_session_error_get(session_ptr));
break;
case NX_LWM2M_CLIENT_SESSION_REGISTERED:
/* Registration to the LWM2M Client done. */
printf( "LWM2M device registered.\n");
break;
case NX_LWM2M_CLIENT_SESSION_DISABLED:
/* Registration to the LWM2M Client done. */
printf( "LWM2M device disabled.\n");
break;
case NX_LWM2M_CLIENT_SESSION_DEREGISTERED:
/* Registration to the LWM2M Client done. */
printf( "LWM2M device deregistered.\n");
break;
case NX_LWM2M_CLIENT_SESSION_ERROR:
/* Failed to register to the LWM2M Client. */
printf( "Failed to register device, error=%02x\n", nx_lwm2m_client_session_error_get(session_ptr));
break;
}
}
/* Application main thread */
void application_thread(ULONG info)
{
UINT status;
NX_LWM2M_ID server_id = 0;
NXD_ADDRESS server_addr;
CHAR *server_uri = NX_NULL;
UINT server_uri_len = 0;
UCHAR security_mode = 0;
/* Create the LWM2M client */
status = nx_lwm2m_client_create(&client, &ip_0, &pool_0, "nxlwm2mclient", sizeof("nxlwm2mclient") - 1, NX_NULL, 0, NX_LWM2M_CLIENT_BINDING_U, client_stack, sizeof(client_stack), 4);
if (status)
{
return;
}
/* Define our custom objects: */
/* Add Temperature Object */
status = nx_lwm2m_client_object_add(&client, &temperature_object, IPSO_TEMPERATURE_OBJECT_ID, ipso_temperature_operation);
if (status)
{
return;
}
/* Define a single instance */
temperature_instance.temperature = 22.5f;
temperature_instance.min_temperature = temperature_instance.temperature;
temperature_instance.max_temperature = temperature_instance.temperature;
status = nx_lwm2m_client_object_instance_add(&temperature_object, &temperature_instance.object_instance, NX_NULL);
if (status)
{
return;
}
/* Add Actuation Object */
status = nx_lwm2m_client_object_add(&client, &actuation_object, IPSO_ACTUATION_OBJECT_ID, ipso_actuation_operation);
if (status)
{
return;
}
/* Define a single instance */
actuation_instance.onoff = NX_FALSE;
status = nx_lwm2m_client_object_instance_add(&actuation_object, &actuation_instance.object_instance, NX_NULL);
if (status)
{
return;
}
/* Create a session */
status = nx_lwm2m_client_session_create(&session, &client, session_callback);
if (status)
{
return;
}
/* Set bootstrap server address. */
server_addr.nxd_ip_version = NX_IP_VERSION_V4;
server_addr.nxd_ip_address.v4 = IP_ADDRESS(23, 97, 187, 154);
printf("Start boostraping\r\n");
status = nx_lwm2m_client_session_bootstrap(&session, 0, &server_addr, 5783);
if (status)
{
return;
}
status = nx_lwm2m_client_session_register_info_get(&session, NX_LWM2M_CLIENT_RESERVED_ID, &server_id, &server_uri, &server_uri_len, &security_mode, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL);
if (status || (security_mode != NX_LWM2M_CLIENT_SECURITY_MODE_NOSEC))
{
return;
}
printf("Register to LWM2M server\r\n");
status = nx_lwm2m_client_session_register(&session, server_id, &server_addr, 5683);
if (status)
{
return;
}
/* Application main loop */
while (1)
{
/* application code... */
tx_thread_sleep(NX_IP_PERIODIC_RATE);
}
/* Terminate the LWM2M Client */
nx_lwm2m_client_delete(&client);
}