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.
data.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 * Bosch Software Innovations GmbH - Please refer to git log 00017 * 00018 *******************************************************************************/ 00019 00020 #include "internals.h" 00021 #include <float.h> 00022 00023 // dataP array length is assumed to be 1. 00024 static int prv_textSerialize(lwm2m_data_t * dataP, 00025 uint8_t ** bufferP) 00026 { 00027 size_t res; 00028 00029 switch (dataP->type) 00030 { 00031 case LWM2M_TYPE_STRING: 00032 *bufferP = (uint8_t *)lwm2m_malloc(dataP->value.asBuffer.length); 00033 if (*bufferP == NULL) return 0; 00034 memcpy(*bufferP, dataP->value.asBuffer.buffer, dataP->value.asBuffer.length); 00035 return (int)dataP->value.asBuffer.length; 00036 00037 case LWM2M_TYPE_INTEGER: 00038 res = utils_int64ToPlainText(dataP->value.asInteger, bufferP); 00039 if (res == 0) return -1; 00040 return (int)res; 00041 00042 case LWM2M_TYPE_FLOAT: 00043 res = utils_float64ToPlainText(dataP->value.asFloat, bufferP); 00044 if (res == 0) return -1; 00045 return (int)res; 00046 00047 case LWM2M_TYPE_BOOLEAN: 00048 res = utils_boolToPlainText(dataP->value.asBoolean, bufferP); 00049 if (res == 0) return -1; 00050 return (int)res; 00051 00052 case LWM2M_TYPE_OBJECT_LINK: 00053 { 00054 char stringBuffer[20]; 00055 int len = snprintf(stringBuffer, 20, "%d:%d", 00056 dataP->value.asObjLink.objectId, 00057 dataP->value.asObjLink.objectInstanceId); 00058 *bufferP = (uint8_t *)lwm2m_malloc(len); 00059 if (*bufferP == NULL) return -1; 00060 memcpy(*bufferP, stringBuffer, len); 00061 return len; 00062 } 00063 case LWM2M_TYPE_OPAQUE: 00064 case LWM2M_TYPE_UNDEFINED: 00065 default: 00066 return -1; 00067 } 00068 } 00069 00070 static int prv_setBuffer(lwm2m_data_t * dataP, 00071 uint8_t * buffer, 00072 size_t bufferLen) 00073 { 00074 dataP->value.asBuffer.buffer = (uint8_t *)lwm2m_malloc(bufferLen); 00075 if (dataP->value.asBuffer.buffer == NULL) 00076 { 00077 lwm2m_data_free(1, dataP); 00078 return 0; 00079 } 00080 dataP->value.asBuffer.length = bufferLen; 00081 memcpy(dataP->value.asBuffer.buffer, buffer, bufferLen); 00082 00083 return 1; 00084 } 00085 00086 lwm2m_data_t * lwm2m_data_new(int size) 00087 { 00088 lwm2m_data_t * dataP; 00089 00090 LOG_ARG("size: %d", size); 00091 if (size <= 0) return NULL; 00092 00093 dataP = (lwm2m_data_t *)lwm2m_malloc(size * sizeof(lwm2m_data_t)); 00094 00095 if (dataP != NULL) 00096 { 00097 memset(dataP, 0, size * sizeof(lwm2m_data_t)); 00098 } 00099 00100 return dataP; 00101 } 00102 00103 void lwm2m_data_free(int size, 00104 lwm2m_data_t * dataP) 00105 { 00106 int i; 00107 00108 LOG_ARG("size: %d", size); 00109 if (size == 0 || dataP == NULL) return; 00110 00111 for (i = 0; i < size; i++) 00112 { 00113 switch (dataP[i].type) 00114 { 00115 case LWM2M_TYPE_MULTIPLE_RESOURCE: 00116 case LWM2M_TYPE_OBJECT_INSTANCE: 00117 case LWM2M_TYPE_OBJECT: 00118 lwm2m_data_free(dataP[i].value.asChildren.count, dataP[i].value.asChildren.array); 00119 break; 00120 00121 case LWM2M_TYPE_STRING: 00122 case LWM2M_TYPE_OPAQUE: 00123 if (dataP[i].value.asBuffer.buffer != NULL) 00124 { 00125 lwm2m_free(dataP[i].value.asBuffer.buffer); 00126 } 00127 00128 default: 00129 // do nothing 00130 break; 00131 } 00132 } 00133 lwm2m_free(dataP); 00134 } 00135 00136 void lwm2m_data_encode_string(const char * string, 00137 lwm2m_data_t * dataP) 00138 { 00139 size_t len; 00140 int res; 00141 00142 LOG_ARG("\"%s\"", string); 00143 if (string == NULL) 00144 { 00145 len = 0; 00146 } 00147 else 00148 { 00149 for (len = 0; string[len] != 0; len++); 00150 } 00151 00152 if (len == 0) 00153 { 00154 dataP->value.asBuffer.length = 0; 00155 dataP->value.asBuffer.buffer = NULL; 00156 res = 1; 00157 } 00158 else 00159 { 00160 res = prv_setBuffer(dataP, (uint8_t *)string, len); 00161 } 00162 00163 if (res == 1) 00164 { 00165 dataP->type = LWM2M_TYPE_STRING; 00166 } 00167 else 00168 { 00169 dataP->type = LWM2M_TYPE_UNDEFINED; 00170 } 00171 } 00172 00173 void lwm2m_data_encode_opaque(uint8_t * buffer, 00174 size_t length, 00175 lwm2m_data_t * dataP) 00176 { 00177 int res; 00178 00179 LOG_ARG("length: %d", length); 00180 if (length == 0) 00181 { 00182 dataP->value.asBuffer.length = 0; 00183 dataP->value.asBuffer.buffer = NULL; 00184 res = 1; 00185 } 00186 else 00187 { 00188 res = prv_setBuffer(dataP, buffer, length); 00189 } 00190 00191 if (res == 1) 00192 { 00193 dataP->type = LWM2M_TYPE_OPAQUE; 00194 } 00195 else 00196 { 00197 dataP->type = LWM2M_TYPE_UNDEFINED; 00198 } 00199 } 00200 00201 void lwm2m_data_encode_nstring(const char * string, 00202 size_t length, 00203 lwm2m_data_t * dataP) 00204 { 00205 LOG_ARG("length: %d, string: \"%s\"", length, string); 00206 lwm2m_data_encode_opaque((uint8_t *)string, length, dataP); 00207 00208 if (dataP->type == LWM2M_TYPE_OPAQUE) 00209 { 00210 dataP->type = LWM2M_TYPE_STRING; 00211 } 00212 } 00213 00214 void lwm2m_data_encode_int(int64_t value, 00215 lwm2m_data_t * dataP) 00216 { 00217 LOG_ARG("value: %" PRId64 "", value); 00218 dataP->type = LWM2M_TYPE_INTEGER; 00219 dataP->value.asInteger = value; 00220 } 00221 00222 int lwm2m_data_decode_int(const lwm2m_data_t * dataP, 00223 int64_t * valueP) 00224 { 00225 int result; 00226 00227 LOG("Entering"); 00228 switch (dataP->type) 00229 { 00230 case LWM2M_TYPE_INTEGER: 00231 *valueP = dataP->value.asInteger; 00232 result = 1; 00233 break; 00234 00235 case LWM2M_TYPE_STRING: 00236 result = utils_plainTextToInt64(dataP->value.asBuffer.buffer, dataP->value.asBuffer.length, valueP); 00237 break; 00238 00239 case LWM2M_TYPE_OPAQUE: 00240 result = utils_opaqueToInt(dataP->value.asBuffer.buffer, dataP->value.asBuffer.length, valueP); 00241 if (result == (int)dataP->value.asBuffer.length) 00242 { 00243 result = 1; 00244 } 00245 else 00246 { 00247 result = 0; 00248 } 00249 break; 00250 00251 default: 00252 return 0; 00253 } 00254 LOG_ARG("result: %d, value: %" PRId64, result, *valueP); 00255 00256 return result; 00257 } 00258 00259 void lwm2m_data_encode_float(double value, 00260 lwm2m_data_t * dataP) 00261 { 00262 LOG_ARG("value: %f", value); 00263 dataP->type = LWM2M_TYPE_FLOAT; 00264 dataP->value.asFloat = value; 00265 } 00266 00267 int lwm2m_data_decode_float(const lwm2m_data_t * dataP, 00268 double * valueP) 00269 { 00270 int result; 00271 00272 LOG("Entering"); 00273 switch (dataP->type) 00274 { 00275 case LWM2M_TYPE_FLOAT: 00276 *valueP = dataP->value.asFloat; 00277 result = 1; 00278 break; 00279 00280 case LWM2M_TYPE_INTEGER: 00281 *valueP = (double)dataP->value.asInteger; 00282 result = 1; 00283 break; 00284 00285 case LWM2M_TYPE_STRING: 00286 result = utils_plainTextToFloat64(dataP->value.asBuffer.buffer, dataP->value.asBuffer.length, valueP); 00287 break; 00288 00289 case LWM2M_TYPE_OPAQUE: 00290 result = utils_opaqueToFloat(dataP->value.asBuffer.buffer, dataP->value.asBuffer.length, valueP); 00291 if (result == (int)dataP->value.asBuffer.length) 00292 { 00293 result = 1; 00294 } 00295 else 00296 { 00297 result = 0; 00298 } 00299 break; 00300 00301 default: 00302 return 0; 00303 } 00304 00305 LOG_ARG("result: %d, value: %f", result, *valueP); 00306 00307 return result; 00308 } 00309 00310 void lwm2m_data_encode_bool(bool value, 00311 lwm2m_data_t * dataP) 00312 { 00313 LOG_ARG("value: %s", value?"true":"false"); 00314 dataP->type = LWM2M_TYPE_BOOLEAN; 00315 dataP->value.asBoolean = value; 00316 } 00317 00318 int lwm2m_data_decode_bool(const lwm2m_data_t * dataP, 00319 bool * valueP) 00320 { 00321 int result; 00322 00323 LOG("Entering"); 00324 switch (dataP->type) 00325 { 00326 case LWM2M_TYPE_BOOLEAN: 00327 *valueP = dataP->value.asBoolean; 00328 result = 1; 00329 break; 00330 00331 case LWM2M_TYPE_STRING: 00332 if (dataP->value.asBuffer.length != 1) return 0; 00333 00334 switch (dataP->value.asBuffer.buffer[0]) 00335 { 00336 case '0': 00337 *valueP = false; 00338 result = 1; 00339 break; 00340 case '1': 00341 *valueP = true; 00342 result = 1; 00343 break; 00344 default: 00345 result = 0; 00346 break; 00347 } 00348 break; 00349 00350 case LWM2M_TYPE_OPAQUE: 00351 if (dataP->value.asBuffer.length != 1) return 0; 00352 00353 switch (dataP->value.asBuffer.buffer[0]) 00354 { 00355 case 0: 00356 *valueP = false; 00357 result = 1; 00358 break; 00359 case 1: 00360 *valueP = true; 00361 result = 1; 00362 break; 00363 default: 00364 result = 0; 00365 break; 00366 } 00367 break; 00368 00369 default: 00370 result = 0; 00371 break; 00372 } 00373 00374 LOG_ARG("result: %d, value: %s", result, *valueP ? "true" : "false"); 00375 00376 return result; 00377 } 00378 00379 void lwm2m_data_encode_objlink(uint16_t objectId, 00380 uint16_t objectInstanceId, 00381 lwm2m_data_t * dataP) 00382 { 00383 LOG_ARG("value: %d/%d", objectId, objectInstanceId); 00384 dataP->type = LWM2M_TYPE_OBJECT_LINK; 00385 dataP->value.asObjLink.objectId = objectId; 00386 dataP->value.asObjLink.objectInstanceId = objectInstanceId; 00387 } 00388 00389 void lwm2m_data_include(lwm2m_data_t * subDataP, 00390 size_t count, 00391 lwm2m_data_t * dataP) 00392 { 00393 LOG_ARG("count: %d", count); 00394 if (subDataP == NULL || count == 0) return; 00395 00396 switch (subDataP[0].type) 00397 { 00398 case LWM2M_TYPE_STRING: 00399 case LWM2M_TYPE_OPAQUE: 00400 case LWM2M_TYPE_INTEGER: 00401 case LWM2M_TYPE_FLOAT: 00402 case LWM2M_TYPE_BOOLEAN: 00403 case LWM2M_TYPE_OBJECT_LINK: 00404 case LWM2M_TYPE_MULTIPLE_RESOURCE: 00405 dataP->type = LWM2M_TYPE_OBJECT_INSTANCE; 00406 break; 00407 case LWM2M_TYPE_OBJECT_INSTANCE: 00408 dataP->type = LWM2M_TYPE_OBJECT; 00409 break; 00410 default: 00411 return; 00412 } 00413 dataP->value.asChildren.count = count; 00414 dataP->value.asChildren.array = subDataP; 00415 } 00416 00417 void lwm2m_data_encode_instances(lwm2m_data_t * subDataP, 00418 size_t count, 00419 lwm2m_data_t * dataP) 00420 { 00421 LOG_ARG("count: %d", count); 00422 lwm2m_data_include(subDataP, count, dataP); 00423 dataP->type = LWM2M_TYPE_MULTIPLE_RESOURCE; 00424 } 00425 00426 int lwm2m_data_parse(lwm2m_uri_t * uriP, 00427 uint8_t * buffer, 00428 size_t bufferLen, 00429 lwm2m_media_type_t format, 00430 lwm2m_data_t ** dataP) 00431 { 00432 LOG_ARG("format: %s, bufferLen: %d", STR_MEDIA_TYPE(format), bufferLen); 00433 LOG_URI(uriP); 00434 switch (format) 00435 { 00436 case LWM2M_CONTENT_TEXT: 00437 if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return 0; 00438 *dataP = lwm2m_data_new(1); 00439 if (*dataP == NULL) return 0; 00440 (*dataP)->id = uriP->resourceId; 00441 (*dataP)->type = LWM2M_TYPE_STRING; 00442 return prv_setBuffer(*dataP, buffer, bufferLen); 00443 00444 case LWM2M_CONTENT_OPAQUE: 00445 if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) return 0; 00446 *dataP = lwm2m_data_new(1); 00447 if (*dataP == NULL) return 0; 00448 (*dataP)->id = uriP->resourceId; 00449 (*dataP)->type = LWM2M_TYPE_OPAQUE; 00450 return prv_setBuffer(*dataP, buffer, bufferLen); 00451 00452 #ifdef LWM2M_OLD_CONTENT_FORMAT_SUPPORT 00453 case LWM2M_CONTENT_TLV_OLD: 00454 #endif 00455 case LWM2M_CONTENT_TLV: 00456 return tlv_parse(buffer, bufferLen, dataP); 00457 00458 #ifdef LWM2M_SUPPORT_JSON 00459 #ifdef LWM2M_OLD_CONTENT_FORMAT_SUPPORT 00460 case LWM2M_CONTENT_JSON_OLD: 00461 #endif 00462 case LWM2M_CONTENT_JSON: 00463 return json_parse(uriP, buffer, bufferLen, dataP); 00464 #endif 00465 00466 default: 00467 return 0; 00468 } 00469 } 00470 00471 int lwm2m_data_serialize(lwm2m_uri_t * uriP, 00472 int size, 00473 lwm2m_data_t * dataP, 00474 lwm2m_media_type_t * formatP, 00475 uint8_t ** bufferP) 00476 { 00477 LOG_URI(uriP); 00478 LOG_ARG("size: %d, formatP: %s", size, STR_MEDIA_TYPE(*formatP)); 00479 00480 // Check format 00481 if (*formatP == LWM2M_CONTENT_TEXT 00482 || *formatP == LWM2M_CONTENT_OPAQUE) 00483 { 00484 if (size != 1 00485 || (uriP != NULL && !LWM2M_URI_IS_SET_RESOURCE(uriP)) 00486 || dataP->type == LWM2M_TYPE_OBJECT 00487 || dataP->type == LWM2M_TYPE_OBJECT_INSTANCE 00488 || dataP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) 00489 { 00490 #ifdef LWM2M_SUPPORT_JSON 00491 *formatP = LWM2M_CONTENT_JSON; 00492 #else 00493 *formatP = LWM2M_CONTENT_TLV; 00494 #endif 00495 } 00496 } 00497 00498 if (*formatP == LWM2M_CONTENT_TEXT 00499 && dataP->type == LWM2M_TYPE_OPAQUE) 00500 { 00501 *formatP = LWM2M_CONTENT_OPAQUE; 00502 } 00503 LOG_ARG("Final format: %s", STR_MEDIA_TYPE(*formatP)); 00504 00505 switch (*formatP) 00506 { 00507 case LWM2M_CONTENT_TEXT: 00508 return prv_textSerialize(dataP, bufferP); 00509 00510 case LWM2M_CONTENT_OPAQUE: 00511 *bufferP = (uint8_t *)lwm2m_malloc(dataP->value.asBuffer.length); 00512 if (*bufferP == NULL) return -1; 00513 memcpy(*bufferP, dataP->value.asBuffer.buffer, dataP->value.asBuffer.length); 00514 return (int)dataP->value.asBuffer.length; 00515 00516 case LWM2M_CONTENT_TLV: 00517 { 00518 bool isResourceInstance; 00519 00520 if (uriP != NULL && LWM2M_URI_IS_SET_RESOURCE(uriP) 00521 && (size != 1 || dataP->id != uriP->resourceId)) 00522 { 00523 isResourceInstance = true; 00524 } 00525 else 00526 { 00527 isResourceInstance = false; 00528 } 00529 return tlv_serialize(isResourceInstance, size, dataP, bufferP); 00530 } 00531 00532 #ifdef LWM2M_CLIENT_MODE 00533 case LWM2M_CONTENT_LINK: 00534 return discover_serialize(NULL, uriP, NULL, size, dataP, bufferP); 00535 #endif 00536 #ifdef LWM2M_SUPPORT_JSON 00537 case LWM2M_CONTENT_JSON: 00538 return json_serialize(uriP, size, dataP, bufferP); 00539 #endif 00540 00541 default: 00542 return -1; 00543 } 00544 } 00545
Generated on Sun Jul 17 2022 20:01:04 by
1.7.2