b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | /******************************************************************************* |
| 2 | * |
| 3 | * Copyright (c) 2013, 2014 Intel Corporation and others. |
| 4 | * All rights reserved. This program and the accompanying materials |
| 5 | * are made available under the terms of the Eclipse Public License v1.0 |
| 6 | * and Eclipse Distribution License v1.0 which accompany this distribution. |
| 7 | * |
| 8 | * The Eclipse Public License is available at |
| 9 | * http://www.eclipse.org/legal/epl-v10.html |
| 10 | * The Eclipse Distribution License is available at |
| 11 | * http://www.eclipse.org/org/documents/edl-v10.php. |
| 12 | * |
| 13 | * Contributors: |
| 14 | * David Navarro, Intel Corporation - initial API and implementation |
| 15 | * Fabien Fleutot - Please refer to git log |
| 16 | * Toby Jaffey - Please refer to git log |
| 17 | * Benjamin CabeĢ - Please refer to git log |
| 18 | * Bosch Software Innovations GmbH - Please refer to git log |
| 19 | * Pascal Rieux - Please refer to git log |
| 20 | * |
| 21 | *******************************************************************************/ |
| 22 | |
| 23 | /* |
| 24 | Copyright (c) 2013, 2014 Intel Corporation |
| 25 | |
| 26 | Redistribution and use in source and binary forms, with or without modification, |
| 27 | are permitted provided that the following conditions are met: |
| 28 | |
| 29 | * Redistributions of source code must retain the above copyright notice, |
| 30 | this list of conditions and the following disclaimer. |
| 31 | * Redistributions in binary form must reproduce the above copyright notice, |
| 32 | this list of conditions and the following disclaimer in the documentation |
| 33 | and/or other materials provided with the distribution. |
| 34 | * Neither the name of Intel Corporation nor the names of its contributors |
| 35 | may be used to endorse or promote products derived from this software |
| 36 | without specific prior written permission. |
| 37 | |
| 38 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| 39 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 40 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| 41 | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| 42 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 43 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 44 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 45 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| 46 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 47 | THE POSSIBILITY OF SUCH DAMAGE. |
| 48 | |
| 49 | David Navarro <david.navarro@intel.com> |
| 50 | |
| 51 | */ |
| 52 | #include "internals.h" |
| 53 | |
| 54 | #ifdef LWM2M_CLIENT_MODE |
| 55 | |
| 56 | |
| 57 | #include <stdlib.h> |
| 58 | #include <string.h> |
| 59 | #include <stdio.h> |
| 60 | |
| 61 | |
| 62 | static lwm2m_object_t * prv_find_object(lwm2m_context_t * contextP, |
| 63 | uint16_t Id) |
| 64 | { |
| 65 | int i; |
| 66 | |
| 67 | if ( |
| 68 | #ifdef LWM2M_BOOTSTRAP |
| 69 | (contextP->bsState != BOOTSTRAP_PENDING) && |
| 70 | #endif |
| 71 | (Id == LWM2M_SECURITY_OBJECT_ID)) |
| 72 | { |
| 73 | return NULL; |
| 74 | } |
| 75 | |
| 76 | for (i = 0 ; i < contextP->numObject ; i++) |
| 77 | { |
| 78 | if (contextP->objectList[i]->objID == Id) |
| 79 | { |
| 80 | return contextP->objectList[i]; |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | return NULL; |
| 85 | } |
| 86 | |
| 87 | coap_status_t object_read(lwm2m_context_t * contextP, |
| 88 | lwm2m_uri_t * uriP, |
| 89 | uint8_t ** bufferP, |
| 90 | size_t * lengthP) |
| 91 | { |
| 92 | coap_status_t result; |
| 93 | lwm2m_object_t * targetP; |
| 94 | lwm2m_tlv_t * tlvP = NULL; |
| 95 | int size = 0; |
| 96 | |
| 97 | #ifdef LWM2M_BOOTSTRAP |
| 98 | if (contextP->bsState == BOOTSTRAP_PENDING) return METHOD_NOT_ALLOWED_4_05; |
| 99 | #endif |
| 100 | |
| 101 | targetP = prv_find_object(contextP, uriP->objectId); |
| 102 | if (NULL == targetP) return NOT_FOUND_4_04; |
| 103 | if (NULL == targetP->readFunc) return METHOD_NOT_ALLOWED_4_05; |
| 104 | if (targetP->instanceList == NULL) |
| 105 | { |
| 106 | // this is a single instance object |
| 107 | if (LWM2M_URI_IS_SET_INSTANCE(uriP) && (uriP->instanceId != 0)) |
| 108 | { |
| 109 | return COAP_404_NOT_FOUND; |
| 110 | } |
| 111 | } |
| 112 | else |
| 113 | { |
| 114 | if (LWM2M_URI_IS_SET_INSTANCE(uriP)) |
| 115 | { |
| 116 | if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) |
| 117 | { |
| 118 | return COAP_404_NOT_FOUND; |
| 119 | } |
| 120 | } |
| 121 | else |
| 122 | { |
| 123 | // multiple object instances read |
| 124 | lwm2m_list_t * instanceP; |
| 125 | int i; |
| 126 | |
| 127 | size = 0; |
| 128 | for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next) |
| 129 | { |
| 130 | size++; |
| 131 | } |
| 132 | |
| 133 | tlvP = lwm2m_tlv_new(size); |
| 134 | if (tlvP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
| 135 | |
| 136 | result = COAP_205_CONTENT; |
| 137 | instanceP = targetP->instanceList; |
| 138 | i = 0; |
| 139 | while (instanceP != NULL && result == COAP_205_CONTENT) |
| 140 | { |
| 141 | result = targetP->readFunc(instanceP->id, (int*)&(tlvP[i].length), (lwm2m_tlv_t **)&(tlvP[i].value), targetP); |
| 142 | tlvP[i].type = LWM2M_TYPE_OBJECT_INSTANCE; |
| 143 | tlvP[i].id = instanceP->id; |
| 144 | i++; |
| 145 | instanceP = instanceP->next; |
| 146 | } |
| 147 | |
| 148 | if (result == COAP_205_CONTENT) |
| 149 | { |
| 150 | *lengthP = lwm2m_tlv_serialize(size, tlvP, bufferP); |
| 151 | if (*lengthP == 0) result = COAP_500_INTERNAL_SERVER_ERROR; |
| 152 | } |
| 153 | lwm2m_tlv_free(size, tlvP); |
| 154 | |
| 155 | return result; |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | // single instance read |
| 160 | if (LWM2M_URI_IS_SET_RESOURCE(uriP)) |
| 161 | { |
| 162 | size = 1; |
| 163 | tlvP = lwm2m_tlv_new(size); |
| 164 | if (tlvP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; |
| 165 | |
| 166 | tlvP->type = LWM2M_TYPE_RESOURCE; |
| 167 | tlvP->flags = LWM2M_TLV_FLAG_TEXT_FORMAT; |
| 168 | tlvP->id = uriP->resourceId; |
| 169 | } |
| 170 | result = targetP->readFunc(uriP->instanceId, &size, &tlvP, targetP); |
| 171 | if (result == COAP_205_CONTENT) |
| 172 | { |
| 173 | if (size == 1 |
| 174 | && tlvP->type == LWM2M_TYPE_RESOURCE |
| 175 | && (tlvP->flags && LWM2M_TLV_FLAG_TEXT_FORMAT) != 0 ) |
| 176 | { |
| 177 | *bufferP = (uint8_t *)malloc(tlvP->length); |
| 178 | if (*bufferP == NULL) |
| 179 | { |
| 180 | result = COAP_500_INTERNAL_SERVER_ERROR; |
| 181 | } |
| 182 | else |
| 183 | { |
| 184 | memcpy(*bufferP, tlvP->value, tlvP->length); |
| 185 | *lengthP = tlvP->length; |
| 186 | } |
| 187 | } |
| 188 | else |
| 189 | { |
| 190 | *lengthP = lwm2m_tlv_serialize(size, tlvP, bufferP); |
| 191 | if (*lengthP == 0) result = COAP_500_INTERNAL_SERVER_ERROR; |
| 192 | } |
| 193 | } |
| 194 | lwm2m_tlv_free(size, tlvP); |
| 195 | |
| 196 | return result; |
| 197 | } |
| 198 | |
| 199 | coap_status_t object_write(lwm2m_context_t * contextP, |
| 200 | lwm2m_uri_t * uriP, |
| 201 | uint8_t * buffer, |
| 202 | size_t length) |
| 203 | { |
| 204 | coap_status_t result = NO_ERROR; |
| 205 | lwm2m_object_t * targetP; |
| 206 | lwm2m_tlv_t * tlvP = NULL; |
| 207 | int size = 0; |
| 208 | |
| 209 | targetP = prv_find_object(contextP, uriP->objectId); |
| 210 | if (NULL == targetP) |
| 211 | { |
| 212 | result = NOT_FOUND_4_04; |
| 213 | } |
| 214 | else if (NULL == targetP->writeFunc) |
| 215 | { |
| 216 | result = METHOD_NOT_ALLOWED_4_05; |
| 217 | } |
| 218 | else |
| 219 | { |
| 220 | if (LWM2M_URI_IS_SET_RESOURCE(uriP)) |
| 221 | { |
| 222 | size = 1; |
| 223 | tlvP = lwm2m_tlv_new(size); |
| 224 | if (tlvP == NULL) |
| 225 | { |
| 226 | return COAP_500_INTERNAL_SERVER_ERROR; |
| 227 | } |
| 228 | |
| 229 | tlvP->flags = LWM2M_TLV_FLAG_TEXT_FORMAT | LWM2M_TLV_FLAG_STATIC_DATA; |
| 230 | tlvP->type = LWM2M_TYPE_RESOURCE; |
| 231 | tlvP->id = uriP->resourceId; |
| 232 | tlvP->length = length; |
| 233 | tlvP->value = (uint8_t *)buffer; |
| 234 | } |
| 235 | else |
| 236 | { |
| 237 | size = lwm2m_tlv_parse(buffer, length, &tlvP); |
| 238 | if (size == 0) |
| 239 | { |
| 240 | result = COAP_500_INTERNAL_SERVER_ERROR; |
| 241 | } |
| 242 | } |
| 243 | } |
| 244 | if (result == NO_ERROR) |
| 245 | { |
| 246 | #ifdef LWM2M_BOOTSTRAP |
| 247 | if (contextP->bsState == BOOTSTRAP_PENDING) |
| 248 | { |
| 249 | tlvP->flags |= LWM2M_TLV_FLAG_BOOTSTRAPPING; |
| 250 | } |
| 251 | #endif |
| 252 | result = targetP->writeFunc(uriP->instanceId, size, tlvP, targetP); |
| 253 | lwm2m_tlv_free(size, tlvP); |
| 254 | } |
| 255 | #ifdef LWM2M_BOOTSTRAP |
| 256 | if (contextP->bsState == BOOTSTRAP_PENDING) |
| 257 | { |
| 258 | if (result == COAP_204_CHANGED) |
| 259 | { |
| 260 | reset_bootstrap_timer(contextP); |
| 261 | } |
| 262 | else |
| 263 | { |
| 264 | bootstrap_failed(contextP); |
| 265 | } |
| 266 | } |
| 267 | #endif |
| 268 | return result; |
| 269 | } |
| 270 | |
| 271 | coap_status_t object_execute(lwm2m_context_t * contextP, |
| 272 | lwm2m_uri_t * uriP, |
| 273 | uint8_t * buffer, |
| 274 | size_t length) |
| 275 | { |
| 276 | lwm2m_object_t * targetP; |
| 277 | |
| 278 | #ifdef LWM2M_BOOTSTRAP |
| 279 | if (contextP->bsState == BOOTSTRAP_PENDING) return METHOD_NOT_ALLOWED_4_05; |
| 280 | #endif |
| 281 | |
| 282 | targetP = prv_find_object(contextP, uriP->objectId); |
| 283 | if (NULL == targetP) return NOT_FOUND_4_04; |
| 284 | if (NULL == targetP->executeFunc) return METHOD_NOT_ALLOWED_4_05; |
| 285 | |
| 286 | return targetP->executeFunc(uriP->instanceId, uriP->resourceId, buffer, length, targetP); |
| 287 | } |
| 288 | |
| 289 | coap_status_t object_create(lwm2m_context_t * contextP, |
| 290 | lwm2m_uri_t * uriP, |
| 291 | uint8_t * buffer, |
| 292 | size_t length) |
| 293 | { |
| 294 | lwm2m_object_t * targetP; |
| 295 | lwm2m_tlv_t * tlvP = NULL; |
| 296 | int size = 0; |
| 297 | uint8_t result; |
| 298 | |
| 299 | if (length == 0 || buffer == 0) |
| 300 | { |
| 301 | return BAD_REQUEST_4_00; |
| 302 | } |
| 303 | |
| 304 | targetP = prv_find_object(contextP, uriP->objectId); |
| 305 | if (NULL == targetP) return NOT_FOUND_4_04; |
| 306 | if (NULL == targetP->createFunc) return METHOD_NOT_ALLOWED_4_05; |
| 307 | |
| 308 | if (LWM2M_URI_IS_SET_INSTANCE(uriP)) |
| 309 | { |
| 310 | if (NULL != lwm2m_list_find(targetP->instanceList, uriP->instanceId)) |
| 311 | { |
| 312 | // Instance already exists |
| 313 | return COAP_406_NOT_ACCEPTABLE; |
| 314 | } |
| 315 | } |
| 316 | else |
| 317 | { |
| 318 | uriP->instanceId = lwm2m_list_newId(targetP->instanceList); |
| 319 | uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; |
| 320 | } |
| 321 | |
| 322 | size = lwm2m_tlv_parse(buffer, length, &tlvP); |
| 323 | if (size == 0) return COAP_500_INTERNAL_SERVER_ERROR; |
| 324 | #ifdef LWM2M_BOOTSTRAP |
| 325 | if (contextP->bsState == BOOTSTRAP_PENDING) |
| 326 | { |
| 327 | tlvP->flags |= LWM2M_TLV_FLAG_BOOTSTRAPPING; |
| 328 | } |
| 329 | #endif |
| 330 | result = targetP->createFunc(uriP->instanceId, size, tlvP, targetP); |
| 331 | lwm2m_tlv_free(size, tlvP); |
| 332 | |
| 333 | return result; |
| 334 | } |
| 335 | |
| 336 | coap_status_t object_delete(lwm2m_context_t * contextP, |
| 337 | lwm2m_uri_t * uriP) |
| 338 | { |
| 339 | lwm2m_object_t * targetP; |
| 340 | |
| 341 | targetP = prv_find_object(contextP, uriP->objectId); |
| 342 | if (NULL == targetP) return NOT_FOUND_4_04; |
| 343 | if (NULL == targetP->deleteFunc) return METHOD_NOT_ALLOWED_4_05; |
| 344 | |
| 345 | LOG(" Call to object_delete\r\n"); |
| 346 | |
| 347 | return targetP->deleteFunc(uriP->instanceId, targetP); |
| 348 | } |
| 349 | |
| 350 | bool object_isInstanceNew(lwm2m_context_t * contextP, |
| 351 | uint16_t objectId, |
| 352 | uint16_t instanceId) |
| 353 | { |
| 354 | lwm2m_object_t * targetP; |
| 355 | |
| 356 | targetP = prv_find_object(contextP, objectId); |
| 357 | if (targetP != NULL) |
| 358 | { |
| 359 | if (NULL != lwm2m_list_find(targetP->instanceList, instanceId)) |
| 360 | { |
| 361 | return false; |
| 362 | } |
| 363 | } |
| 364 | |
| 365 | return true; |
| 366 | } |
| 367 | |
| 368 | int prv_getRegisterPayload(lwm2m_context_t * contextP, |
| 369 | uint8_t * buffer, |
| 370 | size_t length) |
| 371 | { |
| 372 | int index; |
| 373 | int i; |
| 374 | int result; |
| 375 | |
| 376 | // index can not be greater than length |
| 377 | index = 0; |
| 378 | |
| 379 | if ((contextP->altPath != NULL) |
| 380 | && (contextP->altPath[0] != 0)) |
| 381 | { |
| 382 | result = snprintf((char *)buffer, length, REG_ALT_PATH_LINK, contextP->altPath); |
| 383 | if (result > 0 && result <= length) |
| 384 | { |
| 385 | index = result; |
| 386 | } |
| 387 | else |
| 388 | { |
| 389 | return 0; |
| 390 | } |
| 391 | } |
| 392 | for (i = 0 ; i < contextP->numObject ; i++) |
| 393 | { |
| 394 | if (contextP->objectList[i]->objID == LWM2M_SECURITY_OBJECT_ID) continue; |
| 395 | |
| 396 | if (contextP->objectList[i]->instanceList == NULL) |
| 397 | { |
| 398 | result = snprintf((char *)buffer + index, length - index, |
| 399 | REG_OBJECT_PATH, |
| 400 | contextP->altPath?contextP->altPath:"", contextP->objectList[i]->objID); |
| 401 | if (result > 0 && result <= length - index) |
| 402 | { |
| 403 | index += result; |
| 404 | } |
| 405 | else |
| 406 | { |
| 407 | return 0; |
| 408 | } |
| 409 | } |
| 410 | else |
| 411 | { |
| 412 | lwm2m_list_t * targetP; |
| 413 | for (targetP = contextP->objectList[i]->instanceList ; targetP != NULL ; targetP = targetP->next) |
| 414 | { |
| 415 | result = snprintf((char *)buffer + index, length - index, |
| 416 | REG_OBJECT_INSTANCE_PATH, |
| 417 | contextP->altPath?contextP->altPath:"", contextP->objectList[i]->objID, targetP->id); |
| 418 | if (result > 0 && result <= length - index) |
| 419 | { |
| 420 | index += result; |
| 421 | } |
| 422 | else |
| 423 | { |
| 424 | return 0; |
| 425 | } |
| 426 | } |
| 427 | } |
| 428 | } |
| 429 | |
| 430 | if (index > 0) |
| 431 | { |
| 432 | index = index - 1; // remove trailing ',' |
| 433 | } |
| 434 | |
| 435 | buffer[index] = 0; |
| 436 | |
| 437 | return index; |
| 438 | } |
| 439 | |
| 440 | static lwm2m_list_t * prv_findServerInstance(lwm2m_object_t * objectP, |
| 441 | uint16_t shortID) |
| 442 | { |
| 443 | lwm2m_list_t * instanceP; |
| 444 | |
| 445 | instanceP = objectP->instanceList; |
| 446 | while (NULL != instanceP) |
| 447 | { |
| 448 | int64_t value; |
| 449 | lwm2m_tlv_t * tlvP; |
| 450 | int size; |
| 451 | |
| 452 | size = 1; |
| 453 | tlvP = lwm2m_tlv_new(size); |
| 454 | if (tlvP == NULL) return NULL; |
| 455 | tlvP->id = LWM2M_SERVER_SHORT_ID_ID; |
| 456 | |
| 457 | if (objectP->readFunc(instanceP->id, &size, &tlvP, objectP) != COAP_205_CONTENT) |
| 458 | { |
| 459 | lwm2m_tlv_free(size, tlvP); |
| 460 | return NULL; |
| 461 | } |
| 462 | |
| 463 | if (1 == lwm2m_tlv_decode_int(tlvP, &value)) |
| 464 | { |
| 465 | if (value == shortID) |
| 466 | { |
| 467 | lwm2m_tlv_free(size, tlvP); |
| 468 | break; |
| 469 | } |
| 470 | } |
| 471 | lwm2m_tlv_free(size, tlvP); |
| 472 | instanceP = instanceP->next; |
| 473 | } |
| 474 | |
| 475 | return instanceP; |
| 476 | } |
| 477 | |
| 478 | static int prv_getMandatoryInfo(lwm2m_object_t * objectP, |
| 479 | uint16_t instanceID, |
| 480 | lwm2m_server_t * targetP) |
| 481 | { |
| 482 | lwm2m_tlv_t * tlvP; |
| 483 | int size; |
| 484 | int64_t value; |
| 485 | |
| 486 | size = 2; |
| 487 | tlvP = lwm2m_tlv_new(size); |
| 488 | if (tlvP == NULL) return -1; |
| 489 | tlvP[0].id = LWM2M_SERVER_LIFETIME_ID; |
| 490 | tlvP[1].id = LWM2M_SERVER_BINDING_ID; |
| 491 | |
| 492 | if (objectP->readFunc(instanceID, &size, &tlvP, objectP) != COAP_205_CONTENT) |
| 493 | { |
| 494 | lwm2m_tlv_free(size, tlvP); |
| 495 | return -1; |
| 496 | } |
| 497 | |
| 498 | if (0 == lwm2m_tlv_decode_int(tlvP, &value) |
| 499 | || value < 0 || value >0xFFFFFFFF) // This is an implementation limit |
| 500 | { |
| 501 | lwm2m_tlv_free(size, tlvP); |
| 502 | return -1; |
| 503 | } |
| 504 | targetP->lifetime = value; |
| 505 | |
| 506 | targetP->binding = lwm2m_stringToBinding(tlvP[1].value, tlvP[1].length); |
| 507 | |
| 508 | lwm2m_tlv_free(size, tlvP); |
| 509 | |
| 510 | if (targetP->binding == BINDING_UNKNOWN) |
| 511 | { |
| 512 | return -1; |
| 513 | } |
| 514 | |
| 515 | return 0; |
| 516 | } |
| 517 | |
| 518 | int object_getServers(lwm2m_context_t * contextP) |
| 519 | { |
| 520 | lwm2m_object_t * securityObjP = NULL; |
| 521 | lwm2m_object_t * serverObjP = NULL; |
| 522 | lwm2m_list_t * securityInstP; // instanceID of the server in the LWM2M Security Object |
| 523 | int i; |
| 524 | |
| 525 | for (i = 0 ; i < contextP->numObject ; i++) |
| 526 | { |
| 527 | if (contextP->objectList[i]->objID == LWM2M_SECURITY_OBJECT_ID) |
| 528 | { |
| 529 | securityObjP = contextP->objectList[i]; |
| 530 | } |
| 531 | else if (contextP->objectList[i]->objID == LWM2M_SERVER_OBJECT_ID) |
| 532 | { |
| 533 | serverObjP = contextP->objectList[i]; |
| 534 | } |
| 535 | } |
| 536 | |
| 537 | if (NULL == securityObjP) return -1; |
| 538 | |
| 539 | securityInstP = securityObjP->instanceList; |
| 540 | while (securityInstP != NULL) |
| 541 | { |
| 542 | lwm2m_tlv_t * tlvP; |
| 543 | int size; |
| 544 | lwm2m_server_t * targetP; |
| 545 | bool isBootstrap; |
| 546 | int64_t value = 0; |
| 547 | |
| 548 | size = 3; |
| 549 | tlvP = lwm2m_tlv_new(size); |
| 550 | if (tlvP == NULL) return -1; |
| 551 | tlvP[0].id = LWM2M_SECURITY_BOOTSTRAP_ID; |
| 552 | tlvP[1].id = LWM2M_SECURITY_SHORT_SERVER_ID; |
| 553 | tlvP[2].id = LWM2M_SECURITY_HOLD_OFF_ID; |
| 554 | |
| 555 | if (securityObjP->readFunc(securityInstP->id, &size, &tlvP, securityObjP) != COAP_205_CONTENT) |
| 556 | { |
| 557 | lwm2m_tlv_free(size, tlvP); |
| 558 | return -1; |
| 559 | } |
| 560 | |
| 561 | targetP = (lwm2m_server_t *)lwm2m_malloc(sizeof(lwm2m_server_t)); |
| 562 | if (targetP == NULL) { |
| 563 | lwm2m_tlv_free(size, tlvP); |
| 564 | return -1; |
| 565 | } |
| 566 | memset(targetP, 0, sizeof(lwm2m_server_t)); |
| 567 | targetP->secObjInstID = securityInstP->id; |
| 568 | |
| 569 | if (0 == lwm2m_tlv_decode_bool(tlvP + 0, &isBootstrap)) |
| 570 | { |
| 571 | lwm2m_free(targetP); |
| 572 | lwm2m_tlv_free(size, tlvP); |
| 573 | return -1; |
| 574 | } |
| 575 | |
| 576 | if (0 == lwm2m_tlv_decode_int(tlvP + 1, &value) |
| 577 | || value < (isBootstrap ? 0 : 1) || value > 0xFFFF) // 0 is forbidden as a Short Server ID |
| 578 | { |
| 579 | lwm2m_free(targetP); |
| 580 | lwm2m_tlv_free(size, tlvP); |
| 581 | return -1; |
| 582 | } |
| 583 | targetP->shortID = value; |
| 584 | |
| 585 | if (isBootstrap == true) |
| 586 | { |
| 587 | if (0 == lwm2m_tlv_decode_int(tlvP + 2, &value) |
| 588 | || value < 0 || value > 0xFFFFFFFF) // This is an implementation limit |
| 589 | { |
| 590 | lwm2m_free(targetP); |
| 591 | lwm2m_tlv_free(size, tlvP); |
| 592 | return -1; |
| 593 | } |
| 594 | // lifetime of a bootstrap server is set to ClientHoldOffTime |
| 595 | targetP->lifetime = value; |
| 596 | |
| 597 | contextP->bootstrapServerList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->bootstrapServerList, targetP); |
| 598 | } |
| 599 | else |
| 600 | { |
| 601 | lwm2m_list_t * serverInstP; // instanceID of the server in the LWM2M Server Object |
| 602 | |
| 603 | serverInstP = prv_findServerInstance(serverObjP, targetP->shortID); |
| 604 | if (serverInstP == NULL) |
| 605 | { |
| 606 | lwm2m_free(targetP); |
| 607 | lwm2m_tlv_free(size, tlvP); |
| 608 | return -1; |
| 609 | } |
| 610 | if (0 != prv_getMandatoryInfo(serverObjP, serverInstP->id, targetP)) |
| 611 | { |
| 612 | lwm2m_free(targetP); |
| 613 | lwm2m_tlv_free(size, tlvP); |
| 614 | return -1; |
| 615 | } |
| 616 | targetP->status = STATE_DEREGISTERED; |
| 617 | contextP->serverList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->serverList, targetP); |
| 618 | } |
| 619 | lwm2m_tlv_free(size, tlvP); |
| 620 | securityInstP = securityInstP->next; |
| 621 | } |
| 622 | |
| 623 | return 0; |
| 624 | } |
| 625 | |
| 626 | #endif |