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.
management.c
00001 /******************************************************************************* 00002 * 00003 * Copyright (c) 2013, 2014 Intel Corporation and others. 00004 * All rights reserved. This program and the accompanying materials 00005 * are made available under the terms of the Eclipse Public License v1.0 00006 * and Eclipse Distribution License v1.0 which accompany this distribution. 00007 * 00008 * The Eclipse Public License is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * The Eclipse Distribution License is available at 00011 * http://www.eclipse.org/org/documents/edl-v10.php. 00012 * 00013 * Contributors: 00014 * David Navarro, Intel Corporation - initial API and implementation 00015 * domedambrosio - Please refer to git log 00016 * Toby Jaffey - Please refer to git log 00017 * Bosch Software Innovations GmbH - Please refer to git log 00018 * Pascal Rieux - Please refer to git log 00019 * 00020 *******************************************************************************/ 00021 /* 00022 Copyright (c) 2013, 2014 Intel Corporation 00023 00024 Redistribution and use in source and binary forms, with or without modification, 00025 are permitted provided that the following conditions are met: 00026 00027 * Redistributions of source code must retain the above copyright notice, 00028 this list of conditions and the following disclaimer. 00029 * Redistributions in binary form must reproduce the above copyright notice, 00030 this list of conditions and the following disclaimer in the documentation 00031 and/or other materials provided with the distribution. 00032 * Neither the name of Intel Corporation nor the names of its contributors 00033 may be used to endorse or promote products derived from this software 00034 without specific prior written permission. 00035 00036 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00037 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00038 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00039 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00040 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00041 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00042 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00043 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00044 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 00045 THE POSSIBILITY OF SUCH DAMAGE. 00046 00047 David Navarro <david.navarro@intel.com> 00048 00049 */ 00050 00051 #include "internals.h" 00052 #include <stdio.h> 00053 00054 00055 #ifdef LWM2M_CLIENT_MODE 00056 static int prv_readAttributes(multi_option_t * query, 00057 lwm2m_attributes_t * attrP) 00058 { 00059 int64_t intValue; 00060 double floatValue; 00061 00062 memset(attrP, 0, sizeof(lwm2m_attributes_t)); 00063 00064 while (query != NULL) 00065 { 00066 if (lwm2m_strncmp((char *)query->data, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN) == 0) 00067 { 00068 if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MIN_PERIOD)) return -1; 00069 if (query->len == ATTR_MIN_PERIOD_LEN) return -1; 00070 00071 if (1 != utils_plainTextToInt64(query->data + ATTR_MIN_PERIOD_LEN, query->len - ATTR_MIN_PERIOD_LEN, &intValue)) return -1; 00072 if (intValue < 0) return -1; 00073 00074 attrP->toSet |= LWM2M_ATTR_FLAG_MIN_PERIOD; 00075 attrP->minPeriod = intValue; 00076 } 00077 else if (lwm2m_strncmp((char *)query->data, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN - 1) == 0) 00078 { 00079 if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MIN_PERIOD)) return -1; 00080 if (query->len != ATTR_MIN_PERIOD_LEN - 1) return -1; 00081 00082 attrP->toClear |= LWM2M_ATTR_FLAG_MIN_PERIOD; 00083 } 00084 else if (lwm2m_strncmp((char *)query->data, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN) == 0) 00085 { 00086 if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MAX_PERIOD)) return -1; 00087 if (query->len == ATTR_MAX_PERIOD_LEN) return -1; 00088 00089 if (1 != utils_plainTextToInt64(query->data + ATTR_MAX_PERIOD_LEN, query->len - ATTR_MAX_PERIOD_LEN, &intValue)) return -1; 00090 if (intValue < 0) return -1; 00091 00092 attrP->toSet |= LWM2M_ATTR_FLAG_MAX_PERIOD; 00093 attrP->maxPeriod = intValue; 00094 } 00095 else if (lwm2m_strncmp((char *)query->data, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN - 1) == 0) 00096 { 00097 if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_MAX_PERIOD)) return -1; 00098 if (query->len != ATTR_MAX_PERIOD_LEN - 1) return -1; 00099 00100 attrP->toClear |= LWM2M_ATTR_FLAG_MAX_PERIOD; 00101 } 00102 else if (lwm2m_strncmp((char *)query->data, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN) == 0) 00103 { 00104 if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_GREATER_THAN)) return -1; 00105 if (query->len == ATTR_GREATER_THAN_LEN) return -1; 00106 00107 if (1 != utils_plainTextToFloat64(query->data + ATTR_GREATER_THAN_LEN, query->len - ATTR_GREATER_THAN_LEN, &floatValue)) return -1; 00108 00109 attrP->toSet |= LWM2M_ATTR_FLAG_GREATER_THAN; 00110 attrP->greaterThan = floatValue; 00111 } 00112 else if (lwm2m_strncmp((char *)query->data, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN - 1) == 0) 00113 { 00114 if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_GREATER_THAN)) return -1; 00115 if (query->len != ATTR_GREATER_THAN_LEN - 1) return -1; 00116 00117 attrP->toClear |= LWM2M_ATTR_FLAG_GREATER_THAN; 00118 } 00119 else if (lwm2m_strncmp((char *)query->data, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN) == 0) 00120 { 00121 if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_LESS_THAN)) return -1; 00122 if (query->len == ATTR_LESS_THAN_LEN) return -1; 00123 00124 if (1 != utils_plainTextToFloat64(query->data + ATTR_LESS_THAN_LEN, query->len - ATTR_LESS_THAN_LEN, &floatValue)) return -1; 00125 00126 attrP->toSet |= LWM2M_ATTR_FLAG_LESS_THAN; 00127 attrP->lessThan = floatValue; 00128 } 00129 else if (lwm2m_strncmp((char *)query->data, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN - 1) == 0) 00130 { 00131 if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_LESS_THAN)) return -1; 00132 if (query->len != ATTR_LESS_THAN_LEN - 1) return -1; 00133 00134 attrP->toClear |= LWM2M_ATTR_FLAG_LESS_THAN; 00135 } 00136 else if (lwm2m_strncmp((char *)query->data, ATTR_STEP_STR, ATTR_STEP_LEN) == 0) 00137 { 00138 if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_STEP)) return -1; 00139 if (query->len == ATTR_STEP_LEN) return -1; 00140 00141 if (1 != utils_plainTextToFloat64(query->data + ATTR_STEP_LEN, query->len - ATTR_STEP_LEN, &floatValue)) return -1; 00142 if (floatValue < 0) return -1; 00143 00144 attrP->toSet |= LWM2M_ATTR_FLAG_STEP; 00145 attrP->step = floatValue; 00146 } 00147 else if (lwm2m_strncmp((char *)query->data, ATTR_STEP_STR, ATTR_STEP_LEN - 1) == 0) 00148 { 00149 if (0 != ((attrP->toSet | attrP->toClear) & LWM2M_ATTR_FLAG_STEP)) return -1; 00150 if (query->len != ATTR_STEP_LEN - 1) return -1; 00151 00152 attrP->toClear |= LWM2M_ATTR_FLAG_STEP; 00153 } 00154 else return -1; 00155 00156 query = query->next; 00157 } 00158 00159 return 0; 00160 } 00161 00162 coap_status_t dm_handleRequest(lwm2m_context_t * contextP, 00163 lwm2m_uri_t * uriP, 00164 lwm2m_server_t * serverP, 00165 coap_packet_t * message, 00166 coap_packet_t * response) 00167 { 00168 coap_status_t result; 00169 lwm2m_media_type_t format; 00170 00171 LOG_ARG("Code: %02X, server status: %s", message->code, STR_STATUS(serverP->status)); 00172 LOG_URI(uriP); 00173 00174 if (IS_OPTION(message, COAP_OPTION_CONTENT_TYPE)) 00175 { 00176 format = utils_convertMediaType(message->content_type); 00177 } 00178 else 00179 { 00180 format = LWM2M_CONTENT_TLV; 00181 } 00182 00183 if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID) 00184 { 00185 return COAP_404_NOT_FOUND; 00186 } 00187 00188 if (serverP->status != STATE_REGISTERED 00189 && serverP->status != STATE_REG_UPDATE_NEEDED 00190 && serverP->status != STATE_REG_FULL_UPDATE_NEEDED 00191 && serverP->status != STATE_REG_UPDATE_PENDING) 00192 { 00193 return COAP_IGNORE; 00194 } 00195 00196 // TODO: check ACL 00197 00198 switch (message->code) 00199 { 00200 case COAP_GET: 00201 { 00202 uint8_t * buffer = NULL; 00203 size_t length = 0; 00204 int res; 00205 00206 if (IS_OPTION(message, COAP_OPTION_OBSERVE)) 00207 { 00208 lwm2m_data_t * dataP = NULL; 00209 int size = 0; 00210 00211 result = object_readData(contextP, uriP, &size, &dataP); 00212 if (COAP_205_CONTENT == result) 00213 { 00214 result = observe_handleRequest(contextP, uriP, serverP, size, dataP, message, response); 00215 if (COAP_205_CONTENT == result) 00216 { 00217 res = lwm2m_data_serialize(uriP, size, dataP, &format, &buffer); 00218 if (res < 0) 00219 { 00220 result = COAP_500_INTERNAL_SERVER_ERROR; 00221 } 00222 else 00223 { 00224 length = (size_t)res; 00225 LOG_ARG("Observe Request[/%d/%d/%d]: %.*s\n", uriP->objectId, uriP->instanceId, uriP->resourceId, length, buffer); 00226 } 00227 } 00228 lwm2m_data_free(size, dataP); 00229 } 00230 } 00231 else if (IS_OPTION(message, COAP_OPTION_ACCEPT) 00232 && message->accept_num == 1 00233 && message->accept[0] == APPLICATION_LINK_FORMAT) 00234 { 00235 format = LWM2M_CONTENT_LINK; 00236 result = object_discover(contextP, uriP, serverP, &buffer, &length); 00237 } 00238 else 00239 { 00240 if (IS_OPTION(message, COAP_OPTION_ACCEPT)) 00241 { 00242 format = utils_convertMediaType(message->accept[0]); 00243 } 00244 00245 result = object_read(contextP, uriP, &format, &buffer, &length); 00246 } 00247 if (COAP_205_CONTENT == result) 00248 { 00249 coap_set_header_content_type(response, format); 00250 coap_set_payload(response, buffer, length); 00251 // lwm2m_handle_packet will free buffer 00252 } 00253 else 00254 { 00255 lwm2m_free(buffer); 00256 } 00257 } 00258 break; 00259 00260 case COAP_POST: 00261 { 00262 if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) 00263 { 00264 result = object_create(contextP, uriP, format, message->payload, message->payload_len); 00265 if (result == COAP_201_CREATED) 00266 { 00267 //longest uri is /65535/65535 = 12 + 1 (null) chars 00268 char location_path[13] = ""; 00269 //instanceId expected 00270 if ((uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0) 00271 { 00272 result = COAP_500_INTERNAL_SERVER_ERROR; 00273 break; 00274 } 00275 00276 if (sprintf(location_path, "/%d/%d", uriP->objectId, uriP->instanceId) < 0) 00277 { 00278 result = COAP_500_INTERNAL_SERVER_ERROR; 00279 break; 00280 } 00281 coap_set_header_location_path(response, location_path); 00282 00283 lwm2m_update_registration(contextP, 0, true); 00284 } 00285 } 00286 else if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) 00287 { 00288 result = object_write(contextP, uriP, format, message->payload, message->payload_len); 00289 } 00290 else 00291 { 00292 result = object_execute(contextP, uriP, message->payload, message->payload_len); 00293 } 00294 } 00295 break; 00296 00297 case COAP_PUT: 00298 { 00299 if (IS_OPTION(message, COAP_OPTION_URI_QUERY)) 00300 { 00301 lwm2m_attributes_t attr; 00302 00303 if (0 != prv_readAttributes(message->uri_query, &attr)) 00304 { 00305 result = COAP_400_BAD_REQUEST; 00306 } 00307 else 00308 { 00309 result = observe_setParameters(contextP, uriP, serverP, &attr); 00310 } 00311 } 00312 else if (LWM2M_URI_IS_SET_INSTANCE(uriP)) 00313 { 00314 result = object_write(contextP, uriP, format, message->payload, message->payload_len); 00315 } 00316 else 00317 { 00318 result = COAP_400_BAD_REQUEST; 00319 } 00320 } 00321 break; 00322 00323 case COAP_DELETE: 00324 { 00325 if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || LWM2M_URI_IS_SET_RESOURCE(uriP)) 00326 { 00327 result = COAP_400_BAD_REQUEST; 00328 } 00329 else 00330 { 00331 result = object_delete(contextP, uriP); 00332 if (result == COAP_202_DELETED) 00333 { 00334 lwm2m_update_registration(contextP, 0, true); 00335 } 00336 } 00337 } 00338 break; 00339 00340 default: 00341 result = COAP_400_BAD_REQUEST; 00342 break; 00343 } 00344 00345 return result; 00346 } 00347 00348 #endif 00349 00350 #ifdef LWM2M_SERVER_MODE 00351 00352 #define ID_AS_STRING_MAX_LEN 8 00353 00354 static void prv_resultCallback(lwm2m_transaction_t * transacP, 00355 void * message) 00356 { 00357 dm_data_t * dataP = (dm_data_t *)transacP->userData; 00358 00359 if (message == NULL) 00360 { 00361 dataP->callback(dataP->clientID, 00362 &dataP->uri, 00363 COAP_503_SERVICE_UNAVAILABLE, 00364 LWM2M_CONTENT_TEXT, NULL, 0, 00365 dataP->userData); 00366 } 00367 else 00368 { 00369 coap_packet_t * packet = (coap_packet_t *)message; 00370 00371 //if packet is a CREATE response and the instanceId was assigned by the client 00372 if (packet->code == COAP_201_CREATED 00373 && packet->location_path != NULL) 00374 { 00375 char * locationString = NULL; 00376 int result = 0; 00377 lwm2m_uri_t locationUri; 00378 00379 locationString = coap_get_multi_option_as_string(packet->location_path); 00380 if (locationString == NULL) 00381 { 00382 LOG("Error: coap_get_multi_option_as_string() failed for Location_path option in prv_resultCallback()"); 00383 return; 00384 } 00385 00386 result = lwm2m_stringToUri(locationString, strlen(locationString), &locationUri); 00387 if (result == 0) 00388 { 00389 LOG("Error: lwm2m_stringToUri() failed for Location_path option in prv_resultCallback()"); 00390 lwm2m_free(locationString); 00391 return; 00392 } 00393 00394 ((dm_data_t*)transacP->userData)->uri.instanceId = locationUri.instanceId; 00395 ((dm_data_t*)transacP->userData)->uri.flag = locationUri.flag; 00396 00397 lwm2m_free(locationString); 00398 } 00399 00400 dataP->callback(dataP->clientID, 00401 &dataP->uri, 00402 packet->code, 00403 utils_convertMediaType(packet->content_type), 00404 packet->payload, 00405 packet->payload_len, 00406 dataP->userData); 00407 } 00408 lwm2m_free(dataP); 00409 } 00410 00411 static int prv_makeOperation(lwm2m_context_t * contextP, 00412 uint16_t clientID, 00413 lwm2m_uri_t * uriP, 00414 coap_method_t method, 00415 lwm2m_media_type_t format, 00416 uint8_t * buffer, 00417 int length, 00418 lwm2m_result_callback_t callback, 00419 void * userData) 00420 { 00421 lwm2m_client_t * clientP; 00422 lwm2m_transaction_t * transaction; 00423 dm_data_t * dataP; 00424 00425 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); 00426 if (clientP == NULL) return COAP_404_NOT_FOUND; 00427 00428 transaction = transaction_new(clientP->sessionH, method, clientP->altPath, uriP, contextP->nextMID++, 4, NULL); 00429 if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR; 00430 00431 if (method == COAP_GET) 00432 { 00433 coap_set_header_accept(transaction->message, format); 00434 } 00435 else if (buffer != NULL) 00436 { 00437 coap_set_header_content_type(transaction->message, format); 00438 // TODO: Take care of fragmentation 00439 coap_set_payload(transaction->message, buffer, length); 00440 } 00441 00442 if (callback != NULL) 00443 { 00444 dataP = (dm_data_t *)lwm2m_malloc(sizeof(dm_data_t)); 00445 if (dataP == NULL) 00446 { 00447 transaction_free(transaction); 00448 return COAP_500_INTERNAL_SERVER_ERROR; 00449 } 00450 memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t)); 00451 dataP->clientID = clientP->internalID; 00452 dataP->callback = callback; 00453 dataP->userData = userData; 00454 00455 transaction->callback = prv_resultCallback; 00456 transaction->userData = (void *)dataP; 00457 } 00458 00459 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); 00460 00461 return transaction_send(contextP, transaction); 00462 } 00463 00464 int lwm2m_dm_read(lwm2m_context_t * contextP, 00465 uint16_t clientID, 00466 lwm2m_uri_t * uriP, 00467 lwm2m_result_callback_t callback, 00468 void * userData) 00469 { 00470 lwm2m_client_t * clientP; 00471 lwm2m_media_type_t format; 00472 00473 LOG_ARG("clientID: %d", clientID); 00474 LOG_URI(uriP); 00475 00476 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); 00477 if (clientP == NULL) return COAP_404_NOT_FOUND; 00478 00479 if (clientP->supportJSON == true) 00480 { 00481 format = LWM2M_CONTENT_JSON; 00482 } 00483 else 00484 { 00485 format = LWM2M_CONTENT_TLV; 00486 } 00487 00488 return prv_makeOperation(contextP, clientID, uriP, 00489 COAP_GET, 00490 format, 00491 NULL, 0, 00492 callback, userData); 00493 } 00494 00495 int lwm2m_dm_write(lwm2m_context_t * contextP, 00496 uint16_t clientID, 00497 lwm2m_uri_t * uriP, 00498 lwm2m_media_type_t format, 00499 uint8_t * buffer, 00500 int length, 00501 lwm2m_result_callback_t callback, 00502 void * userData) 00503 { 00504 LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length); 00505 LOG_URI(uriP); 00506 if (!LWM2M_URI_IS_SET_INSTANCE(uriP) 00507 || length == 0) 00508 { 00509 return COAP_400_BAD_REQUEST; 00510 } 00511 00512 if (LWM2M_URI_IS_SET_RESOURCE(uriP)) 00513 { 00514 return prv_makeOperation(contextP, clientID, uriP, 00515 COAP_PUT, 00516 format, buffer, length, 00517 callback, userData); 00518 } 00519 else 00520 { 00521 return prv_makeOperation(contextP, clientID, uriP, 00522 COAP_POST, 00523 format, buffer, length, 00524 callback, userData); 00525 } 00526 } 00527 00528 int lwm2m_dm_execute(lwm2m_context_t * contextP, 00529 uint16_t clientID, 00530 lwm2m_uri_t * uriP, 00531 lwm2m_media_type_t format, 00532 uint8_t * buffer, 00533 int length, 00534 lwm2m_result_callback_t callback, 00535 void * userData) 00536 { 00537 LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length); 00538 LOG_URI(uriP); 00539 if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) 00540 { 00541 return COAP_400_BAD_REQUEST; 00542 } 00543 00544 return prv_makeOperation(contextP, clientID, uriP, 00545 COAP_POST, 00546 format, buffer, length, 00547 callback, userData); 00548 } 00549 00550 int lwm2m_dm_create(lwm2m_context_t * contextP, 00551 uint16_t clientID, 00552 lwm2m_uri_t * uriP, 00553 lwm2m_media_type_t format, 00554 uint8_t * buffer, 00555 int length, 00556 lwm2m_result_callback_t callback, 00557 void * userData) 00558 { 00559 LOG_ARG("clientID: %d, format: %s, length: %d", clientID, STR_MEDIA_TYPE(format), length); 00560 LOG_URI(uriP); 00561 00562 if (LWM2M_URI_IS_SET_INSTANCE(uriP) 00563 || length == 0) 00564 { 00565 return COAP_400_BAD_REQUEST; 00566 } 00567 00568 return prv_makeOperation(contextP, clientID, uriP, 00569 COAP_POST, 00570 format, buffer, length, 00571 callback, userData); 00572 } 00573 00574 int lwm2m_dm_delete(lwm2m_context_t * contextP, 00575 uint16_t clientID, 00576 lwm2m_uri_t * uriP, 00577 lwm2m_result_callback_t callback, 00578 void * userData) 00579 { 00580 LOG_ARG("clientID: %d", clientID); 00581 LOG_URI(uriP); 00582 if (!LWM2M_URI_IS_SET_INSTANCE(uriP) 00583 || LWM2M_URI_IS_SET_RESOURCE(uriP)) 00584 { 00585 return COAP_400_BAD_REQUEST; 00586 } 00587 00588 return prv_makeOperation(contextP, clientID, uriP, 00589 COAP_DELETE, 00590 LWM2M_CONTENT_TEXT, NULL, 0, 00591 callback, userData); 00592 } 00593 00594 int lwm2m_dm_write_attributes(lwm2m_context_t * contextP, 00595 uint16_t clientID, 00596 lwm2m_uri_t * uriP, 00597 lwm2m_attributes_t * attrP, 00598 lwm2m_result_callback_t callback, 00599 void * userData) 00600 { 00601 #define _PRV_BUFFER_SIZE 32 00602 lwm2m_client_t * clientP; 00603 lwm2m_transaction_t * transaction; 00604 coap_packet_t * coap_pkt; 00605 uint8_t buffer[_PRV_BUFFER_SIZE]; 00606 size_t length; 00607 00608 LOG_ARG("clientID: %d", clientID); 00609 LOG_URI(uriP); 00610 if (attrP == NULL) return COAP_400_BAD_REQUEST; 00611 00612 if (0 != (attrP->toSet & attrP->toClear)) return COAP_400_BAD_REQUEST; 00613 if (0 != (attrP->toSet & ATTR_FLAG_NUMERIC) && !LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_400_BAD_REQUEST; 00614 if (ATTR_FLAG_NUMERIC == (attrP->toSet & ATTR_FLAG_NUMERIC) 00615 && (attrP->lessThan + 2 * attrP->step >= attrP->greaterThan)) return COAP_400_BAD_REQUEST; 00616 00617 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); 00618 if (clientP == NULL) return COAP_404_NOT_FOUND; 00619 00620 transaction = transaction_new(clientP->sessionH, COAP_PUT, clientP->altPath, uriP, contextP->nextMID++, 4, NULL); 00621 if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR; 00622 00623 if (callback != NULL) 00624 { 00625 dm_data_t * dataP; 00626 00627 dataP = (dm_data_t *)lwm2m_malloc(sizeof(dm_data_t)); 00628 if (dataP == NULL) 00629 { 00630 transaction_free(transaction); 00631 return COAP_500_INTERNAL_SERVER_ERROR; 00632 } 00633 memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t)); 00634 dataP->clientID = clientP->internalID; 00635 dataP->callback = callback; 00636 dataP->userData = userData; 00637 00638 transaction->callback = prv_resultCallback; 00639 transaction->userData = (void *)dataP; 00640 } 00641 00642 coap_pkt = (coap_packet_t *)transaction->message; 00643 free_multi_option(coap_pkt->uri_query); 00644 if (attrP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) 00645 { 00646 memcpy(buffer, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN); 00647 length = utils_intToText(attrP->minPeriod, buffer + ATTR_MIN_PERIOD_LEN, _PRV_BUFFER_SIZE - ATTR_MIN_PERIOD_LEN); 00648 if (length == 0) 00649 { 00650 transaction_free(transaction); 00651 return COAP_500_INTERNAL_SERVER_ERROR; 00652 } 00653 coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_MIN_PERIOD_LEN + length, 0); 00654 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); 00655 } 00656 if (attrP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) 00657 { 00658 memcpy(buffer, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN); 00659 length = utils_intToText(attrP->maxPeriod, buffer + ATTR_MAX_PERIOD_LEN, _PRV_BUFFER_SIZE - ATTR_MAX_PERIOD_LEN); 00660 if (length == 0) 00661 { 00662 transaction_free(transaction); 00663 return COAP_500_INTERNAL_SERVER_ERROR; 00664 } 00665 coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_MAX_PERIOD_LEN + length, 0); 00666 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); 00667 } 00668 if (attrP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN) 00669 { 00670 memcpy(buffer, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN); 00671 length = utils_floatToText(attrP->greaterThan, buffer + ATTR_GREATER_THAN_LEN, _PRV_BUFFER_SIZE - ATTR_GREATER_THAN_LEN); 00672 if (length == 0) 00673 { 00674 transaction_free(transaction); 00675 return COAP_500_INTERNAL_SERVER_ERROR; 00676 } 00677 coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_GREATER_THAN_LEN + length, 0); 00678 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); 00679 } 00680 if (attrP->toSet & LWM2M_ATTR_FLAG_LESS_THAN) 00681 { 00682 memcpy(buffer, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN); 00683 length = utils_floatToText(attrP->lessThan, buffer + ATTR_LESS_THAN_LEN, _PRV_BUFFER_SIZE - ATTR_LESS_THAN_LEN); 00684 if (length == 0) 00685 { 00686 transaction_free(transaction); 00687 return COAP_500_INTERNAL_SERVER_ERROR; 00688 } 00689 coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_LESS_THAN_LEN + length, 0); 00690 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); 00691 } 00692 if (attrP->toSet & LWM2M_ATTR_FLAG_STEP) 00693 { 00694 memcpy(buffer, ATTR_STEP_STR, ATTR_STEP_LEN); 00695 length = utils_floatToText(attrP->step, buffer + ATTR_STEP_LEN, _PRV_BUFFER_SIZE - ATTR_STEP_LEN); 00696 if (length == 0) 00697 { 00698 transaction_free(transaction); 00699 return COAP_500_INTERNAL_SERVER_ERROR; 00700 } 00701 coap_add_multi_option(&(coap_pkt->uri_query), buffer, ATTR_STEP_LEN + length, 0); 00702 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); 00703 } 00704 if (attrP->toClear & LWM2M_ATTR_FLAG_MIN_PERIOD) 00705 { 00706 coap_add_multi_option(&(coap_pkt->uri_query), ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN -1, 0); 00707 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); 00708 } 00709 if (attrP->toClear & LWM2M_ATTR_FLAG_MAX_PERIOD) 00710 { 00711 coap_add_multi_option(&(coap_pkt->uri_query), ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN - 1, 0); 00712 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); 00713 } 00714 if (attrP->toClear & LWM2M_ATTR_FLAG_GREATER_THAN) 00715 { 00716 coap_add_multi_option(&(coap_pkt->uri_query), ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN - 1, 0); 00717 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); 00718 } 00719 if (attrP->toClear & LWM2M_ATTR_FLAG_LESS_THAN) 00720 { 00721 coap_add_multi_option(&(coap_pkt->uri_query), ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN - 1, 0); 00722 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); 00723 } 00724 if (attrP->toClear & LWM2M_ATTR_FLAG_STEP) 00725 { 00726 coap_add_multi_option(&(coap_pkt->uri_query), ATTR_STEP_STR, ATTR_STEP_LEN - 1, 0); 00727 SET_OPTION(coap_pkt, COAP_OPTION_URI_QUERY); 00728 } 00729 00730 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); 00731 00732 return transaction_send(contextP, transaction); 00733 } 00734 00735 int lwm2m_dm_discover(lwm2m_context_t * contextP, 00736 uint16_t clientID, 00737 lwm2m_uri_t * uriP, 00738 lwm2m_result_callback_t callback, 00739 void * userData) 00740 { 00741 lwm2m_client_t * clientP; 00742 lwm2m_transaction_t * transaction; 00743 dm_data_t * dataP; 00744 00745 LOG_ARG("clientID: %d", clientID); 00746 LOG_URI(uriP); 00747 clientP = (lwm2m_client_t *)lwm2m_list_find((lwm2m_list_t *)contextP->clientList, clientID); 00748 if (clientP == NULL) return COAP_404_NOT_FOUND; 00749 00750 transaction = transaction_new(clientP->sessionH, COAP_GET, clientP->altPath, uriP, contextP->nextMID++, 4, NULL); 00751 if (transaction == NULL) return COAP_500_INTERNAL_SERVER_ERROR; 00752 00753 coap_set_header_accept(transaction->message, LWM2M_CONTENT_LINK); 00754 00755 if (callback != NULL) 00756 { 00757 dataP = (dm_data_t *)lwm2m_malloc(sizeof(dm_data_t)); 00758 if (dataP == NULL) 00759 { 00760 transaction_free(transaction); 00761 return COAP_500_INTERNAL_SERVER_ERROR; 00762 } 00763 memcpy(&dataP->uri, uriP, sizeof(lwm2m_uri_t)); 00764 dataP->clientID = clientP->internalID; 00765 dataP->callback = callback; 00766 dataP->userData = userData; 00767 00768 transaction->callback = prv_resultCallback; 00769 transaction->userData = (void *)dataP; 00770 } 00771 00772 contextP->transactionList = (lwm2m_transaction_t *)LWM2M_LIST_ADD(contextP->transactionList, transaction); 00773 00774 return transaction_send(contextP, transaction); 00775 } 00776 00777 #endif
Generated on Thu Jul 14 2022 09:09:49 by
1.7.2