diff --git a/pkg/wakaama/Makefile.dep b/pkg/wakaama/Makefile.dep index 60f69d3f09..6d5124f54c 100644 --- a/pkg/wakaama/Makefile.dep +++ b/pkg/wakaama/Makefile.dep @@ -2,6 +2,7 @@ USEMODULE += wakaama_core wakaama_core_coap13 wakaama_client # include contrib code (platform adaption and client implementation) USEMODULE += wakaama_contrib +USEMODULE += uri_parser # this allows us to include our own objects, implemented in the 'objects' # folder, by adding 'wakaama_objects_' modules diff --git a/pkg/wakaama/contrib/lwm2m_client_connection.c b/pkg/wakaama/contrib/lwm2m_client_connection.c index 88a301babf..b772997e24 100644 --- a/pkg/wakaama/contrib/lwm2m_client_connection.c +++ b/pkg/wakaama/contrib/lwm2m_client_connection.c @@ -41,16 +41,18 @@ #include #include "kernel_defines.h" #include "net/netif.h" +#include "uri_parser.h" #include "liblwm2m.h" #include "lwm2m_client.h" #include "lwm2m_client_config.h" #include "lwm2m_client_connection.h" +#include "objects/common.h" #define ENABLE_DEBUG 0 #include "debug.h" -#define URI_LENGTH 256 +#define MAX_URI_LENGTH 256 /** * @brief Creates a new connection object based on the security instance @@ -61,22 +63,8 @@ * * @return Pointer to the new connection */ -static lwm2m_client_connection_t *_connection_create(int instance_id, - lwm2m_client_data_t *client_data); - -/** - * @brief Gets the URI from an @p instance_id of a @p obj security object - * - * @param[in] obj security object - * @param[in] instance_id ID number of the instance of security object - * @param[out] uri_buffer buffer to place the URI - * @param[in] buffer_size size of @p uri_buffer - * - * @return Pointer to the URI in success - * @return NULL otherwise - */ -static char *_get_uri_from_security_obj(lwm2m_object_t *obj, int instance_id, - char *uri_buffer, int buffer_size); +static lwm2m_client_connection_t *_connection_create(uint16_t sec_obj_inst_id, + lwm2m_client_data_t *client_data); /** * @brief Sends data with a specified connection @p conn @@ -93,27 +81,6 @@ static int _connection_send(lwm2m_client_connection_t *conn, uint8_t *buffer, size_t buffer_size, lwm2m_client_data_t *client_data); -/** - * @brief Parses the schema of a given URI and sets the default port for the - * found valid schema - * @param[in] uri URI string to parse - * @param[out] port will point to the default port string - * @param[in] instance_id instance ID of the connection - * - * @return pointer to the character after the schema, if found - * @return NULL if no valid schema found - */ -static char *_parse_schema(char *uri, char **port, int instance_id); - -/** - * @brief Parses the host and the port part after the schema - * - * @param[in, out] host pointer to the beginning of the host - * @param[out] port pointer to store the position of the port - * @param[in] default_port default port - */ -static void _parse_host_and_port(char **host, char **port, char *default_port); - /** * @brief Tries to find an interface in the host string. If not, it will check * if there only exists one interface, and will use it @@ -127,25 +94,11 @@ static netif_t *_get_interface(char *host); void *lwm2m_connect_server(uint16_t sec_obj_inst_id, void *user_data) { lwm2m_client_data_t *client_data = (lwm2m_client_data_t *)user_data; - lwm2m_client_connection_t *new_conn = NULL; + lwm2m_client_connection_t *new_conn; - /* get the security object list */ - lwm2m_object_t *security_objects = (lwm2m_object_t *)LWM2M_LIST_FIND( - client_data->lwm2m_ctx->objectList, - LWM2M_SECURITY_OBJECT_ID); - if (!security_objects) { - DEBUG("[lwm2m_connect_server] Could not find sec object\n"); - return NULL; - } + DEBUG("[lwm2m_connect_server] Connecting to server in security instance %d\n", sec_obj_inst_id); - /* get the security object instance */ - lwm2m_list_t *instance = LWM2M_LIST_FIND(security_objects, sec_obj_inst_id); - if (instance == NULL) { - DEBUG("[lwm2m_connect_server] Could not find sec object instance\n"); - return NULL; - } - - new_conn = _connection_create(instance->id, client_data); + new_conn = _connection_create(sec_obj_inst_id, client_data); if (new_conn) { DEBUG("[lwm2m_connect_server] Connection created\n"); /* if the connections list is empty this is the first node, if not @@ -176,7 +129,7 @@ void lwm2m_close_connection(void *sessionH, void *user_data) else { lwm2m_client_connection_t *prev = client_data->conn_list; - while(prev != NULL && prev->next != conn) { + while (prev != NULL && prev->next != conn) { prev = prev->next; } if (prev != NULL) { @@ -232,7 +185,7 @@ lwm2m_client_connection_t *lwm2m_client_connection_find( DEBUG("Conn list is null!"); } - while(conn != NULL) { + while (conn != NULL) { ipv6_addr_to_str(ip, (ipv6_addr_t *)&conn->remote.addr.ipv6, ip_len); DEBUG("Comparing to [%s]:%d\n", ip, conn->remote.port); if ((conn->remote.port == remote->port) && @@ -267,51 +220,6 @@ static int _connection_send(lwm2m_client_connection_t *conn, uint8_t *buffer, return 0; } -static char *_parse_schema(char *uri, char **port, int instance_id) -{ - char *host = NULL; - if (!uri) { - DEBUG("[_parse_schema] Could not get URI of instance\n"); - goto out; - } - - /* parse the URI in the form "coaps://[host]:port" */ - if (!strncmp(uri, SCHEME_COAPS, sizeof(SCHEME_COAPS) - 1)) { - host = uri + sizeof(SCHEME_COAPS) - 1; - } - else if (!strncmp(uri, SCHEME_COAP, sizeof(SCHEME_COAP) - 1)) { - host = uri + sizeof(SCHEME_COAP) - 1; - } - - *port = (IS_ACTIVE(CONFIG_LWM2M_BOOTSTRAP) && !instance_id) ? - CONFIG_LWM2M_BSSERVER_PORT : CONFIG_LWM2M_STANDARD_PORT; -out: - return host; -} - -static void _parse_host_and_port(char **host, char **port, char *default_port) -{ - char *_port = NULL; - char *pos = *host; - - if (pos[0] == '[') { - (*host)++; - pos = strrchr(pos, ']'); - } - - _port = strrchr(pos, ':'); - if (!_port) { - *pos = '\0'; - DEBUG("[_parse_port] No port specified, using default\n"); - _port = default_port; - } - else { - *(_port - 1) = '\0'; - _port++; - } - *port = _port; -} - static netif_t *_get_interface(char *host) { netif_t *netif = NULL; @@ -338,41 +246,60 @@ static netif_t *_get_interface(char *host) return netif; } -static lwm2m_client_connection_t *_connection_create(int instance_id, - lwm2m_client_data_t *client_data) +static lwm2m_client_connection_t *_connection_create(uint16_t sec_obj_inst_id, + lwm2m_client_data_t *client_data) { lwm2m_client_connection_t *conn = NULL; - char *default_port; - char *host; + char uri[MAX_URI_LENGTH]; char *port; - char *uri; - char uri_buf[URI_LENGTH + 1]; + bool is_bootstrap; - memset(uri_buf, 0, sizeof(uri_buf)); DEBUG("Creating connection\n"); - /* get the list of security objects */ - lwm2m_object_t *security_objects = (lwm2m_object_t *)LWM2M_LIST_FIND( - client_data->lwm2m_ctx->objectList, - LWM2M_SECURITY_OBJECT_ID); - if (!security_objects) { - DEBUG("[_connection_create] Could not find any security object\n"); - return NULL; + /* prepare Server URI query */ + lwm2m_uri_t resource_uri = { + .objectId = LWM2M_SECURITY_URI_ID, + .instanceId = sec_obj_inst_id, + .resourceId = LWM2M_SECURITY_URI_ID, + .flag = LWM2M_URI_FLAG_OBJECT_ID | LWM2M_URI_FLAG_INSTANCE_ID | LWM2M_URI_FLAG_RESOURCE_ID + }; + + int res = lwm2m_get_string(client_data, &resource_uri, uri, ARRAY_SIZE(uri)); + if (res < 0) { + DEBUG("[_connection_create] Could not get security instance URI\n"); + goto out; } - /* get the URI from the security object instance */ - uri = _get_uri_from_security_obj(security_objects, instance_id, - uri_buf, sizeof(uri_buf) - 1); + uri_parser_result_t parsed_uri; + res = uri_parser_process_string(&parsed_uri, uri); - host = _parse_schema(uri, &default_port, instance_id); - if (!host) { + if (0 != res || !parsed_uri.host) { DEBUG("[_connection_create] Could not parse URI schema\n"); - goto free_out; + goto out; } - _parse_host_and_port(&host, &port, default_port); - DEBUG("[_connection_create] Creating connection to Host: %s, Port: %s\n", - host, port); + resource_uri.resourceId = LWM2M_SECURITY_BOOTSTRAP_ID; + res = lwm2m_get_bool(client_data, &resource_uri, &is_bootstrap); + if (res < 0) { + DEBUG("[_connection_create] Could verify if the server is bootstrap\n"); + goto out; + } + + /* if no port specified, use the default server or BS-server ports */ + if (!parsed_uri.port) { + if (is_bootstrap) { + port = CONFIG_LWM2M_BSSERVER_PORT; + } + else { + port = CONFIG_LWM2M_STANDARD_PORT; + } + } + else { + port = parsed_uri.port; + } + + DEBUG("[_connection_create] Creating connection to Host: %.*s, Port: %s\n", + parsed_uri.ipv6addr_len, parsed_uri.ipv6addr, port); /* allocate new connection */ conn = lwm2m_malloc(sizeof(lwm2m_client_connection_t)); @@ -387,7 +314,8 @@ static lwm2m_client_connection_t *_connection_create(int instance_id, conn->remote.netif = SOCK_ADDR_ANY_NETIF; conn->remote.port = atoi(port); - if (!ipv6_addr_from_str((ipv6_addr_t *)&conn->remote.addr.ipv6, host)) { + if (!ipv6_addr_from_buf((ipv6_addr_t *)&conn->remote.addr.ipv6, parsed_uri.ipv6addr, + parsed_uri.ipv6addr_len)) { DEBUG("[_connection_create] IPv6 address malformed\n"); goto free_out; } @@ -401,7 +329,7 @@ static lwm2m_client_connection_t *_connection_create(int instance_id, * if not, check the number of interfaces and default to the first if there * is only one defined. */ if (ipv6_addr_is_link_local((ipv6_addr_t *)&conn->remote.addr.ipv6)) { - netif_t *netif = _get_interface(host); + netif_t *netif = _get_interface(parsed_uri.host); if (netif == NULL) { goto free_out; } @@ -423,29 +351,3 @@ free_out: out: return conn; } - -static char *_get_uri_from_security_obj(lwm2m_object_t *obj, int instance_id, - char *uri_buffer, int buffer_size) -{ - int size = 1; - char *res = NULL; - - /* allocate a data instance */ - lwm2m_data_t *data = lwm2m_data_new(size); - - /* get the uri from the security object */ - data->id = 0; - obj->readFunc(instance_id, &size, &data, obj); - - if (data != NULL && data->type == LWM2M_TYPE_STRING && - data->value.asBuffer.length > 0) { - if ((size_t)buffer_size > data->value.asBuffer.length) { - strncpy(uri_buffer, (char *)data->value.asBuffer.buffer, - data->value.asBuffer.length); - res = uri_buffer; - } - } - - lwm2m_data_free(size, data); - return res; -} diff --git a/pkg/wakaama/include/lwm2m_client_config.h b/pkg/wakaama/include/lwm2m_client_config.h index c870f958a0..c2e43850a9 100644 --- a/pkg/wakaama/include/lwm2m_client_config.h +++ b/pkg/wakaama/include/lwm2m_client_config.h @@ -23,7 +23,6 @@ * @author Leandro Lanzieri */ - #ifndef LWM2M_CLIENT_CONFIG_H #define LWM2M_CLIENT_CONFIG_H