From 945610305a77388f3ab24da824b175fc11807f24 Mon Sep 17 00:00:00 2001 From: Nihad Ferhatovic Date: Thu, 9 May 2024 13:07:39 +0200 Subject: [PATCH 1/2] Adds description for all methods within server and client c files within examples. --- examples/client/lwm2mclient.c | 189 ++++++++++++++++++++++++++++--- examples/server/lwm2mserver.c | 206 ++++++++++++++++++++++++++++++++++ 2 files changed, 381 insertions(+), 14 deletions(-) diff --git a/examples/client/lwm2mclient.c b/examples/client/lwm2mclient.c index 73e2d703..3f270756 100644 --- a/examples/client/lwm2mclient.c +++ b/examples/client/lwm2mclient.c @@ -95,6 +95,7 @@ lwm2m_object_t * objArray[OBJ_COUNT]; # define BACKUP_OBJECT_COUNT 2 lwm2m_object_t * backupObjectArray[BACKUP_OBJECT_COUNT]; +// Structure to hold client data typedef struct { lwm2m_object_t * securityObjP; @@ -109,6 +110,13 @@ typedef struct int addressFamily; } client_data_t; +/** + * @brief Callback function to quit the LwM2M client. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer. + * @param user_data User data. + */ static void prv_quit(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) @@ -118,14 +126,30 @@ static void prv_quit(lwm2m_context_t * lwm2mH, (void)buffer; (void)user_data; + // Set the quit flag to terminate the program g_quit = 1; } +/** + * @brief Signal handler for SIGINT (Ctrl+C) for graceful shutdown. + * + * @param lwm2mH LwM2M context. + * @param uri URI of the resource. + */ void handle_sigint(int signum) { + // Set the quit flag to initiate a graceful shutdown g_quit = 2; } +/** + * @brief Callback function for handling value changes in resources. + * + * @param lwm2mH LwM2M context. + * @param uri URI of the resource. + * @param value New value of the resource. + * @param valueLength Length of the new value. + */ void handle_value_changed(lwm2m_context_t * lwm2mH, lwm2m_uri_t * uri, const char * value, @@ -206,6 +230,13 @@ void handle_value_changed(lwm2m_context_t * lwm2mH, } #ifdef WITH_TINYDTLS +/** + * @brief Connects to the LwM2M server using DTLS. + * + * @param secObjInstID Security Object Instance ID. + * @param userData User data. + * @return void* Pointer to the connection object. + */ void * lwm2m_connect_server(uint16_t secObjInstID, void * userData) { @@ -230,6 +261,13 @@ void * lwm2m_connect_server(uint16_t secObjInstID, return (void *)newConnP; } #else +/** + * @brief Connects to the LwM2M server using CoAP. + * + * @param secObjInstID Security Object Instance ID. + * @param userData User data. + * @return void* Pointer to the connection object. + */ void * lwm2m_connect_server(uint16_t secObjInstID, void * userData) { @@ -286,6 +324,12 @@ void * lwm2m_connect_server(uint16_t secObjInstID, } #endif +/** + * @brief Closes the connection. + * + * @param sessionH Session handler. + * @param userData User data. + */ void lwm2m_close_connection(void * sessionH, void * userData) { @@ -329,6 +373,13 @@ void lwm2m_close_connection(void * sessionH, } } +/** + * @brief Outputs information about bootstrap servers and LWM2M servers. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer. + * @param user_data Unused parameter. + */ static void prv_output_servers(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) @@ -416,6 +467,13 @@ static void prv_output_servers(lwm2m_context_t * lwm2mH, } } +/** + * @brief Handles resource value changes or value change reports. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer. + * @param user_data Unused parameter. + */ static void prv_change(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) @@ -450,6 +508,13 @@ static void prv_change(lwm2m_context_t * lwm2mH, fprintf(stdout, "Syntax error !\n"); } +/** + * @brief Outputs a list of registered LWM2M objects and their instances. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer. + * @param user_data Unused parameter. + */ static void prv_object_list(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) @@ -478,6 +543,13 @@ static void prv_object_list(lwm2m_context_t * lwm2mH, } } +/** + * @brief Dumps the TLV data for a given instance of an object. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param objectP Pointer to the LWM2M object structure. + * @param id Instance ID of the object. + */ static void prv_instance_dump(lwm2m_context_t * lwm2mH, lwm2m_object_t * objectP, uint16_t id) @@ -500,6 +572,13 @@ static void prv_instance_dump(lwm2m_context_t * lwm2mH, } +/** + * @brief Dumps the TLV data for an object or its instances. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer. + * @param user_data Unused parameter. + */ static void prv_object_dump(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) @@ -548,6 +627,13 @@ static void prv_object_dump(lwm2m_context_t * lwm2mH, fprintf(stdout, "Syntax error !\n"); } +/** + * @brief Updates the registration with a specified server. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer containing the server ID. + * @param user_data Unused parameter. + */ static void prv_update(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) @@ -572,6 +658,13 @@ static void prv_update(lwm2m_context_t * lwm2mH, } #ifndef LWM2M_VERSION_1_0 +/** + * @brief Sends data to specified LWM2M server(s). + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer containing server ID(s) and URI(s). + * @param user_data Unused parameter. + */ static void prv_send(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { lwm2m_uri_t uri; lwm2m_uri_t *uris = NULL; @@ -637,6 +730,11 @@ static void prv_send(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { } #endif +/** + * @brief Updates the simulated battery level and reports it to the LWM2M server. + * + * @param context Pointer to the LWM2M context. + */ static void update_battery_level(lwm2m_context_t * context) { static time_t next_change_time = 0; @@ -665,6 +763,13 @@ static void update_battery_level(lwm2m_context_t * context) } } +/** + * @brief Adds a test object to the LWM2M server. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer. + * @param user_data Unused parameter. + */ static void prv_add(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) @@ -695,6 +800,13 @@ static void prv_add(lwm2m_context_t * lwm2mH, return; } +/** + * @brief Removes the specified object from the LWM2M server. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer. + * @param user_data Unused parameter. + */ static void prv_remove(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) @@ -719,7 +831,13 @@ static void prv_remove(lwm2m_context_t * lwm2mH, } #ifdef LWM2M_BOOTSTRAP - +/** + * @brief Initiates the bootstrap process by resetting the state and lifetime of bootstrap servers. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer. + * @param user_data Unused parameter. + */ static void prv_initiate_bootstrap(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) @@ -739,6 +857,13 @@ static void prv_initiate_bootstrap(lwm2m_context_t * lwm2mH, } } +/** + * @brief Displays the backup of security and server objects. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer. + * @param user_data Unused parameter. + */ static void prv_display_backup(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) @@ -768,6 +893,11 @@ static void prv_display_backup(lwm2m_context_t * lwm2mH, } } +/** + * @brief Backs up the content of security and server objects. + * + * @param context Pointer to the LWM2M context. + */ static void prv_backup_objects(lwm2m_context_t * context) { uint16_t i; @@ -799,6 +929,11 @@ static void prv_backup_objects(lwm2m_context_t * context) copy_server_object(backupObjectArray[1], (lwm2m_object_t *)LWM2M_LIST_FIND(context->objectList, LWM2M_SERVER_OBJECT_ID)); } +/** + * @brief Restores the content of security and server objects from backup. + * + * @param context Pointer to the LWM2M context. + */ static void prv_restore_objects(lwm2m_context_t * context) { lwm2m_object_t * targetP; @@ -822,6 +957,12 @@ static void prv_restore_objects(lwm2m_context_t * context) fprintf(stdout, "[BOOTSTRAP] ObjectList restored\r\n"); } +/** + * @brief Updates the bootstrap information based on changes in the context state. + * + * @param previousBootstrapState Pointer to the previous bootstrap state. + * @param context Pointer to the LWM2M context. + */ static void update_bootstrap_info(lwm2m_client_state_t * previousBootstrapState, lwm2m_context_t * context) { @@ -842,6 +983,9 @@ static void update_bootstrap_info(lwm2m_client_state_t * previousBootstrapState, } } +/** + * @brief Closes backup objects by cleaning up and freeing memory. + */ static void close_backup_object(void) { int i; for (i = 0; i < BACKUP_OBJECT_COUNT; i++) { @@ -864,6 +1008,13 @@ static void close_backup_object(void) { } #endif +/** + * @brief Displays the objects present in the LWM2M context. + * + * @param lwm2mH Pointer to the LWM2M context. + * @param buffer Pointer to a character buffer. + * @param user_data Unused parameter. + */ static void prv_display_objects(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { lwm2m_object_t *object; @@ -905,6 +1056,9 @@ static void prv_display_objects(lwm2m_context_t *lwm2mH, char *buffer, void *use } } +/** + * @brief Prints usage instructions for the LWM2M client. + */ void print_usage(void) { fprintf(stdout, "Usage: lwm2mclient [OPTION]\r\n"); @@ -927,21 +1081,28 @@ void print_usage(void) fprintf(stdout, "\r\n"); } +/** + * @brief Main function. + * + * @param argc Argument count - number of arguments. + * @param argv Argument vector. + * @return Execution status. + */ int main(int argc, char *argv[]) { - client_data_t data; - int result; - lwm2m_context_t * lwm2mH = NULL; - const char * localPort = "56830"; - const char * server = NULL; - const char * serverPort = LWM2M_STANDARD_PORT_STR; - const char *name = "testlwm2mclient"; - int lifetime = 300; - int batterylevelchanging = 0; - time_t reboot_time = 0; - int opt; - bool bootstrapRequested = false; - bool serverPortChanged = false; + client_data_t data; // Structure for client data + int result; // Variable to store the result of operations + lwm2m_context_t * lwm2mH = NULL; // Pointer to LWM2M context + const char * localPort = "56830"; // Default local UDP port + const char * server = NULL; // Pointer to server address + const char * serverPort = LWM2M_STANDARD_PORT_STR; // Default server port + const char *name = "testlwm2mclient"; // Default client name + int lifetime = 300; // Default client lifetime + int batterylevelchanging = 0; // Flag to indicate battery level change + time_t reboot_time = 0; // Time for rebooting + int opt; // Variable for command line options + bool bootstrapRequested = false; // Flag to indicate bootstrap request + bool serverPortChanged = false; // Flag to indicate if server port is changed #ifdef LWM2M_BOOTSTRAP lwm2m_client_state_t previousState = STATE_INITIAL; diff --git a/examples/server/lwm2mserver.c b/examples/server/lwm2mserver.c index 74fd031a..23c0781f 100644 --- a/examples/server/lwm2mserver.c +++ b/examples/server/lwm2mserver.c @@ -77,12 +77,23 @@ static int g_quit = 0; +/** + * @brief Prints an error message based on the provided status. + * + * @param status The status code representing the error. + */ static void prv_print_error(uint8_t status) { fprintf(stdout, "Error: "); print_status(stdout, status); fprintf(stdout, "\r\n"); } +/** + * @brief Returns a string representation of the provided LwM2M version. + * + * @param version The LwM2M version. + * @returns A string representing the LwM2M version. + */ static const char *prv_dump_version(lwm2m_version_t version) { switch (version) { case VERSION_MISSING: @@ -98,6 +109,11 @@ static const char *prv_dump_version(lwm2m_version_t version) { } } +/** + * @brief Prints the binding mode of a client. + * + * @param binding The binding mode of the client. + */ static void prv_dump_binding(lwm2m_binding_t binding) { if (BINDING_UNKNOWN == binding) { fprintf(stdout, "\tbinding: \"Not specified\"\r\n"); @@ -126,6 +142,11 @@ static void prv_dump_binding(lwm2m_binding_t binding) { } } +/** + * @brief Prints details of a client. + * + * @param targetP Pointer to the client structure. + */ static void prv_dump_client(lwm2m_client_t *targetP) { lwm2m_client_object_t *objectP; @@ -161,6 +182,13 @@ static void prv_dump_client(lwm2m_client_t *targetP) { fprintf(stdout, "\r\n"); } +/** + * @brief Prints details of all registered clients. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Buffer for output. + * @param user_data User data (unused). + */ static void prv_output_clients(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { lwm2m_client_t *targetP; @@ -179,6 +207,13 @@ static void prv_output_clients(lwm2m_context_t *lwm2mH, char *buffer, void *user } } +/** + * @brief Reads an ID from a buffer. + * + * @param buffer Buffer containing the ID. + * @param idP Pointer to store the read ID. + * @returns The number of items successfully read. + */ static int prv_read_id(char *buffer, uint16_t *idP) { int nb; int value; @@ -195,6 +230,11 @@ static int prv_read_id(char *buffer, uint16_t *idP) { return nb; } +/** + * @brief Prints a URI. + * + * @param uriP Pointer to the URI structure. + */ static void prv_printUri(const lwm2m_uri_t *uriP) { fprintf(stdout, "/%d", uriP->objectId); if (LWM2M_URI_IS_SET_INSTANCE(uriP)) @@ -211,6 +251,19 @@ static void prv_printUri(const lwm2m_uri_t *uriP) { #endif } +/** + * @brief Callback function to handle result of an operation. + * + * @param contextP Pointer to the LwM2M context. + * @param clientID ID of the client. + * @param uriP Pointer to the URI structure. + * @param status Status of the operation. + * @param block_info Pointer to block information. + * @param format Media type format. + * @param data Pointer to data. + * @param dataLength: Length of the data. + * @param userData: User data (unused). + */ static void prv_result_callback(lwm2m_context_t *contextP, uint16_t clientID, lwm2m_uri_t *uriP, int status, block_info_t *block_info, lwm2m_media_type_t format, uint8_t *data, size_t dataLength, void *userData) { @@ -230,6 +283,19 @@ static void prv_result_callback(lwm2m_context_t *contextP, uint16_t clientID, lw fflush(stdout); } +/** + * @brief Callback function to handle notifications. + * + * @param contextP Pointer to the LwM2M context. + * @param clientID ID of the client. + * @param uriP Pointer to the URI structure. + * @param count Notification count. + * @param block_info Pointer to block information. + * @param format Media type format. + * @param data Pointer to data. + * @param dataLength: Length of the data. + * @param userData: User data (unused). + */ static void prv_notify_callback(lwm2m_context_t *contextP, uint16_t clientID, lwm2m_uri_t *uriP, int count, block_info_t *block_info, lwm2m_media_type_t format, uint8_t *data, size_t dataLength, void *userData) { @@ -247,6 +313,13 @@ static void prv_notify_callback(lwm2m_context_t *contextP, uint16_t clientID, lw fflush(stdout); } +/** + * @brief Reads data from a client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Buffer containing client data. + * @param user_data User data (unused). + */ static void prv_read_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { uint16_t clientId; lwm2m_uri_t uri; @@ -284,6 +357,13 @@ static void prv_read_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_da fprintf(stdout, "Syntax error !"); } +/** + * @brief Discovers resources of a client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Buffer containing client data. + * @param user_data User data (unused). + */ static void prv_discover_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { uint16_t clientId; lwm2m_uri_t uri; @@ -321,6 +401,13 @@ static void prv_discover_client(lwm2m_context_t *lwm2mH, char *buffer, void *use fprintf(stdout, "Syntax error !"); } +/** + * @brief Writes data to a client. + * + * @param buffer Buffer containing client data. + * @param lwm2mH Pointer to the LwM2M context. + * @param partialUpdate Flag indicating whether it's a partial update. + */ static void prv_do_write_client(char *buffer, lwm2m_context_t *lwm2mH, bool partialUpdate) { uint16_t clientId; lwm2m_uri_t uri; @@ -394,6 +481,13 @@ static void prv_do_write_client(char *buffer, lwm2m_context_t *lwm2mH, bool part fprintf(stdout, "Syntax error !"); } +/** + * @brief Writes data to the LwM2M client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Data buffer containing information to be written. + * @param user_data User data (unused). + */ static void prv_write_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { /* unused parameter */ (void)user_data; @@ -401,6 +495,13 @@ static void prv_write_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_d prv_do_write_client(buffer, lwm2mH, false); } +/** + * @brief Updates data on the LwM2M client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Data buffer containing information to be updated. + * @param user_data User data (unused). + */ static void prv_update_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { /* unused parameter */ (void)user_data; @@ -408,6 +509,13 @@ static void prv_update_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_ prv_do_write_client(buffer, lwm2mH, true); } +/** + * @brief Sets time-related attributes for the LwM2M client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Data buffer containing attribute information. + * @param user_data User data (unused). + */ static void prv_time_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { uint16_t clientId; lwm2m_uri_t uri; @@ -473,6 +581,13 @@ static void prv_time_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_da fprintf(stdout, "Syntax error !"); } +/** + * @brief Sets value-related attributes for the LwM2M client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Data buffer containing attribute information. + * @param user_data User data (unused). + */ static void prv_attr_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { uint16_t clientId; lwm2m_uri_t uri; @@ -544,6 +659,13 @@ static void prv_attr_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_da fprintf(stdout, "Syntax error !"); } +/** + * @brief Clears attributes for the LwM2M client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Data buffer containing attribute information. + * @param user_data User data (unused). + */ static void prv_clear_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { uint16_t clientId; lwm2m_uri_t uri; @@ -587,6 +709,13 @@ static void prv_clear_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_d fprintf(stdout, "Syntax error !"); } +/** + * @brief Executes a command on the LwM2M client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Data buffer containing command information. + * @param user_data User data (unused). + */ static void prv_exec_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { uint16_t clientId; lwm2m_uri_t uri; @@ -631,6 +760,13 @@ static void prv_exec_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_da fprintf(stdout, "Syntax error !"); } +/** + * @brief Creates a new object instance on the LwM2M client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Data buffer containing object instance information. + * @param user_data User data (unused). + */ static void prv_create_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { uint16_t clientId; lwm2m_uri_t uri; @@ -735,6 +871,13 @@ static void prv_create_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_ fprintf(stdout, "Syntax error !"); } +/** + * @brief Deletes an object instance on the LwM2M client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Data buffer containing object instance information. + * @param user_data User data (unused). + */ static void prv_delete_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { uint16_t clientId; lwm2m_uri_t uri; @@ -772,6 +915,13 @@ static void prv_delete_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_ fprintf(stdout, "Syntax error !"); } +/** + * @brief Observes a resource on the LwM2M client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Data buffer containing observation information. + * @param user_data User data (unused). + */ static void prv_observe_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { uint16_t clientId; lwm2m_uri_t uri; @@ -809,6 +959,13 @@ static void prv_observe_client(lwm2m_context_t *lwm2mH, char *buffer, void *user fprintf(stdout, "Syntax error !"); } +/** + * @brief Cancels an observation on the LwM2M client. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param buffer Data buffer containing observation cancellation information. + * @param user_data User data (unused). + */ static void prv_cancel_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { uint16_t clientId; lwm2m_uri_t uri; @@ -846,6 +1003,19 @@ static void prv_cancel_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_ fprintf(stdout, "Syntax error !"); } +/** + * @brief Callback function for monitoring client registrations, updates, and unregistrations. + * + * @param lwm2mH Pointer to the LwM2M context. + * @param clientID ID of the client. + * @param uriP Pointer to the URI structure. + * @param status Status of the operation. + * @param block_info Pointer to block information. + * @param format Media format of the data. + * @param data Pointer to the data. + * @param dataLength Length of the data. + * @param userData User data (unused). + */ static void prv_monitor_callback(lwm2m_context_t *lwm2mH, uint16_t clientID, lwm2m_uri_t *uriP, int status, block_info_t *block_info, lwm2m_media_type_t format, uint8_t *data, size_t dataLength, void *userData) { @@ -884,16 +1054,32 @@ static void prv_monitor_callback(lwm2m_context_t *lwm2mH, uint16_t clientID, lwm fflush(stdout); } +/** + * @brief Callback function to quit the LwM2M server. + * + * @param lwm2mH Pointer to the LwM2M context (unused). + * @param buffer Pointer to the data buffer. + * @param user_data User data (unused). + */ static void prv_quit(lwm2m_context_t *lwm2mH, char *buffer, void *user_data) { /* unused parameters */ (void)lwm2mH; (void)user_data; + // Set the quit flag to terminate the program g_quit = 1; } +/** + * @brief Handles the SIGINT signal to quit the server. + * + * @param signum Signal number. + */ void handle_sigint(int signum) { g_quit = 2; } +/** + * @brief Prints usage information for the server. + */ void print_usage(void) { fprintf(stderr, "Usage: lwm2mserver [OPTION]\r\n"); fprintf(stderr, "Launch a LWM2M server on localhost.\r\n\n"); @@ -905,6 +1091,9 @@ void print_usage(void) { fprintf(stdout, "\r\n"); } +/** + * @brief Array containing command descriptions. + */ command_desc_t commands[] = {{"list", "List registered clients.", NULL, prv_output_clients, NULL}, {"read", "Read from a client.", " read CLIENT# URI\r\n" @@ -992,6 +1181,9 @@ command_desc_t commands[] = {{"list", "List registered clients.", NULL, prv_outp COMMAND_END_LIST}; +/** + * @brief Starts the CoAP server. + */ void startCoapServer() { int sock; const char *localPort = LWM2M_STANDARD_PORT_STR; @@ -1113,10 +1305,24 @@ void startCoapServer() { close(sock); connection_free(connList); } + +/** + * @brief Returns a test link. + * + * @return Test link string. + */ const char *testLink() { const char *mystr = "Hello from Wakaama server source !!!"; return mystr; } + +/** + * @brief Main function. + * + * @param argc Argument count - number of arguments. + * @param argv Argument vector. + * @return Execution status. + */ int main(int argc, char *argv[]) { // int addressFamily = AF_INET6; int opt; From 71e37febc352c62e8c6c61570c4e51350b2ea03f Mon Sep 17 00:00:00 2001 From: Nihad Ferhatovic Date: Thu, 16 May 2024 01:14:14 +0200 Subject: [PATCH 2/2] Ticket #36: Resolves PR findings. --- examples/client/lwm2mclient.c | 99 ++++++++++++++++++++++---------- examples/server/lwm2mserver.c | 103 ++++++++++++++++++++++++---------- 2 files changed, 140 insertions(+), 62 deletions(-) diff --git a/examples/client/lwm2mclient.c b/examples/client/lwm2mclient.c index 3f270756..0aa94ce5 100644 --- a/examples/client/lwm2mclient.c +++ b/examples/client/lwm2mclient.c @@ -81,17 +81,36 @@ #include #include +// Maximum size of a information packet in bytes +// Used for retrieving the data received #define MAX_PACKET_SIZE 2048 + +// Default IPv6 server address #define DEFAULT_SERVER_IPV6 "[::1]" + +// Default IPv4 server address #define DEFAULT_SERVER_IPV4 "127.0.0.1" +// Flag indicating a reboot +// Possible values: +// 0 - Default value +// Any other value triggers reboot process int g_reboot = 0; +// Flag indicating program termination +// Possible values: +// 0 - Default value +// 1 - Terminate the program forcefully +// 2 - Initiation of a graceful shutdown static int g_quit = 0; +// Number of supported client objects #define OBJ_COUNT 9 + +// Defined in wakaama/include/liblwm2m.h - Line 503 lwm2m_object_t * objArray[OBJ_COUNT]; -// only backup security and server objects +// Backup security and server objects +// Used if Bootstrap support is enabled for Lwm2m client # define BACKUP_OBJECT_COUNT 2 lwm2m_object_t * backupObjectArray[BACKUP_OBJECT_COUNT]; @@ -103,6 +122,7 @@ typedef struct int sock; #ifdef WITH_TINYDTLS dtls_connection_t * connList; + // Defined in wakaama/include/liblwm2m.h - Line 817 lwm2m_context_t * lwm2mH; #else connection_t * connList; @@ -155,6 +175,8 @@ void handle_value_changed(lwm2m_context_t * lwm2mH, const char * value, size_t valueLength) { + // Iterate function for finding element in a list of the lwm2m_list_t pointer by id + // Return the node with ID 'id' from the list 'head' or NULL if not found lwm2m_object_t * object = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri->objectId); if (NULL != object) @@ -325,7 +347,7 @@ void * lwm2m_connect_server(uint16_t secObjInstID, #endif /** - * @brief Closes the connection. + * @brief Closes the connection. If TinyDTLS is used, secure session and target is used. * * @param sessionH Session handler. * @param userData User data. @@ -350,6 +372,7 @@ void lwm2m_close_connection(void * sessionH, if (targetP == app_data->connList) { app_data->connList = targetP->next; + // Free a memory block allocated for target object. lwm2m_free(targetP); } else @@ -468,7 +491,7 @@ static void prv_output_servers(lwm2m_context_t * lwm2mH, } /** - * @brief Handles resource value changes or value change reports. + * @brief Handles/Changes value of resource or value change reports. * * @param lwm2mH Pointer to the LWM2M context. * @param buffer Pointer to a character buffer. @@ -478,34 +501,34 @@ static void prv_change(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) { - lwm2m_uri_t uri; - char * end = NULL; + lwm2m_uri_t uri; // URI structure + char * end = NULL; // Pointer to end of string int result; /* unused parameter */ (void)user_data; - end = get_end_of_arg(buffer); - if (end[0] == 0) goto syntax_error; + end = get_end_of_arg(buffer); // Get the end of the argument + if (end[0] == 0) goto syntax_error; // Check for syntax error - result = lwm2m_stringToUri(buffer, end - buffer, &uri); - if (result == 0) goto syntax_error; + result = lwm2m_stringToUri(buffer, end - buffer, &uri); // Convert string to URI + if (result == 0) goto syntax_error; // Check for conversion error - buffer = get_next_arg(end, &end); + buffer = get_next_arg(end, &end); // Get next argument if (buffer[0] == 0) { - fprintf(stderr, "report change!\n"); - lwm2m_resource_value_changed(lwm2mH, &uri); + fprintf(stderr, "report change!\n"); // Output change report + lwm2m_resource_value_changed(lwm2mH, &uri); // Handle resource value change } else { - handle_value_changed(lwm2mH, &uri, buffer, end - buffer); + handle_value_changed(lwm2mH, &uri, buffer, end - buffer); // Handle value change } return; syntax_error: - fprintf(stdout, "Syntax error !\n"); + fprintf(stdout, "Syntax error !\n"); // Output syntax error } /** @@ -544,7 +567,7 @@ static void prv_object_list(lwm2m_context_t * lwm2mH, } /** - * @brief Dumps the TLV data for a given instance of an object. + * @brief Prepares and prints the TLV (Type-Length-Value) data for a given instance of an object. * * @param lwm2mH Pointer to the LWM2M context. * @param objectP Pointer to the LWM2M object structure. @@ -568,12 +591,14 @@ static void prv_instance_dump(lwm2m_context_t * lwm2mH, return; } + // The function prints the TLV data along with its type and value in a structured format, + // making it easier for developers to understand and analyze. dump_tlv(stdout, numData, dataArray, 0); } /** - * @brief Dumps the TLV data for an object or its instances. + * @brief Prepares and prints the TLV (Type-Length-Value) data for an object and its instances. * * @param lwm2mH Pointer to the LWM2M context. * @param buffer Pointer to a character buffer. @@ -583,36 +608,45 @@ static void prv_object_dump(lwm2m_context_t * lwm2mH, char * buffer, void * user_data) { - lwm2m_uri_t uri; - char * end = NULL; - int result; - lwm2m_object_t * objectP; + lwm2m_uri_t uri; // Declaring a URI structure to store the parsed URI. + char * end = NULL; // Pointer to the end of the input buffer. + int result; // Variable to store the result of operations. + lwm2m_object_t * objectP; // Pointer to the LwM2M object. /* unused parameter */ (void)user_data; - end = get_end_of_arg(buffer); + end = get_end_of_arg(buffer); // Finding the end of the argument in the buffer. + + // Checking if the end of the argument is reached or not. if (end[0] == 0) goto syntax_error; + // Parsing the buffer into URI format. result = lwm2m_stringToUri(buffer, end - buffer, &uri); if (result == 0) goto syntax_error; + + // Checking if the URI specifies a resource, which is not allowed for dumping objects. if (LWM2M_URI_IS_SET_RESOURCE(&uri)) goto syntax_error; + // Finding the object specified by the URI in the object list of the LwM2M context. objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(lwm2mH->objectList, uri.objectId); if (objectP == NULL) { + // Print an error message if the object is not found. fprintf(stdout, "Object not found.\n"); return; } + // If an instance ID is set in a given URI structure, dump only that instance. if (LWM2M_URI_IS_SET_INSTANCE(&uri)) { prv_instance_dump(lwm2mH, objectP, uri.instanceId); } else { - lwm2m_list_t * instanceP; - + lwm2m_list_t * instanceP; + + // Looping through each instance of the object and dumping its information. for (instanceP = objectP->instanceList; instanceP != NULL ; instanceP = instanceP->next) { fprintf(stdout, "Instance %d:\r\n", instanceP->id); @@ -628,7 +662,8 @@ static void prv_object_dump(lwm2m_context_t * lwm2mH, } /** - * @brief Updates the registration with a specified server. + * @brief Updates the registration of specified server. + * Trigerred once update command is trigerred. Visit lwm2mclient.c line: 1169. * * @param lwm2mH Pointer to the LWM2M context. * @param buffer Pointer to a character buffer containing the server ID. @@ -641,10 +676,12 @@ static void prv_update(lwm2m_context_t * lwm2mH, /* unused parameter */ (void)user_data; - if (buffer[0] == 0) goto syntax_error; + if (buffer[0] == 0) goto syntax_error; // Checking if the buffer is empty. + // Converting the buffer content to an integer (server ID). uint16_t serverId = (uint16_t) atoi(buffer); - int res = lwm2m_update_registration(lwm2mH, serverId, false); + // Update the registration status of server in the LwM2M context based on the provided server ID. + int res = lwm2m_update_registration(lwm2mH, serverId, false); if (res != 0) { fprintf(stdout, "Registration update error: "); @@ -740,8 +777,8 @@ static void update_battery_level(lwm2m_context_t * context) static time_t next_change_time = 0; time_t tv_sec; - tv_sec = lwm2m_gettime(); - if (tv_sec < 0) return; + tv_sec = lwm2m_gettime(); // Get current time + if (tv_sec < 0) return; // Return if current time is negative if (next_change_time < tv_sec) { @@ -753,9 +790,9 @@ static void update_battery_level(lwm2m_context_t * context) if (0 > level) level = -level; if (lwm2m_stringToUri("/3/0/9", 6, &uri)) { - valueLength = sprintf(value, "%d", level); - fprintf(stderr, "New Battery Level: %d\n", level); - handle_value_changed(context, &uri, value, valueLength); + valueLength = sprintf(value, "%d", level); // Format battery level value + fprintf(stderr, "New Battery Level: %d\n", level); // Output new battery level + handle_value_changed(context, &uri, value, valueLength); // Handle value change } level = rand() % 20; if (0 > level) level = -level; diff --git a/examples/server/lwm2mserver.c b/examples/server/lwm2mserver.c index 23c0781f..b20f4786 100644 --- a/examples/server/lwm2mserver.c +++ b/examples/server/lwm2mserver.c @@ -73,8 +73,16 @@ #include "commandline.h" #include "connection.h" #include "lwm2mserver.h" + +// Maximum size of a information packet in bytes +// Used for retrieving the data received #define MAX_PACKET_SIZE 2048 +// Flag indicating program termination +// Possible values: +// 0 - Default value +// 1 - Terminate the program forcefully +// 2 - Initiation of a graceful shutdown static int g_quit = 0; /** @@ -208,7 +216,7 @@ static void prv_output_clients(lwm2m_context_t *lwm2mH, char *buffer, void *user } /** - * @brief Reads an ID from a buffer. + * @brief Reads an ID of the client from a buffer. * * @param buffer Buffer containing the ID. * @param idP Pointer to store the read ID. @@ -388,6 +396,10 @@ static void prv_discover_client(lwm2m_context_t *lwm2mH, char *buffer, void *use if (!check_end_of_args(end)) goto syntax_error; + // Performing Discovering of client based of its client ID. + // Creates, adjusts and sends get request to discover client. + // Returns 404 or 500 response if there are issues with finding the client, + // creating the transaction, or allocating memory for custom data. result = lwm2m_dm_discover(lwm2mH, clientId, &uri, prv_result_callback, NULL); if (result == 0) { @@ -482,7 +494,7 @@ static void prv_do_write_client(char *buffer, lwm2m_context_t *lwm2mH, bool part } /** - * @brief Writes data to the LwM2M client. + * @brief Wrapper for prv_do_write_client method. * * @param lwm2mH Pointer to the LwM2M context. * @param buffer Data buffer containing information to be written. @@ -496,7 +508,7 @@ static void prv_write_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_d } /** - * @brief Updates data on the LwM2M client. + * @brief Wrapper for prv_update_client method. * * @param lwm2mH Pointer to the LwM2M context. * @param buffer Data buffer containing information to be updated. @@ -521,7 +533,7 @@ static void prv_time_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_da lwm2m_uri_t uri; char *end = NULL; int result; - lwm2m_attributes_t attr; + lwm2m_attributes_t attr; // Defined in liblwm2m.h, line: 676 int nb; int value; @@ -593,7 +605,7 @@ static void prv_attr_client(lwm2m_context_t *lwm2mH, char *buffer, void *user_da lwm2m_uri_t uri; char *end = NULL; int result; - lwm2m_attributes_t attr; + lwm2m_attributes_t attr; // Defined in liblwm2m.h, line: 676 int nb; float value; @@ -1185,50 +1197,60 @@ command_desc_t commands[] = {{"list", "List registered clients.", NULL, prv_outp * @brief Starts the CoAP server. */ void startCoapServer() { - int sock; - const char *localPort = LWM2M_STANDARD_PORT_STR; - int addressFamily = AF_INET6; - lwm2m_context_t *lwm2mH = NULL; - connection_t *connList = NULL; - struct timeval tv; - int result; - fd_set readfds; - + int sock; // Socket file descriptor. + const char *localPort = LWM2M_STANDARD_PORT_STR; // Port number for CoAP server: 5683. + int addressFamily = AF_INET6; // Address family for socket. + lwm2m_context_t *lwm2mH = NULL; // LwM2M context pointer. + connection_t *connList = NULL; // List of connections. + struct timeval tv; // Timeout value for select(). + int result; // Result of operations. + fd_set readfds; // Set of file descriptors for select(). + + // Open socket for CoAP server. sock = create_socket(localPort, addressFamily); if (sock < 0) { fprintf(stderr, "Error opening socket: %d\r\n", errno); // return -1; } + // Initialize LwM2M context. lwm2mH = lwm2m_init(NULL); if (NULL == lwm2mH) { fprintf(stderr, "lwm2m_init() failed\r\n"); // return -1; } + // Set signal handler for SIGINT (Ctrl+C). signal(SIGINT, handle_sigint); fprintf(stdout, "> "); fflush(stdout); + // Set callback function monitoring of client registrations, updates, and unregistrations. lwm2m_set_monitoring_callback(lwm2mH, prv_monitor_callback, NULL); + // Main loop, iterates until quit flag is set while (0 == g_quit) { - FD_ZERO(&readfds); - FD_SET(sock, &readfds); - FD_SET(STDIN_FILENO, &readfds); + FD_ZERO(&readfds); // Initialize file descriptor set. + FD_SET(sock, &readfds); // Add socket to set. + FD_SET(STDIN_FILENO, &readfds); // Add stdin to set. - tv.tv_sec = 60; + tv.tv_sec = 60; // Timeout for select() (60 seconds). tv.tv_usec = 0; + // Perform LwM2M processing step and adjust timeout to the max time interval to wait. + // Returns 0 if everything is okay, other value if not result = lwm2m_step(lwm2mH, &(tv.tv_sec)); + // Check for error if (result != 0) { fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result); // return -1; } + // Wait for activity on sockets or stdin or timeout. + // Defined in select.h, line: 102 result = select(FD_SETSIZE, &readfds, 0, 0, &tv); - + // Check for error if (result < 0) { if (errno != EINTR) { fprintf(stderr, "Error in select(): %d\r\n", errno); @@ -1236,74 +1258,93 @@ void startCoapServer() { } else if (result > 0) { uint8_t buffer[MAX_PACKET_SIZE]; ssize_t numBytes; - + // Check if data is available on socket. if (FD_ISSET(sock, &readfds)) { struct sockaddr_storage addr; socklen_t addrLen; addrLen = sizeof(addr); + // Receive data from socket. numBytes = recvfrom(sock, buffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrLen); + // Check for error and does size of packet is bigger than max packet size - 2048 bytes if (numBytes == -1) { fprintf(stderr, "Error in recvfrom(): %d\r\n", errno); } else if (numBytes >= MAX_PACKET_SIZE) { fprintf(stderr, "Received packet >= MAX_PACKET_SIZE\r\n"); } else { - char s[INET6_ADDRSTRLEN]; - in_port_t port; - connection_t *connP; + // Packet received + char s[INET6_ADDRSTRLEN]; // Buffer to hold the IP address + in_port_t port; // Variable to hold the port number + connection_t *connP; // Pointer to a connection structure - s[0] = 0; + s[0] = 0; // Initialize the string buffer + // Checks if address is IPv4 or IPv6 if (AF_INET == addr.ss_family) { + // Cast the generic sockaddr to sockaddr_in (IPv4) struct sockaddr_in *saddr = (struct sockaddr_in *)&addr; + // Convert the network address to a presentation format inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN); - port = saddr->sin_port; + port = saddr->sin_port; // Get the port number } else if (AF_INET6 == addr.ss_family) { + // Cast the generic sockaddr to sockaddr_in6 (IPv6) struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr; + // Convert the network address to a presentation format inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN); port = saddr->sin6_port; } - + // Print information about the received packet fprintf(stderr, "%zd bytes received from [%s]:%hu\r\n", numBytes, s, ntohs(port)); output_buffer(stderr, buffer, (size_t)numBytes, 0); + // Find or create a connection structure associated with the sender connP = connection_find(connList, &addr, addrLen); if (connP == NULL) { + // If the connection does not exist, create a new one connP = connection_new_incoming(connList, sock, (struct sockaddr *)&addr, addrLen); if (connP != NULL) { + // If the connection creation is successful, update the connection list connList = connP; } } if (connP != NULL) { + // Valid connection found + // Dispatch the received packet using the LwM2M protocol lwm2m_handle_packet(lwm2mH, buffer, (size_t)numBytes, connP); } } + // Since data is not available on socket, check if it is available on stdin. } else if (FD_ISSET(STDIN_FILENO, &readfds)) { char *line = NULL; size_t bufLen = 0; + // Read command from stdin. numBytes = getline(&line, &bufLen, stdin); if (numBytes > 1) { line[numBytes] = 0; + // Handle commands received in buffer. + // If command is unknown, print unknown cmd. handle_command(lwm2mH, commands, line); fprintf(stdout, "\r\n"); } if (g_quit == 0) { + // if flag for quitting is not raised, print prompt fprintf(stdout, "> "); + // Force the contents of the buffer to be written to the output device immediately. fflush(stdout); } else { fprintf(stdout, "\r\n"); } - + // Free allocated memory for command line. lwm2m_free(line); } } } - - lwm2m_close(lwm2mH); - close(sock); - connection_free(connList); + // Clean up resources. + lwm2m_close(lwm2mH); // Close LwM2M context + close(sock); // Close socket + connection_free(connList); // Free list of connections } /**