Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: wakaama/management.c
- Revision:
- 3:a280069151ac
- Parent:
- 0:f9d13e09cf11
- Child:
- 15:d0f20339c1ad
--- a/wakaama/management.c Fri Apr 28 09:53:26 2017 +0000
+++ b/wakaama/management.c Fri Apr 28 18:13:27 2017 +0800
@@ -14,6 +14,8 @@
* David Navarro, Intel Corporation - initial API and implementation
* domedambrosio - Please refer to git log
* Toby Jaffey - Please refer to git log
+ * Bosch Software Innovations GmbH - Please refer to git log
+ * Pascal Rieux - Please refer to git log
*
*******************************************************************************/
/*
@@ -51,41 +53,215 @@
#ifdef LWM2M_CLIENT_MODE
-coap_status_t handle_dm_request(lwm2m_context_t * contextP,
+static int prv_readAttributes(multi_option_t * query,
+ lwm2m_attributes_t * attrP)
+{
+ int64_t intValue;
+ double floatValue;
+
+ memset(attrP, 0, sizeof(lwm2m_attributes_t));
+
+ while (query != NULL)
+ {
+ if (lwm2m_strncmp((char *)query->data, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN) == 0)
+ {
+ if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MIN_PERIOD)) return -1;
+ if (query->len == ATTR_MIN_PERIOD_LEN) return -1;
+
+ if (1 != utils_plainTextToInt64(query->data + ATTR_MIN_PERIOD_LEN, query->len - ATTR_MIN_PERIOD_LEN, &intValue)) return -1;
+ if (intValue < 0) return -1;
+
+ attrP->toSet |= LWM2M_ATTR_FLAG_MIN_PERIOD;
+ attrP->minPeriod = intValue;
+ }
+ else if (lwm2m_strncmp((char *)query->data, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN - 1) == 0)
+ {
+ if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MIN_PERIOD)) return -1;
+ if (query->len != ATTR_MIN_PERIOD_LEN - 1) return -1;
+
+ attrP->toClear |= LWM2M_ATTR_FLAG_MIN_PERIOD;
+ }
+ else if (lwm2m_strncmp((char *)query->data, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN) == 0)
+ {
+ if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MAX_PERIOD)) return -1;
+ if (query->len == ATTR_MAX_PERIOD_LEN) return -1;
+
+ if (1 != utils_plainTextToInt64(query->data + ATTR_MAX_PERIOD_LEN, query->len - ATTR_MAX_PERIOD_LEN, &intValue)) return -1;
+ if (intValue < 0) return -1;
+
+ attrP->toSet |= LWM2M_ATTR_FLAG_MAX_PERIOD;
+ attrP->maxPeriod = intValue;
+ }
+ else if (lwm2m_strncmp((char *)query->data, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN - 1) == 0)
+ {
+ if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MAX_PERIOD)) return -1;
+ if (query->len != ATTR_MAX_PERIOD_LEN - 1) return -1;
+
+ attrP->toClear |= LWM2M_ATTR_FLAG_MAX_PERIOD;
+ }
+ else if (lwm2m_strncmp((char *)query->data, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN) == 0)
+ {
+ if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_GREATER_THAN)) return -1;
+ if (query->len == ATTR_GREATER_THAN_LEN) return -1;
+
+ if (1 != utils_plainTextToFloat64(query->data + ATTR_GREATER_THAN_LEN, query->len - ATTR_GREATER_THAN_LEN, &floatValue)) return -1;
+
+ attrP->toSet |= LWM2M_ATTR_FLAG_GREATER_THAN;
+ attrP->greaterThan = floatValue;
+ }
+ else if (lwm2m_strncmp((char *)query->data, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN - 1) == 0)
+ {
+ if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_GREATER_THAN)) return -1;
+ if (query->len != ATTR_GREATER_THAN_LEN - 1) return -1;
+
+ attrP->toClear |= LWM2M_ATTR_FLAG_GREATER_THAN;
+ }
+ else if (lwm2m_strncmp((char *)query->data, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN) == 0)
+ {
+ if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_LESS_THAN)) return -1;
+ if (query->len == ATTR_LESS_THAN_LEN) return -1;
+
+ if (1 != utils_plainTextToFloat64(query->data + ATTR_LESS_THAN_LEN, query->len - ATTR_LESS_THAN_LEN, &floatValue)) return -1;
+
+ attrP->toSet |= LWM2M_ATTR_FLAG_LESS_THAN;
+ attrP->lessThan = floatValue;
+ }
+ else if (lwm2m_strncmp((char *)query->data, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN - 1) == 0)
+ {
+ if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_LESS_THAN)) return -1;
+ if (query->len != ATTR_LESS_THAN_LEN - 1) return -1;
+
+ attrP->toClear |= LWM2M_ATTR_FLAG_LESS_THAN;
+ }
+ else if (lwm2m_strncmp((char *)query->data, ATTR_STEP_STR, ATTR_STEP_LEN) == 0)
+ {
+ if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_STEP)) return -1;
+ if (query->len == ATTR_STEP_LEN) return -1;
+
+ if (1 != utils_plainTextToFloat64(query->data + ATTR_STEP_LEN, query->len - ATTR_STEP_LEN, &floatValue)) return -1;
+ if (floatValue < 0) return -1;
+
+ attrP->toSet |= LWM2M_ATTR_FLAG_STEP;
+ attrP->step = floatValue;
+ }
+ else if (lwm2m_strncmp((char *)query->data, ATTR_STEP_STR, ATTR_STEP_LEN - 1) == 0)
+ {
+ if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_STEP)) return -1;
+ if (query->len != ATTR_STEP_LEN - 1) return -1;
+
+ attrP->toClear |= LWM2M_ATTR_FLAG_STEP;
+ }
+ else return -1;
+
+ query = query->next;
+ }
+
+ return 0;
+}
+
+coap_status_t dm_handleRequest(lwm2m_context_t * contextP,
lwm2m_uri_t * uriP,
- void * fromSessionH,
+ lwm2m_server_t * serverP,
coap_packet_t * message,
coap_packet_t * response)
{
coap_status_t result;
+ lwm2m_media_type_t format;
+
+ LOG_ARG("Code: %02X, server status: %s", message->code, STR_STATUS(serverP->status));
+ LOG_URI(uriP);
+
+ if (IS_OPTION(message, COAP_OPTION_CONTENT_TYPE))
+ {
+ format = utils_convertMediaType(message->content_type);
+ }
+ else
+ {
+ format = LWM2M_CONTENT_TLV;
+ }
+
+ if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID)
+ {
+ return COAP_404_NOT_FOUND;
+ }
+
+ if (serverP->status != STATE_REGISTERED
+ && serverP->status != STATE_REG_UPDATE_NEEDED
+ && serverP->status != STATE_REG_FULL_UPDATE_NEEDED
+ && serverP->status != STATE_REG_UPDATE_PENDING)
+ {
+ return COAP_IGNORE;
+ }
+
+ // TODO: check ACL
switch (message->code)
{
case COAP_GET:
{
- char * buffer = NULL;
- int length = 0;
+ uint8_t * buffer = NULL;
+ size_t length = 0;
+ int res;
- result = object_read(contextP, uriP, &buffer, &length);
- if (result == COAP_205_CONTENT)
+ if (IS_OPTION(message, COAP_OPTION_OBSERVE))
{
- if (IS_OPTION(message, COAP_OPTION_OBSERVE))
+ lwm2m_data_t * dataP = NULL;
+ int size = 0;
+
+ result = object_readData(contextP, uriP, &size, &dataP);
+ if (COAP_205_CONTENT == result)
{
- result = handle_observe_request(contextP, uriP, fromSessionH, message, response);
+ result = observe_handleRequest(contextP, uriP, serverP, size, dataP, message, response);
+ if (COAP_205_CONTENT == result)
+ {
+ res = lwm2m_data_serialize(uriP, size, dataP, &format, &buffer);
+ if (res < 0)
+ {
+ result = COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ else
+ {
+ length = (size_t)res;
+ LOG_ARG("Observe Request[/%d/%d/%d]: %.*s\n", uriP->objectId, uriP->instanceId, uriP->resourceId, length, buffer);
+ }
+ }
+ lwm2m_data_free(size, dataP);
}
- if (result == COAP_205_CONTENT)
+ }
+ else if (IS_OPTION(message, COAP_OPTION_ACCEPT)
+ && message->accept_num == 1
+ && message->accept[0] == APPLICATION_LINK_FORMAT)
+ {
+ format = LWM2M_CONTENT_LINK;
+ result = object_discover(contextP, uriP, serverP, &buffer, &length);
+ }
+ else
+ {
+ if (IS_OPTION(message, COAP_OPTION_ACCEPT))
{
- coap_set_payload(response, buffer, length);
- // lwm2m_handle_packet will free buffer
+ format = utils_convertMediaType(message->accept[0]);
}
+
+ result = object_read(contextP, uriP, &format, &buffer, &length);
+ }
+ if (COAP_205_CONTENT == result)
+ {
+ coap_set_header_content_type(response, format);
+ coap_set_payload(response, buffer, length);
+ // lwm2m_handle_packet will free buffer
+ }
+ else
+ {
+ lwm2m_free(buffer);
}
}
break;
+
case COAP_POST:
{
if (!LWM2M_URI_IS_SET_INSTANCE(uriP))
{
- result = object_create(contextP, uriP, message->payload, message->payload_len);
+ result = object_create(contextP, uriP, format, message->payload, message->payload_len);
if (result == COAP_201_CREATED)
{
//longest uri is /65535/65535 = 12 + 1 (null) chars
@@ -103,18 +279,13 @@
break;
}
coap_set_header_location_path(response, location_path);
+
+ lwm2m_update_registration(contextP, 0, true);
}
}
else if (!LWM2M_URI_IS_SET_RESOURCE(uriP))
{
- if (object_isInstanceNew(contextP, uriP->objectId, uriP->instanceId))
- {
- result = object_create(contextP, uriP, message->payload, message->payload_len);
- }
- else
- {
- result = object_write(contextP, uriP, message->payload, message->payload_len);
- }
+ result = object_write(contextP, uriP, format, message->payload, message->payload_len);
}
else
{
@@ -122,54 +293,75 @@
}
}
break;
+
case COAP_PUT:
{
- if (LWM2M_URI_IS_SET_INSTANCE(uriP))
+ if (IS_OPTION(message, COAP_OPTION_URI_QUERY))
{
- result = object_write(contextP, uriP, message->payload, message->payload_len);
+ lwm2m_attributes_t attr;
+
+ if (0 != prv_readAttributes(message->uri_query, &attr))
+ {
+ result = COAP_400_BAD_REQUEST;
+ }
+ else
+ {
+ result = observe_setParameters(contextP, uriP, serverP, &attr);
+ }
+ }
+ else if (LWM2M_URI_IS_SET_INSTANCE(uriP))
+ {
+ result = object_write(contextP, uriP, format, message->payload, message->payload_len);
}
else
{
- result = BAD_REQUEST_4_00;
+ result = COAP_400_BAD_REQUEST;
}
}
break;
+
case COAP_DELETE:
{
- if (LWM2M_URI_IS_SET_INSTANCE(uriP) && !LWM2M_URI_IS_SET_RESOURCE(uriP))
+ if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || LWM2M_URI_IS_SET_RESOURCE(uriP))
{
- result = object_delete(contextP, uriP);
+ result = COAP_400_BAD_REQUEST;
}
else
{
- result = BAD_REQUEST_4_00;
+ result = object_delete(contextP, uriP);
+ if (result == COAP_202_DELETED)
+ {
+ lwm2m_update_registration(contextP, 0, true);
+ }
}
}
break;
+
default:
- result = BAD_REQUEST_4_00;
+ result = COAP_400_BAD_REQUEST;
break;
}
return result;
}
+
#endif
#ifdef LWM2M_SERVER_MODE
#define ID_AS_STRING_MAX_LEN 8
-static void dm_result_callback(lwm2m_transaction_t * transacP,
+static void prv_resultCallback(lwm2m_transaction_t * transacP,
void * message)
{
dm_data_t * dataP = (dm_data_t *)transacP->userData;
if (message == NULL)
{
- dataP->callback(((lwm2m_client_t*)transacP->peerP)->internalID,
+ dataP->callback(dataP->clientID,
&dataP->uri,
COAP_503_SERVICE_UNAVAILABLE,
- NULL, 0,
+ LWM2M_CONTENT_TEXT, NULL, 0,
dataP->userData);
}
else
@@ -187,14 +379,14 @@
locationString = coap_get_multi_option_as_string(packet->location_path);
if (locationString == NULL)
{
- fprintf(stderr, "Error: coap_get_multi_option_as_string() failed for Location_path option in dm_result_callback()\n");
+ LOG("Error: coap_get_multi_option_as_string() failed for Location_path option in prv_resultCallback()");
return;
}
result = lwm2m_stringToUri(locationString, strlen(locationString), &locationUri);
if (result == 0)
{
- fprintf(stderr, "Error: lwm2m_stringToUri() failed for Location_path option in dm_result_callback()\n");
+ LOG("Error: lwm2m_stringToUri() failed for Location_path option in prv_resultCallback()");
lwm2m_free(locationString);
return;
}
@@ -205,9 +397,10 @@
lwm2m_free(locationString);
}
- dataP->callback(((lwm2m_client_t*)transacP->peerP)->internalID,
+ dataP->callback(dataP->clientID,
&dataP->uri,
packet->code,
+ utils_convertMediaType(packet->content_type),
packet->payload,
packet->payload_len,
dataP->userData);
@@ -215,14 +408,15 @@
lwm2m_free(dataP);
}
-static int prv_make_operation(lwm2m_context_t * contextP,
- uint16_t clientID,
- lwm2m_uri_t * uriP,
- coap_method_t method,
- char * buffer,
- int length,
- lwm2m_result_callback_t callback,
- void * userData)
+static int prv_makeOperation(lwm2m_context_t * contextP,
+ uint16_t clientID,
+ lwm2m_uri_t * uriP,
+ coap_method_t method,
+ lwm2m_media_type_t format,
+ uint8_t * buffer,
+ int length,
+ lwm2m_result_callback_t callback,
+ void * userData)
{
lwm2m_client_t * clientP;
lwm2m_transaction_t * transaction;
@@ -231,11 +425,16 @@
clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
if (clientP == NULL) return COAP_404_NOT_FOUND;
- transaction = transaction_new(method, uriP, contextP->nextMID++, ENDPOINT_CLIENT, (void *)clientP);
- if (transaction == NULL) return INTERNAL_SERVER_ERROR_5_00;
+ transaction = transaction_new(clientP->sessionH, method, clientP->altPath, uriP, contextP->nextMID++, 4, NULL);
+ if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
- if (buffer != NULL)
+ if (method == COAP_GET)
{
+ coap_set_header_accept(transaction->message, format);
+ }
+ else if (buffer != NULL)
+ {
+ coap_set_header_content_type(transaction->message, format);
// TODO: Take care of fragmentation
coap_set_payload(transaction->message, buffer, length);
}
@@ -249,10 +448,11 @@
return COAP_500_INTERNAL_SERVER_ERROR;
}
memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t));
+ dataP->clientID = clientP->internalID;
dataP->callback = callback;
dataP->userData = userData;
- transaction->callback = dm_result_callback;
+ transaction->callback = prv_resultCallback;
transaction->userData = (void *)dataP;
}
@@ -267,19 +467,42 @@
lwm2m_result_callback_t callback,
void * userData)
{
- return prv_make_operation(contextP, clientID, uriP,
- COAP_GET, NULL, 0,
- callback, userData);
+ lwm2m_client_t * clientP;
+ lwm2m_media_type_t format;
+
+ LOG_ARG("clientID: %d", clientID);
+ LOG_URI(uriP);
+
+ clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
+ if (clientP == NULL) return COAP_404_NOT_FOUND;
+
+ if (clientP->supportJSON == true)
+ {
+ format = LWM2M_CONTENT_JSON;
+ }
+ else
+ {
+ format = LWM2M_CONTENT_TLV;
+ }
+
+ return prv_makeOperation(contextP, clientID, uriP,
+ COAP_GET,
+ format,
+ NULL, 0,
+ callback, userData);
}
int lwm2m_dm_write(lwm2m_context_t * contextP,
uint16_t clientID,
lwm2m_uri_t * uriP,
- char * buffer,
+ lwm2m_media_type_t format,
+ uint8_t * buffer,
int length,
lwm2m_result_callback_t callback,
void * userData)
{
+ LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length);
+ LOG_URI(uriP);
if (!LWM2M_URI_IS_SET_INSTANCE(uriP)
|| length == 0)
{
@@ -288,14 +511,16 @@
if (LWM2M_URI_IS_SET_RESOURCE(uriP))
{
- return prv_make_operation(contextP, clientID, uriP,
- COAP_PUT, buffer, length,
+ return prv_makeOperation(contextP, clientID, uriP,
+ COAP_PUT,
+ format, buffer, length,
callback, userData);
}
else
{
- return prv_make_operation(contextP, clientID, uriP,
- COAP_POST, buffer, length,
+ return prv_makeOperation(contextP, clientID, uriP,
+ COAP_POST,
+ format, buffer, length,
callback, userData);
}
}
@@ -303,37 +528,46 @@
int lwm2m_dm_execute(lwm2m_context_t * contextP,
uint16_t clientID,
lwm2m_uri_t * uriP,
- char * buffer,
+ lwm2m_media_type_t format,
+ uint8_t * buffer,
int length,
lwm2m_result_callback_t callback,
void * userData)
{
+ LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length);
+ LOG_URI(uriP);
if (!LWM2M_URI_IS_SET_RESOURCE(uriP))
{
return COAP_400_BAD_REQUEST;
}
- return prv_make_operation(contextP, clientID, uriP,
- COAP_POST, buffer, length,
+ return prv_makeOperation(contextP, clientID, uriP,
+ COAP_POST,
+ format, buffer, length,
callback, userData);
}
int lwm2m_dm_create(lwm2m_context_t * contextP,
uint16_t clientID,
lwm2m_uri_t * uriP,
- char * buffer,
+ lwm2m_media_type_t format,
+ uint8_t * buffer,
int length,
lwm2m_result_callback_t callback,
void * userData)
{
- if (LWM2M_URI_IS_SET_RESOURCE(uriP)
+ LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length);
+ LOG_URI(uriP);
+
+ if (LWM2M_URI_IS_SET_INSTANCE(uriP)
|| length == 0)
{
return COAP_400_BAD_REQUEST;
}
- return prv_make_operation(contextP, clientID, uriP,
- COAP_POST, buffer, length,
+ return prv_makeOperation(contextP, clientID, uriP,
+ COAP_POST,
+ format, buffer, length,
callback, userData);
}
@@ -343,14 +577,201 @@
lwm2m_result_callback_t callback,
void * userData)
{
+ LOG_ARG("clientID: %d", clientID);
+ LOG_URI(uriP);
if (!LWM2M_URI_IS_SET_INSTANCE(uriP)
|| LWM2M_URI_IS_SET_RESOURCE(uriP))
{
return COAP_400_BAD_REQUEST;
}
- return prv_make_operation(contextP, clientID, uriP,
- COAP_DELETE, NULL, 0,
+ return prv_makeOperation(contextP, clientID, uriP,
+ COAP_DELETE,
+ LWM2M_CONTENT_TEXT, NULL, 0,
callback, userData);
}
+
+int lwm2m_dm_write_attributes(lwm2m_context_t * contextP,
+ uint16_t clientID,
+ lwm2m_uri_t * uriP,
+ lwm2m_attributes_t * attrP,
+ lwm2m_result_callback_t callback,
+ void * userData)
+{
+#define _PRV_BUFFER_SIZE 32
+ lwm2m_client_t * clientP;
+ lwm2m_transaction_t * transaction;
+ coap_packet_t * coap_pkt;
+ uint8_t buffer[_PRV_BUFFER_SIZE];
+ size_t length;
+
+ LOG_ARG("clientID: %d", clientID);
+ LOG_URI(uriP);
+ if (attrP == NULL) return COAP_400_BAD_REQUEST;
+
+ if (0 != (attrP->toSet & attrP->toClear)) return COAP_400_BAD_REQUEST;
+ if (0 != (attrP->toSet & ATTR_FLAG_NUMERIC) && !LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST;
+ if (ATTR_FLAG_NUMERIC == (attrP->toSet & ATTR_FLAG_NUMERIC)
+ && (attrP->lessThan + 2 * attrP->step >= attrP->greaterThan)) return COAP_400_BAD_REQUEST;
+
+ clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
+ if (clientP == NULL) return COAP_404_NOT_FOUND;
+
+ transaction = transaction_new(clientP->sessionH, COAP_PUT, clientP->altPath, uriP, contextP->nextMID++, 4, NULL);
+ if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
+
+ if (callback != NULL)
+ {
+ dm_data_t * dataP;
+
+ dataP = (dm_data_t *)lwm2m_malloc(sizeof(dm_data_t));
+ if (dataP == NULL)
+ {
+ transaction_free(transaction);
+ return COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t));
+ dataP->clientID = clientP->internalID;
+ dataP->callback = callback;
+ dataP->userData = userData;
+
+ transaction->callback = prv_resultCallback;
+ transaction->userData = (void *)dataP;
+ }
+
+ coap_pkt = (coap_packet_t *)transaction->message;
+ free_multi_option(coap_pkt->uri_query);
+ if (attrP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD)
+ {
+ memcpy(buffer, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN);
+ length = utils_intToText(attrP->minPeriod, buffer + ATTR_MIN_PERIOD_LEN, _PRV_BUFFER_SIZE - ATTR_MIN_PERIOD_LEN);
+ if (length == 0)
+ {
+ transaction_free(transaction);
+ return COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_MIN_PERIOD_LEN + length, 0);
+ SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+ }
+ if (attrP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD)
+ {
+ memcpy(buffer, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN);
+ length = utils_intToText(attrP->maxPeriod, buffer + ATTR_MAX_PERIOD_LEN, _PRV_BUFFER_SIZE - ATTR_MAX_PERIOD_LEN);
+ if (length == 0)
+ {
+ transaction_free(transaction);
+ return COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_MAX_PERIOD_LEN + length, 0);
+ SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+ }
+ if (attrP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN)
+ {
+ memcpy(buffer, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN);
+ length = utils_floatToText(attrP->greaterThan, buffer + ATTR_GREATER_THAN_LEN, _PRV_BUFFER_SIZE - ATTR_GREATER_THAN_LEN);
+ if (length == 0)
+ {
+ transaction_free(transaction);
+ return COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_GREATER_THAN_LEN + length, 0);
+ SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+ }
+ if (attrP->toSet & LWM2M_ATTR_FLAG_LESS_THAN)
+ {
+ memcpy(buffer, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN);
+ length = utils_floatToText(attrP->lessThan, buffer + ATTR_LESS_THAN_LEN, _PRV_BUFFER_SIZE - ATTR_LESS_THAN_LEN);
+ if (length == 0)
+ {
+ transaction_free(transaction);
+ return COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_LESS_THAN_LEN + length, 0);
+ SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+ }
+ if (attrP->toSet & LWM2M_ATTR_FLAG_STEP)
+ {
+ memcpy(buffer, ATTR_STEP_STR, ATTR_STEP_LEN);
+ length = utils_floatToText(attrP->step, buffer + ATTR_STEP_LEN, _PRV_BUFFER_SIZE - ATTR_STEP_LEN);
+ if (length == 0)
+ {
+ transaction_free(transaction);
+ return COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_STEP_LEN + length, 0);
+ SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+ }
+ if (attrP->toClear & LWM2M_ATTR_FLAG_MIN_PERIOD)
+ {
+ coap_add_multi_option(&(coap_pkt->uri_query), ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN -1, 0);
+ SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+ }
+ if (attrP->toClear & LWM2M_ATTR_FLAG_MAX_PERIOD)
+ {
+ coap_add_multi_option(&(coap_pkt->uri_query), ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN - 1, 0);
+ SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+ }
+ if (attrP->toClear & LWM2M_ATTR_FLAG_GREATER_THAN)
+ {
+ coap_add_multi_option(&(coap_pkt->uri_query), ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN - 1, 0);
+ SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+ }
+ if (attrP->toClear & LWM2M_ATTR_FLAG_LESS_THAN)
+ {
+ coap_add_multi_option(&(coap_pkt->uri_query), ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN - 1, 0);
+ SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+ }
+ if (attrP->toClear & LWM2M_ATTR_FLAG_STEP)
+ {
+ coap_add_multi_option(&(coap_pkt->uri_query), ATTR_STEP_STR, ATTR_STEP_LEN - 1, 0);
+ SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY);
+ }
+
+ contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);
+
+ return transaction_send(contextP, transaction);
+}
+
+int lwm2m_dm_discover(lwm2m_context_t * contextP,
+ uint16_t clientID,
+ lwm2m_uri_t * uriP,
+ lwm2m_result_callback_t callback,
+ void * userData)
+{
+ lwm2m_client_t * clientP;
+ lwm2m_transaction_t * transaction;
+ dm_data_t * dataP;
+
+ LOG_ARG("clientID: %d", clientID);
+ LOG_URI(uriP);
+ clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID);
+ if (clientP == NULL) return COAP_404_NOT_FOUND;
+
+ transaction = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, NULL);
+ if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
+
+ coap_set_header_accept(transaction->message, LWM2M_CONTENT_LINK);
+
+ if (callback != NULL)
+ {
+ dataP = (dm_data_t *)lwm2m_malloc(sizeof(dm_data_t));
+ if (dataP == NULL)
+ {
+ transaction_free(transaction);
+ return COAP_500_INTERNAL_SERVER_ERROR;
+ }
+ memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t));
+ dataP->clientID = clientP->internalID;
+ dataP->callback = callback;
+ dataP->userData = userData;
+
+ transaction->callback = prv_resultCallback;
+ transaction->userData = (void *)dataP;
+ }
+
+ contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction);
+
+ return transaction_send(contextP, transaction);
+}
+
#endif