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.
objects.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 * Fabien Fleutot - Please refer to git log 00016 * Toby Jaffey - Please refer to git log 00017 * Benjamin Cabé - Please refer to git log 00018 * Bosch Software Innovations GmbH - Please refer to git log 00019 * Pascal Rieux - Please refer to git log 00020 * 00021 *******************************************************************************/ 00022 00023 /* 00024 Copyright (c) 2013, 2014 Intel Corporation 00025 00026 Redistribution and use in source and binary forms, with or without modification, 00027 are permitted provided that the following conditions are met: 00028 00029 * Redistributions of source code must retain the above copyright notice, 00030 this list of conditions and the following disclaimer. 00031 * Redistributions in binary form must reproduce the above copyright notice, 00032 this list of conditions and the following disclaimer in the documentation 00033 and/or other materials provided with the distribution. 00034 * Neither the name of Intel Corporation nor the names of its contributors 00035 may be used to endorse or promote products derived from this software 00036 without specific prior written permission. 00037 00038 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00039 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00040 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00041 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00042 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00043 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00044 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00045 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00046 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 00047 THE POSSIBILITY OF SUCH DAMAGE. 00048 00049 David Navarro <david.navarro@intel.com> 00050 00051 */ 00052 #include "internals.h" 00053 00054 #ifdef LWM2M_CLIENT_MODE 00055 00056 00057 #include <stdlib.h> 00058 #include <string.h> 00059 #include <stdio.h> 00060 00061 00062 uint8_t object_checkReadable(lwm2m_context_t * contextP, 00063 lwm2m_uri_t * uriP) 00064 { 00065 coap_status_t result; 00066 lwm2m_object_t * targetP; 00067 lwm2m_data_t * dataP = NULL; 00068 int size; 00069 00070 LOG_URI(uriP); 00071 targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); 00072 if (NULL == targetP) return COAP_404_NOT_FOUND; 00073 if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; 00074 00075 if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) return COAP_205_CONTENT; 00076 00077 if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; 00078 00079 if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_205_CONTENT; 00080 00081 size = 1; 00082 dataP = lwm2m_data_new(1); 00083 if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; 00084 00085 dataP->id = uriP->resourceId; 00086 00087 result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP); 00088 lwm2m_data_free(1, dataP); 00089 00090 return result; 00091 } 00092 00093 uint8_t object_checkNumeric(lwm2m_context_t * contextP, 00094 lwm2m_uri_t * uriP) 00095 { 00096 coap_status_t result; 00097 lwm2m_object_t * targetP; 00098 lwm2m_data_t * dataP = NULL; 00099 int size; 00100 00101 LOG_URI(uriP); 00102 if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return COAP_405_METHOD_NOT_ALLOWED; 00103 00104 targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); 00105 if (NULL == targetP) return COAP_404_NOT_FOUND; 00106 if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; 00107 00108 size = 1; 00109 dataP = lwm2m_data_new(1); 00110 if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; 00111 00112 dataP->id = uriP->resourceId; 00113 00114 result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP); 00115 if (result == COAP_205_CONTENT) 00116 { 00117 switch (dataP->type) 00118 { 00119 case LWM2M_TYPE_INTEGER: 00120 case LWM2M_TYPE_FLOAT: 00121 break; 00122 default: 00123 result = COAP_405_METHOD_NOT_ALLOWED; 00124 } 00125 } 00126 00127 lwm2m_data_free(1, dataP); 00128 00129 return result; 00130 } 00131 00132 coap_status_t object_readData(lwm2m_context_t * contextP, 00133 lwm2m_uri_t * uriP, 00134 int * sizeP, 00135 lwm2m_data_t ** dataP) 00136 { 00137 coap_status_t result; 00138 lwm2m_object_t * targetP; 00139 00140 LOG_URI(uriP); 00141 targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); 00142 if (NULL == targetP) return COAP_404_NOT_FOUND; 00143 if (NULL == targetP->readFunc) return COAP_405_METHOD_NOT_ALLOWED; 00144 00145 if (LWM2M_URI_IS_SET_INSTANCE(uriP)) 00146 { 00147 if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; 00148 00149 // single instance read 00150 if (LWM2M_URI_IS_SET_RESOURCE(uriP)) 00151 { 00152 *sizeP = 1; 00153 *dataP = lwm2m_data_new(*sizeP); 00154 if (*dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; 00155 00156 (*dataP)->id = uriP->resourceId; 00157 } 00158 00159 result = targetP->readFunc(uriP->instanceId, sizeP, dataP, targetP); 00160 } 00161 else 00162 { 00163 // multiple object instances read 00164 lwm2m_list_t * instanceP; 00165 int i; 00166 00167 result = COAP_205_CONTENT; 00168 00169 *sizeP = 0; 00170 for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next) 00171 { 00172 (*sizeP)++; 00173 } 00174 00175 if (*sizeP == 0) 00176 { 00177 *dataP = NULL; 00178 } 00179 else 00180 { 00181 *dataP = lwm2m_data_new(*sizeP); 00182 if (*dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; 00183 00184 instanceP = targetP->instanceList; 00185 i = 0; 00186 while (instanceP != NULL && result == COAP_205_CONTENT) 00187 { 00188 result = targetP->readFunc(instanceP->id, (int*)&((*dataP)[i].value.asChildren.count), &((*dataP)[i].value.asChildren.array), targetP); 00189 (*dataP)[i].type = LWM2M_TYPE_OBJECT_INSTANCE; 00190 (*dataP)[i].id = instanceP->id; 00191 i++; 00192 instanceP = instanceP->next; 00193 } 00194 } 00195 } 00196 00197 LOG_ARG("result: %u.%2u, size: %d", (result & 0xFF) >> 5, (result & 0x1F), *sizeP); 00198 return result; 00199 } 00200 00201 coap_status_t object_read(lwm2m_context_t * contextP, 00202 lwm2m_uri_t * uriP, 00203 lwm2m_media_type_t * formatP, 00204 uint8_t ** bufferP, 00205 size_t * lengthP) 00206 { 00207 coap_status_t result; 00208 lwm2m_data_t * dataP = NULL; 00209 int size = 0; 00210 int res; 00211 00212 LOG_URI(uriP); 00213 result = object_readData(contextP, uriP, &size, &dataP); 00214 00215 if (result == COAP_205_CONTENT) 00216 { 00217 res = lwm2m_data_serialize(uriP, size, dataP, formatP, bufferP); 00218 if (res < 0) 00219 { 00220 result = COAP_500_INTERNAL_SERVER_ERROR; 00221 } 00222 else 00223 { 00224 *lengthP = (size_t)res; 00225 } 00226 } 00227 lwm2m_data_free(size, dataP); 00228 00229 LOG_ARG("result: %u.%2u, length: %d", (result & 0xFF) >> 5, (result & 0x1F), *lengthP); 00230 00231 return result; 00232 } 00233 00234 coap_status_t object_write(lwm2m_context_t * contextP, 00235 lwm2m_uri_t * uriP, 00236 lwm2m_media_type_t format, 00237 uint8_t * buffer, 00238 size_t length) 00239 { 00240 coap_status_t result = NO_ERROR; 00241 lwm2m_object_t * targetP; 00242 lwm2m_data_t * dataP = NULL; 00243 int size = 0; 00244 00245 LOG_URI(uriP); 00246 targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); 00247 if (NULL == targetP) 00248 { 00249 result = COAP_404_NOT_FOUND; 00250 } 00251 else if (NULL == targetP->writeFunc) 00252 { 00253 result = COAP_405_METHOD_NOT_ALLOWED; 00254 } 00255 else 00256 { 00257 size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); 00258 if (size == 0) 00259 { 00260 result = COAP_406_NOT_ACCEPTABLE; 00261 } 00262 } 00263 if (result == NO_ERROR) 00264 { 00265 result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP); 00266 lwm2m_data_free(size, dataP); 00267 } 00268 00269 LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); 00270 00271 return result; 00272 } 00273 00274 coap_status_t object_execute(lwm2m_context_t * contextP, 00275 lwm2m_uri_t * uriP, 00276 uint8_t * buffer, 00277 size_t length) 00278 { 00279 lwm2m_object_t * targetP; 00280 00281 LOG_URI(uriP); 00282 targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); 00283 if (NULL == targetP) return COAP_404_NOT_FOUND; 00284 if (NULL == targetP->executeFunc) return COAP_405_METHOD_NOT_ALLOWED; 00285 if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; 00286 00287 return targetP->executeFunc(uriP->instanceId, uriP->resourceId, buffer, length, targetP); 00288 } 00289 00290 coap_status_t object_create(lwm2m_context_t * contextP, 00291 lwm2m_uri_t * uriP, 00292 lwm2m_media_type_t format, 00293 uint8_t * buffer, 00294 size_t length) 00295 { 00296 lwm2m_object_t * targetP; 00297 lwm2m_data_t * dataP = NULL; 00298 int size = 0; 00299 uint8_t result; 00300 00301 LOG_URI(uriP); 00302 00303 if (length == 0 || buffer == 0) 00304 { 00305 return COAP_400_BAD_REQUEST; 00306 } 00307 00308 targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); 00309 if (NULL == targetP) return COAP_404_NOT_FOUND; 00310 if (NULL == targetP->createFunc) return COAP_405_METHOD_NOT_ALLOWED; 00311 00312 size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); 00313 if (size <= 0) return COAP_400_BAD_REQUEST; 00314 00315 switch (dataP[0].type) 00316 { 00317 case LWM2M_TYPE_OBJECT: 00318 result = COAP_400_BAD_REQUEST; 00319 goto exit; 00320 00321 case LWM2M_TYPE_OBJECT_INSTANCE: 00322 if (size != 1) 00323 { 00324 result = COAP_400_BAD_REQUEST; 00325 goto exit; 00326 } 00327 if (NULL != lwm2m_list_find(targetP->instanceList, dataP[0].id)) 00328 { 00329 // Instance already exists 00330 result = COAP_406_NOT_ACCEPTABLE; 00331 goto exit; 00332 } 00333 result = targetP->createFunc(dataP[0].id, dataP[0].value.asChildren.count, dataP[0].value.asChildren.array, targetP); 00334 uriP->instanceId = dataP[0].id; 00335 uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; 00336 break; 00337 00338 default: 00339 if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) 00340 { 00341 uriP->instanceId = lwm2m_list_newId(targetP->instanceList); 00342 uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; 00343 } 00344 result = targetP->createFunc(uriP->instanceId, size, dataP, targetP); 00345 break; 00346 } 00347 00348 exit: 00349 lwm2m_data_free(size, dataP); 00350 00351 LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); 00352 00353 return result; 00354 } 00355 00356 coap_status_t object_delete(lwm2m_context_t * contextP, 00357 lwm2m_uri_t * uriP) 00358 { 00359 lwm2m_object_t * objectP; 00360 coap_status_t result; 00361 00362 LOG_URI(uriP); 00363 objectP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); 00364 if (NULL == objectP) return COAP_404_NOT_FOUND; 00365 if (NULL == objectP->deleteFunc) return COAP_405_METHOD_NOT_ALLOWED; 00366 00367 LOG("Entering"); 00368 00369 if (LWM2M_URI_IS_SET_INSTANCE(uriP)) 00370 { 00371 result = objectP->deleteFunc(uriP->instanceId, objectP); 00372 } 00373 else 00374 { 00375 lwm2m_list_t * instanceP; 00376 00377 result = COAP_202_DELETED; 00378 instanceP = objectP->instanceList; 00379 while (NULL != instanceP 00380 && result == COAP_202_DELETED) 00381 { 00382 result = objectP->deleteFunc(instanceP->id, objectP); 00383 instanceP = objectP->instanceList; 00384 } 00385 } 00386 00387 LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); 00388 00389 return result; 00390 } 00391 00392 coap_status_t object_discover(lwm2m_context_t * contextP, 00393 lwm2m_uri_t * uriP, 00394 lwm2m_server_t * serverP, 00395 uint8_t ** bufferP, 00396 size_t * lengthP) 00397 { 00398 coap_status_t result; 00399 lwm2m_object_t * targetP; 00400 lwm2m_data_t * dataP = NULL; 00401 int size = 0; 00402 00403 LOG_URI(uriP); 00404 targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); 00405 if (NULL == targetP) return COAP_404_NOT_FOUND; 00406 if (NULL == targetP->discoverFunc) return COAP_501_NOT_IMPLEMENTED; 00407 00408 if (LWM2M_URI_IS_SET_INSTANCE(uriP)) 00409 { 00410 if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) return COAP_404_NOT_FOUND; 00411 00412 // single instance read 00413 if (LWM2M_URI_IS_SET_RESOURCE(uriP)) 00414 { 00415 size = 1; 00416 dataP = lwm2m_data_new(size); 00417 if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; 00418 00419 dataP->id = uriP->resourceId; 00420 } 00421 00422 result = targetP->discoverFunc(uriP->instanceId, &size, &dataP, targetP); 00423 } 00424 else 00425 { 00426 // multiple object instances read 00427 lwm2m_list_t * instanceP; 00428 int i; 00429 00430 result = COAP_205_CONTENT; 00431 00432 size = 0; 00433 for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next) 00434 { 00435 size++; 00436 } 00437 00438 if (size != 0) 00439 { 00440 dataP = lwm2m_data_new(size); 00441 if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; 00442 00443 instanceP = targetP->instanceList; 00444 i = 0; 00445 while (instanceP != NULL && result == COAP_205_CONTENT) 00446 { 00447 result = targetP->discoverFunc(instanceP->id, (int*)&(dataP[i].value.asChildren.count), &(dataP[i].value.asChildren.array), targetP); 00448 dataP[i].type = LWM2M_TYPE_OBJECT_INSTANCE; 00449 dataP[i].id = instanceP->id; 00450 i++; 00451 instanceP = instanceP->next; 00452 } 00453 } 00454 } 00455 00456 if (result == COAP_205_CONTENT) 00457 { 00458 int len; 00459 00460 len = discover_serialize(contextP, uriP, serverP, size, dataP, bufferP); 00461 if (len <= 0) result = COAP_500_INTERNAL_SERVER_ERROR; 00462 else *lengthP = len; 00463 } 00464 lwm2m_data_free(size, dataP); 00465 00466 LOG_ARG("result: %u.%2u", (result & 0xFF) >> 5, (result & 0x1F)); 00467 00468 return result; 00469 } 00470 00471 bool object_isInstanceNew(lwm2m_context_t * contextP, 00472 uint16_t objectId, 00473 uint16_t instanceId) 00474 { 00475 lwm2m_object_t * targetP; 00476 00477 LOG("Entering"); 00478 targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, objectId); 00479 if (targetP != NULL) 00480 { 00481 if (NULL != lwm2m_list_find(targetP->instanceList, instanceId)) 00482 { 00483 return false; 00484 } 00485 } 00486 00487 return true; 00488 } 00489 00490 static int prv_getObjectTemplate(uint8_t * buffer, 00491 size_t length, 00492 uint16_t id) 00493 { 00494 int index; 00495 int result; 00496 00497 if (length < REG_OBJECT_MIN_LEN) return -1; 00498 00499 buffer[0] = '<'; 00500 buffer[1] = '/'; 00501 index = 2; 00502 00503 result = utils_intCopy((char *)buffer + index, length - index, id); 00504 if (result < 0) return -1; 00505 index += result; 00506 00507 if (length - index < REG_OBJECT_MIN_LEN - 3) return -1; 00508 buffer[index] = '/'; 00509 index++; 00510 00511 return index; 00512 } 00513 00514 int object_getRegisterPayload(lwm2m_context_t * contextP, 00515 uint8_t * buffer, 00516 size_t bufferLen) 00517 { 00518 size_t index; 00519 int result; 00520 lwm2m_object_t * objectP; 00521 00522 LOG("Entering"); 00523 // index can not be greater than bufferLen 00524 index = 0; 00525 00526 result = utils_stringCopy((char *)buffer, bufferLen, REG_START); 00527 if (result < 0) return 0; 00528 index += result; 00529 00530 if ((contextP->altPath != NULL) 00531 && (contextP->altPath[0] != 0)) 00532 { 00533 result = utils_stringCopy((char *)buffer + index, bufferLen - index, contextP->altPath); 00534 } 00535 else 00536 { 00537 result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_DEFAULT_PATH); 00538 } 00539 if (result < 0) return 0; 00540 index += result; 00541 00542 result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_LWM2M_RESOURCE_TYPE); 00543 if (result < 0) return 0; 00544 index += result; 00545 00546 for (objectP = contextP->objectList; objectP != NULL; objectP = objectP->next) 00547 { 00548 size_t start; 00549 size_t length; 00550 00551 if (objectP->objID == LWM2M_SECURITY_OBJECT_ID) continue; 00552 00553 start = index; 00554 result = prv_getObjectTemplate(buffer + index, bufferLen - index, objectP->objID); 00555 if (result < 0) return 0; 00556 length = result; 00557 index += length; 00558 00559 if (objectP->instanceList == NULL) 00560 { 00561 index--; 00562 result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_PATH_END); 00563 if (result < 0) return 0; 00564 index += result; 00565 } 00566 else 00567 { 00568 lwm2m_list_t * targetP; 00569 for (targetP = objectP->instanceList ; targetP != NULL ; targetP = targetP->next) 00570 { 00571 if (bufferLen - index <= length) return 0; 00572 00573 if (index != start + length) 00574 { 00575 memcpy(buffer + index, buffer + start, length); 00576 index += length; 00577 } 00578 00579 result = utils_intCopy((char *)buffer + index, bufferLen - index, targetP->id); 00580 if (result < 0) return 0; 00581 index += result; 00582 00583 result = utils_stringCopy((char *)buffer + index, bufferLen - index, REG_PATH_END); 00584 if (result < 0) return 0; 00585 index += result; 00586 } 00587 } 00588 } 00589 00590 if (index > 0) 00591 { 00592 index = index - 1; // remove trailing ',' 00593 } 00594 00595 buffer[index] = 0; 00596 00597 return index; 00598 } 00599 00600 static lwm2m_list_t * prv_findServerInstance(lwm2m_object_t * objectP, 00601 uint16_t shortID) 00602 { 00603 lwm2m_list_t * instanceP; 00604 00605 instanceP = objectP->instanceList; 00606 while (NULL != instanceP) 00607 { 00608 int64_t value; 00609 lwm2m_data_t * dataP; 00610 int size; 00611 00612 size = 1; 00613 dataP = lwm2m_data_new(size); 00614 if (dataP == NULL) return NULL; 00615 dataP->id = LWM2M_SERVER_SHORT_ID_ID; 00616 00617 if (objectP->readFunc(instanceP->id, &size, &dataP, objectP) != COAP_205_CONTENT) 00618 { 00619 lwm2m_data_free(size, dataP); 00620 return NULL; 00621 } 00622 00623 if (1 == lwm2m_data_decode_int(dataP, &value)) 00624 { 00625 if (value == shortID) 00626 { 00627 lwm2m_data_free(size, dataP); 00628 break; 00629 } 00630 } 00631 lwm2m_data_free(size, dataP); 00632 instanceP = instanceP->next; 00633 } 00634 00635 return instanceP; 00636 } 00637 00638 static int prv_getMandatoryInfo(lwm2m_object_t * objectP, 00639 uint16_t instanceID, 00640 lwm2m_server_t * targetP) 00641 { 00642 lwm2m_data_t * dataP; 00643 int size; 00644 int64_t value; 00645 00646 size = 2; 00647 dataP = lwm2m_data_new(size); 00648 if (dataP == NULL) return -1; 00649 dataP[0].id = LWM2M_SERVER_LIFETIME_ID; 00650 dataP[1].id = LWM2M_SERVER_BINDING_ID; 00651 00652 if (objectP->readFunc(instanceID, &size, &dataP, objectP) != COAP_205_CONTENT) 00653 { 00654 lwm2m_data_free(size, dataP); 00655 return -1; 00656 } 00657 00658 if (0 == lwm2m_data_decode_int(dataP, &value) 00659 || value < 0 || value >0xFFFFFFFF) // This is an implementation limit 00660 { 00661 lwm2m_data_free(size, dataP); 00662 return -1; 00663 } 00664 targetP->lifetime = value; 00665 00666 targetP->binding = utils_stringToBinding(dataP[1].value.asBuffer.buffer, dataP[1].value.asBuffer.length); 00667 00668 lwm2m_data_free(size, dataP); 00669 00670 if (targetP->binding == BINDING_UNKNOWN) 00671 { 00672 return -1; 00673 } 00674 00675 return 0; 00676 } 00677 00678 int object_getServers(lwm2m_context_t * contextP) 00679 { 00680 lwm2m_object_t * objectP; 00681 lwm2m_object_t * securityObjP = NULL; 00682 lwm2m_object_t * serverObjP = NULL; 00683 lwm2m_list_t * securityInstP; // instanceID of the server in the LWM2M Security Object 00684 00685 LOG("Entering"); 00686 00687 for (objectP = contextP->objectList; objectP != NULL; objectP = objectP->next) 00688 { 00689 if (objectP->objID == LWM2M_SECURITY_OBJECT_ID) 00690 { 00691 securityObjP = objectP; 00692 } 00693 else if (objectP->objID == LWM2M_SERVER_OBJECT_ID) 00694 { 00695 serverObjP = objectP; 00696 } 00697 } 00698 00699 if (NULL == securityObjP) return -1; 00700 00701 securityInstP = securityObjP->instanceList; 00702 while (securityInstP != NULL) 00703 { 00704 if (LWM2M_LIST_FIND(contextP->bootstrapServerList, securityInstP->id) == NULL 00705 && LWM2M_LIST_FIND(contextP->serverList, securityInstP->id) == NULL) 00706 { 00707 // This server is new. eg created by last bootstrap 00708 00709 lwm2m_data_t * dataP; 00710 int size; 00711 lwm2m_server_t * targetP; 00712 bool isBootstrap; 00713 int64_t value = 0; 00714 00715 size = 3; 00716 dataP = lwm2m_data_new(size); 00717 if (dataP == NULL) return -1; 00718 dataP[0].id = LWM2M_SECURITY_BOOTSTRAP_ID; 00719 dataP[1].id = LWM2M_SECURITY_SHORT_SERVER_ID; 00720 dataP[2].id = LWM2M_SECURITY_HOLD_OFF_ID; 00721 00722 if (securityObjP->readFunc(securityInstP->id, &size, &dataP, securityObjP) != COAP_205_CONTENT) 00723 { 00724 lwm2m_data_free(size, dataP); 00725 return -1; 00726 } 00727 00728 targetP = (lwm2m_server_t *)lwm2m_malloc(sizeof(lwm2m_server_t)); 00729 if (targetP == NULL) { 00730 lwm2m_data_free(size, dataP); 00731 return -1; 00732 } 00733 memset(targetP, 0, sizeof(lwm2m_server_t)); 00734 targetP->secObjInstID = securityInstP->id; 00735 00736 if (0 == lwm2m_data_decode_bool(dataP + 0, &isBootstrap)) 00737 { 00738 lwm2m_free(targetP); 00739 lwm2m_data_free(size, dataP); 00740 return -1; 00741 } 00742 00743 if (0 == lwm2m_data_decode_int(dataP + 1, &value) 00744 || value < (isBootstrap ? 0 : 1) || value > 0xFFFF) // 0 is forbidden as a Short Server ID 00745 { 00746 lwm2m_free(targetP); 00747 lwm2m_data_free(size, dataP); 00748 return -1; 00749 } 00750 targetP->shortID = value; 00751 00752 if (isBootstrap == true) 00753 { 00754 if (0 == lwm2m_data_decode_int(dataP + 2, &value) 00755 || value < 0 || value > 0xFFFFFFFF) // This is an implementation limit 00756 { 00757 lwm2m_free(targetP); 00758 lwm2m_data_free(size, dataP); 00759 return -1; 00760 } 00761 // lifetime of a bootstrap server is set to ClientHoldOffTime 00762 targetP->lifetime = value; 00763 00764 contextP->bootstrapServerList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->bootstrapServerList, targetP); 00765 } 00766 else 00767 { 00768 lwm2m_list_t * serverInstP; // instanceID of the server in the LWM2M Server Object 00769 00770 serverInstP = prv_findServerInstance(serverObjP, targetP->shortID); 00771 if (serverInstP == NULL) 00772 { 00773 lwm2m_free(targetP); 00774 lwm2m_data_free(size, dataP); 00775 return -1; 00776 } 00777 if (0 != prv_getMandatoryInfo(serverObjP, serverInstP->id, targetP)) 00778 { 00779 lwm2m_free(targetP); 00780 lwm2m_data_free(size, dataP); 00781 return -1; 00782 } 00783 targetP->status = STATE_DEREGISTERED; 00784 contextP->serverList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->serverList, targetP); 00785 } 00786 lwm2m_data_free(size, dataP); 00787 } 00788 securityInstP = securityInstP->next; 00789 } 00790 00791 return 0; 00792 } 00793 00794 coap_status_t object_createInstance(lwm2m_context_t * contextP, 00795 lwm2m_uri_t * uriP, 00796 lwm2m_data_t * dataP) 00797 { 00798 lwm2m_object_t * targetP; 00799 00800 LOG_URI(uriP); 00801 targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); 00802 if (NULL == targetP) return COAP_404_NOT_FOUND; 00803 00804 if (NULL == targetP->createFunc) 00805 { 00806 return COAP_405_METHOD_NOT_ALLOWED; 00807 } 00808 00809 return targetP->createFunc(lwm2m_list_newId(targetP->instanceList), dataP->value.asChildren.count, dataP->value.asChildren.array, targetP); 00810 } 00811 00812 coap_status_t object_writeInstance(lwm2m_context_t * contextP, 00813 lwm2m_uri_t * uriP, 00814 lwm2m_data_t * dataP) 00815 { 00816 lwm2m_object_t * targetP; 00817 00818 LOG_URI(uriP); 00819 targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); 00820 if (NULL == targetP) return COAP_404_NOT_FOUND; 00821 00822 if (NULL == targetP->writeFunc) 00823 { 00824 return COAP_405_METHOD_NOT_ALLOWED; 00825 } 00826 00827 return targetP->writeFunc(dataP->id, dataP->value.asChildren.count, dataP->value.asChildren.array, targetP); 00828 } 00829 00830 #endif
Generated on Sun Jul 17 2022 20:01:04 by
1.7.2