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.
utils.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 * Toby Jaffey - Please refer to git log 00016 * 00017 *******************************************************************************/ 00018 00019 /* 00020 Copyright (c) 2013, 2014 Intel Corporation 00021 00022 Redistribution and use in source and binary forms, with or without modification, 00023 are permitted provided that the following conditions are met: 00024 00025 * Redistributions of source code must retain the above copyright notice, 00026 this list of conditions and the following disclaimer. 00027 * Redistributions in binary form must reproduce the above copyright notice, 00028 this list of conditions and the following disclaimer in the documentation 00029 and/or other materials provided with the distribution. 00030 * Neither the name of Intel Corporation nor the names of its contributors 00031 may be used to endorse or promote products derived from this software 00032 without specific prior written permission. 00033 00034 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00035 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00036 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00037 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00038 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00039 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00040 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00041 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00042 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 00043 THE POSSIBILITY OF SUCH DAMAGE. 00044 00045 David Navarro <david.navarro@intel.com> 00046 00047 */ 00048 00049 #include "internals.h" 00050 #include <stdlib.h> 00051 #include <string.h> 00052 #include <stdio.h> 00053 #include <float.h> 00054 00055 00056 int utils_plainTextToInt64(uint8_t * buffer, 00057 int length, 00058 int64_t * dataP) 00059 { 00060 uint64_t result = 0; 00061 int sign = 1; 00062 int i = 0; 00063 00064 if (0 == length) return 0; 00065 00066 if (buffer[0] == '-') 00067 { 00068 sign = -1; 00069 i = 1; 00070 } 00071 00072 while (i < length) 00073 { 00074 if ('0' <= buffer[i] && buffer[i] <= '9') 00075 { 00076 if (result > (UINT64_MAX / 10)) return 0; 00077 result *= 10; 00078 result += buffer[i] - '0'; 00079 } 00080 else 00081 { 00082 return 0; 00083 } 00084 i++; 00085 } 00086 00087 if (result > INT64_MAX) return 0; 00088 00089 if (sign == -1) 00090 { 00091 *dataP = 0 - result; 00092 } 00093 else 00094 { 00095 *dataP = result; 00096 } 00097 00098 return 1; 00099 } 00100 00101 int utils_plainTextToFloat64(uint8_t * buffer, 00102 int length, 00103 double * dataP) 00104 { 00105 double result; 00106 int sign; 00107 int i; 00108 00109 if (0 == length) return 0; 00110 00111 if (buffer[0] == '-') 00112 { 00113 sign = -1; 00114 i = 1; 00115 } 00116 else 00117 { 00118 sign = 1; 00119 i = 0; 00120 } 00121 00122 result = 0; 00123 while (i < length && buffer[i] != '.') 00124 { 00125 if ('0' <= buffer[i] && buffer[i] <= '9') 00126 { 00127 if (result > (DBL_MAX / 10)) return 0; 00128 result *= 10; 00129 result += (buffer[i] - '0'); 00130 } 00131 else 00132 { 00133 return 0; 00134 } 00135 i++; 00136 } 00137 if (buffer[i] == '.') 00138 { 00139 double dec; 00140 00141 i++; 00142 if (i == length) return 0; 00143 00144 dec = 0.1; 00145 while (i < length) 00146 { 00147 if ('0' <= buffer[i] && buffer[i] <= '9') 00148 { 00149 if (result > (DBL_MAX - 1)) return 0; 00150 result += (buffer[i] - '0') * dec; 00151 dec /= 10; 00152 } 00153 else 00154 { 00155 return 0; 00156 } 00157 i++; 00158 } 00159 } 00160 00161 *dataP = result * sign; 00162 return 1; 00163 } 00164 00165 size_t utils_intToText(int64_t data, 00166 uint8_t * string, 00167 size_t length) 00168 { 00169 int index; 00170 bool minus; 00171 size_t result; 00172 00173 if (data < 0) 00174 { 00175 minus = true; 00176 data = 0 - data; 00177 } 00178 else 00179 { 00180 minus = false; 00181 } 00182 00183 index = length - 1; 00184 do 00185 { 00186 string[index] = '0' + data%10; 00187 data /= 10; 00188 index --; 00189 } while (index >= 0 && data > 0); 00190 00191 if (data > 0) return 0; 00192 00193 if (minus == true) 00194 { 00195 if (index == 0) return 0; 00196 string[index] = '-'; 00197 } 00198 else 00199 { 00200 index++; 00201 } 00202 00203 result = length - index; 00204 00205 if (result < length) 00206 { 00207 memmove(string, string + index, result); 00208 } 00209 00210 return result; 00211 } 00212 00213 size_t utils_floatToText(double data, 00214 uint8_t * string, 00215 size_t length) 00216 { 00217 size_t intLength; 00218 size_t decLength; 00219 int64_t intPart; 00220 double decPart; 00221 00222 if (data <= (double)INT64_MIN || data >= (double)INT64_MAX) return 0; 00223 00224 intPart = (int64_t)data; 00225 decPart = data - intPart; 00226 if (decPart < 0) 00227 { 00228 decPart = 1 - decPart; 00229 } 00230 else 00231 { 00232 decPart = 1 + decPart; 00233 } 00234 00235 if (decPart <= 1 + FLT_EPSILON) 00236 { 00237 decPart = 0; 00238 } 00239 00240 if (intPart == 0 && data < 0) 00241 { 00242 // deal with numbers between -1 and 0 00243 if (length < 4) return 0; // "-0.n" 00244 string[0] = '-'; 00245 string[1] = '0'; 00246 intLength = 2; 00247 } 00248 else 00249 { 00250 intLength = utils_intToText(intPart, string, length); 00251 if (intLength == 0) return 0; 00252 } 00253 decLength = 0; 00254 if (decPart >= FLT_EPSILON) 00255 { 00256 double noiseFloor; 00257 00258 if (intLength >= length - 1) return 0; 00259 00260 noiseFloor = FLT_EPSILON; 00261 do 00262 { 00263 decPart *= 10; 00264 noiseFloor *= 10; 00265 } while (decPart - (int64_t)decPart > noiseFloor); 00266 00267 decLength = utils_intToText(decPart, string + intLength, length - intLength); 00268 if (decLength <= 1) return 0; 00269 00270 // replace the leading 1 with a dot 00271 string[intLength] = '.'; 00272 } 00273 00274 return intLength + decLength; 00275 } 00276 00277 size_t utils_int64ToPlainText(int64_t data, 00278 uint8_t ** bufferP) 00279 { 00280 #define _PRV_STR_LENGTH 32 00281 uint8_t string[_PRV_STR_LENGTH]; 00282 size_t length; 00283 00284 length = utils_intToText(data, string, _PRV_STR_LENGTH); 00285 if (length == 0) return 0; 00286 00287 *bufferP = (uint8_t *)lwm2m_malloc(length); 00288 if (NULL == *bufferP) return 0; 00289 00290 memcpy(*bufferP, string, length); 00291 00292 return length; 00293 } 00294 00295 00296 size_t utils_float64ToPlainText(double data, 00297 uint8_t ** bufferP) 00298 { 00299 uint8_t string[_PRV_STR_LENGTH * 2]; 00300 size_t length; 00301 00302 length = utils_floatToText(data, string, _PRV_STR_LENGTH * 2); 00303 if (length == 0) return 0; 00304 00305 *bufferP = (uint8_t *)lwm2m_malloc(length); 00306 if (NULL == *bufferP) return 0; 00307 00308 memcpy(*bufferP, string, length); 00309 00310 return length; 00311 } 00312 00313 00314 size_t utils_boolToPlainText(bool data, 00315 uint8_t ** bufferP) 00316 { 00317 return utils_int64ToPlainText((int64_t)(data?1:0), bufferP); 00318 } 00319 00320 lwm2m_binding_t utils_stringToBinding(uint8_t * buffer, 00321 size_t length) 00322 { 00323 if (length == 0) return BINDING_UNKNOWN; 00324 00325 switch (buffer[0]) 00326 { 00327 case 'U': 00328 switch (length) 00329 { 00330 case 1: 00331 return BINDING_U; 00332 case 2: 00333 switch (buffer[1]) 00334 { 00335 case 'Q': 00336 return BINDING_UQ; 00337 case 'S': 00338 return BINDING_US; 00339 default: 00340 break; 00341 } 00342 break; 00343 case 3: 00344 if (buffer[1] == 'Q' && buffer[2] == 'S') 00345 { 00346 return BINDING_UQS; 00347 } 00348 break; 00349 default: 00350 break; 00351 } 00352 break; 00353 00354 case 'S': 00355 switch (length) 00356 { 00357 case 1: 00358 return BINDING_S; 00359 case 2: 00360 if (buffer[1] == 'Q') 00361 { 00362 return BINDING_SQ; 00363 } 00364 break; 00365 default: 00366 break; 00367 } 00368 break; 00369 00370 default: 00371 break; 00372 } 00373 00374 return BINDING_UNKNOWN; 00375 } 00376 00377 lwm2m_media_type_t utils_convertMediaType(coap_content_type_t type) 00378 { 00379 // Here we just check the content type is a valid value for LWM2M 00380 switch((uint16_t)type) 00381 { 00382 case TEXT_PLAIN: 00383 return LWM2M_CONTENT_TEXT; 00384 case APPLICATION_OCTET_STREAM: 00385 return LWM2M_CONTENT_OPAQUE; 00386 case LWM2M_CONTENT_TLV_OLD: 00387 return LWM2M_CONTENT_TLV_OLD; 00388 case LWM2M_CONTENT_TLV: 00389 return LWM2M_CONTENT_TLV; 00390 case LWM2M_CONTENT_JSON_OLD: 00391 return LWM2M_CONTENT_JSON_OLD; 00392 case LWM2M_CONTENT_JSON: 00393 return LWM2M_CONTENT_JSON; 00394 case APPLICATION_LINK_FORMAT: 00395 return LWM2M_CONTENT_LINK; 00396 00397 default: 00398 return LWM2M_CONTENT_TEXT; 00399 } 00400 } 00401 00402 #ifdef LWM2M_CLIENT_MODE 00403 lwm2m_server_t * utils_findServer(lwm2m_context_t * contextP, 00404 void * fromSessionH) 00405 { 00406 lwm2m_server_t * targetP; 00407 00408 targetP = contextP->serverList; 00409 while (targetP != NULL 00410 && false == lwm2m_session_is_equal(targetP->sessionH, fromSessionH, contextP->userData)) 00411 { 00412 targetP = targetP->next; 00413 } 00414 00415 return targetP; 00416 } 00417 #endif 00418 00419 lwm2m_server_t * utils_findBootstrapServer(lwm2m_context_t * contextP, 00420 void * fromSessionH) 00421 { 00422 #ifdef LWM2M_CLIENT_MODE 00423 00424 lwm2m_server_t * targetP; 00425 00426 targetP = contextP->bootstrapServerList; 00427 while (targetP != NULL 00428 && false == lwm2m_session_is_equal(targetP->sessionH, fromSessionH, contextP->userData)) 00429 { 00430 targetP = targetP->next; 00431 } 00432 00433 return targetP; 00434 00435 #else 00436 00437 return NULL; 00438 00439 #endif 00440 } 00441 00442 int utils_isAltPathValid(const char * altPath) 00443 { 00444 int i; 00445 00446 if (altPath == NULL) return 0; 00447 00448 if (altPath[0] != '/') return 0; 00449 00450 for (i = 1 ; altPath[i] != 0 ; i++) 00451 { 00452 // TODO: Support multi-segment alternative path 00453 if (altPath[i] == '/') return 0; 00454 // TODO: Check needs for sub-delims, ':' and '@' 00455 if ((altPath[i] < 'A' || altPath[i] > 'Z') // ALPHA 00456 && (altPath[i] < 'a' || altPath[i] > 'z') 00457 && (altPath[i] < '0' || altPath[i] > '9') // DIGIT 00458 && (altPath[i] != '-') // Other unreserved 00459 && (altPath[i] != '.') 00460 && (altPath[i] != '_') 00461 && (altPath[i] != '~') 00462 && (altPath[i] != '%')) // pct_encoded 00463 { 00464 return 0; 00465 } 00466 00467 } 00468 return 1; 00469 } 00470 00471 // copy a string in a buffer. 00472 // return the number of copied bytes or -1 if the buffer is not large enough 00473 int utils_stringCopy(char * buffer, 00474 size_t length, 00475 const char * str) 00476 { 00477 size_t i; 00478 00479 for (i = 0 ; i < length && str[i] != 0 ; i++) 00480 { 00481 buffer[i] = str[i]; 00482 } 00483 00484 if (i == length) return -1; 00485 00486 buffer[i] = 0; 00487 00488 return (int)i; 00489 } 00490 00491 int utils_intCopy(char * buffer, 00492 size_t length, 00493 int32_t value) 00494 { 00495 #define _PRV_INT32_MAX_STR_LEN 11 00496 uint8_t str[_PRV_INT32_MAX_STR_LEN]; 00497 size_t len; 00498 00499 len = utils_intToText(value, str, _PRV_INT32_MAX_STR_LEN); 00500 if (len == 0) return -1; 00501 if (len > length + 1) return -1; 00502 00503 memcpy(buffer, str, len); 00504 buffer[len] = 0; 00505 00506 return len; 00507 } 00508 00509 void utils_copyValue(void * dst, 00510 const void * src, 00511 size_t len) 00512 { 00513 #ifdef LWM2M_BIG_ENDIAN 00514 memcpy(dst, src, len); 00515 #else 00516 #ifdef LWM2M_LITTLE_ENDIAN 00517 size_t i; 00518 00519 for (i = 0; i < len; i++) 00520 { 00521 ((uint8_t *)dst)[i] = ((uint8_t *)src)[len - 1 - i]; 00522 } 00523 #endif 00524 #endif 00525 } 00526 00527 int utils_opaqueToInt(const uint8_t * buffer, 00528 size_t buffer_len, 00529 int64_t * dataP) 00530 { 00531 *dataP = 0; 00532 00533 switch (buffer_len) 00534 { 00535 case 1: 00536 { 00537 *dataP = (int8_t)buffer[0]; 00538 00539 break; 00540 } 00541 00542 case 2: 00543 { 00544 int16_t value; 00545 00546 utils_copyValue(&value, buffer, buffer_len); 00547 00548 *dataP = value; 00549 break; 00550 } 00551 00552 case 4: 00553 { 00554 int32_t value; 00555 00556 utils_copyValue(&value, buffer, buffer_len); 00557 00558 *dataP = value; 00559 break; 00560 } 00561 00562 case 8: 00563 utils_copyValue(dataP, buffer, buffer_len); 00564 return buffer_len; 00565 00566 default: 00567 return 0; 00568 } 00569 00570 return buffer_len; 00571 } 00572 00573 int utils_opaqueToFloat(const uint8_t * buffer, 00574 size_t buffer_len, 00575 double * dataP) 00576 { 00577 switch (buffer_len) 00578 { 00579 case 4: 00580 { 00581 float temp; 00582 00583 utils_copyValue(&temp, buffer, buffer_len); 00584 00585 *dataP = temp; 00586 } 00587 return 4; 00588 00589 case 8: 00590 utils_copyValue(dataP, buffer, buffer_len); 00591 return 8; 00592 00593 default: 00594 return 0; 00595 } 00596 } 00597 00598 /** 00599 * Encode an integer value to a byte representation. 00600 * Returns the length of the result. For values < 0xff length is 1, 00601 * for values < 0xffff length is 2 and so on. 00602 * @param data Input value 00603 * @param data_buffer Result in data_buffer is in big endian encoding 00604 * Negative values are represented in two's complement as of 00605 * OMA-TS-LightweightM2M-V1_0-20160308-D, Appendix C 00606 */ 00607 size_t utils_encodeInt(int64_t data, 00608 uint8_t data_buffer[_PRV_64BIT_BUFFER_SIZE]) 00609 { 00610 size_t length = 0; 00611 00612 memset(data_buffer, 0, _PRV_64BIT_BUFFER_SIZE); 00613 00614 if (data >= INT8_MIN && data <= INT8_MAX) 00615 { 00616 length = 1; 00617 data_buffer[0] = data; 00618 } 00619 else if (data >= INT16_MIN && data <= INT16_MAX) 00620 { 00621 int16_t value; 00622 00623 value = data; 00624 length = 2; 00625 data_buffer[0] = (value >> 8) & 0xFF; 00626 data_buffer[1] = value & 0xFF; 00627 } 00628 else if (data >= INT32_MIN && data <= INT32_MAX) 00629 { 00630 int32_t value; 00631 00632 value = data; 00633 length = 4; 00634 utils_copyValue(data_buffer, &value, length); 00635 } 00636 else if (data >= INT64_MIN && data <= INT64_MAX) 00637 { 00638 length = 8; 00639 utils_copyValue(data_buffer, &data, length); 00640 } 00641 00642 return length; 00643 } 00644 00645 size_t utils_encodeFloat(double data, 00646 uint8_t data_buffer[_PRV_64BIT_BUFFER_SIZE]) 00647 { 00648 size_t length = 0; 00649 00650 memset(data_buffer, 0, _PRV_64BIT_BUFFER_SIZE); 00651 00652 if ((data < 0.0 - (double)FLT_MAX) || (data >(double)FLT_MAX)) 00653 { 00654 length = 8; 00655 utils_copyValue(data_buffer, &data, 8); 00656 } 00657 else 00658 { 00659 float value; 00660 00661 length = 4; 00662 value = (float)data; 00663 utils_copyValue(data_buffer, &value, 4); 00664 } 00665 00666 return length; 00667 } 00668 00669 #define PRV_B64_PADDING '=' 00670 00671 static char b64Alphabet[64] = 00672 { 00673 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 00674 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 00675 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 00676 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' 00677 }; 00678 00679 static void prv_encodeBlock(uint8_t input[3], 00680 uint8_t output[4]) 00681 { 00682 output[0] = b64Alphabet[input[0] >> 2]; 00683 output[1] = b64Alphabet[((input[0] & 0x03) << 4) | (input[1] >> 4)]; 00684 output[2] = b64Alphabet[((input[1] & 0x0F) << 2) | (input[2] >> 6)]; 00685 output[3] = b64Alphabet[input[2] & 0x3F]; 00686 } 00687 00688 static uint8_t prv_b64Revert(uint8_t value) 00689 { 00690 if (value >= 'A' && value <= 'Z') 00691 { 00692 return (value - 'A'); 00693 } 00694 if (value >= 'a' && value <= 'z') 00695 { 00696 return (26 + value - 'a'); 00697 } 00698 if (value >= '0' && value <= '9') 00699 { 00700 return (52 + value - '0'); 00701 } 00702 switch (value) 00703 { 00704 case '+': 00705 return 62; 00706 case '/': 00707 return 63; 00708 default: 00709 return 0; 00710 } 00711 } 00712 00713 static void prv_decodeBlock(uint8_t input[4], 00714 uint8_t output[3]) 00715 { 00716 uint8_t tmp[4]; 00717 int i; 00718 00719 memset(output, 0, 3); 00720 00721 for (i = 0; i < 4; i++) 00722 { 00723 tmp[i] = prv_b64Revert(input[i]); 00724 } 00725 00726 output[0] = (tmp[0] << 2) | (tmp[1] >> 4); 00727 output[1] = (tmp[1] << 4) | (tmp[2] >> 2); 00728 output[2] = (tmp[2] << 6) | tmp[3]; 00729 } 00730 00731 static size_t prv_getBase64Size(size_t dataLen) 00732 { 00733 size_t result_len; 00734 00735 result_len = 4 * (dataLen / 3); 00736 if (dataLen % 3) result_len += 4; 00737 00738 return result_len; 00739 } 00740 00741 size_t utils_base64Encode(uint8_t * dataP, 00742 size_t dataLen, 00743 uint8_t * bufferP, 00744 size_t bufferLen) 00745 { 00746 unsigned int data_index; 00747 unsigned int result_index; 00748 size_t result_len; 00749 00750 result_len = prv_getBase64Size(dataLen); 00751 00752 if (result_len > bufferLen) return 0; 00753 00754 data_index = 0; 00755 result_index = 0; 00756 while (data_index < dataLen) 00757 { 00758 switch (dataLen - data_index) 00759 { 00760 case 0: 00761 // should never happen 00762 break; 00763 case 1: 00764 bufferP[result_index] = b64Alphabet[dataP[data_index] >> 2]; 00765 bufferP[result_index + 1] = b64Alphabet[(dataP[data_index] & 0x03) << 4]; 00766 bufferP[result_index + 2] = PRV_B64_PADDING; 00767 bufferP[result_index + 3] = PRV_B64_PADDING; 00768 break; 00769 case 2: 00770 bufferP[result_index] = b64Alphabet[dataP[data_index] >> 2]; 00771 bufferP[result_index + 1] = b64Alphabet[(dataP[data_index] & 0x03) << 4 | (dataP[data_index + 1] >> 4)]; 00772 bufferP[result_index + 2] = b64Alphabet[(dataP[data_index + 1] & 0x0F) << 2]; 00773 bufferP[result_index + 3] = PRV_B64_PADDING; 00774 break; 00775 default: 00776 prv_encodeBlock(dataP + data_index, bufferP + result_index); 00777 break; 00778 } 00779 data_index += 3; 00780 result_index += 4; 00781 } 00782 00783 return result_len; 00784 } 00785 00786 size_t utils_opaqueToBase64(uint8_t * dataP, 00787 size_t dataLen, 00788 uint8_t ** bufferP) 00789 { 00790 size_t buffer_len; 00791 size_t result_len; 00792 00793 buffer_len = prv_getBase64Size(dataLen); 00794 00795 *bufferP = (uint8_t *)lwm2m_malloc(buffer_len); 00796 if (!*bufferP) return 0; 00797 memset(*bufferP, 0, buffer_len); 00798 00799 result_len = utils_base64Encode(dataP, dataLen, *bufferP, buffer_len); 00800 00801 if (result_len == 0) 00802 { 00803 lwm2m_free(*bufferP); 00804 *bufferP = NULL; 00805 } 00806 00807 return result_len; 00808 } 00809 00810 size_t utils_base64ToOpaque(uint8_t * dataP, 00811 size_t dataLen, 00812 uint8_t ** bufferP) 00813 { 00814 size_t data_index; 00815 size_t result_index; 00816 size_t result_len; 00817 00818 if (dataLen % 4) return 0; 00819 00820 result_len = (dataLen >> 2) * 3; 00821 *bufferP = (uint8_t *)lwm2m_malloc(result_len); 00822 if (NULL == *bufferP) return 0; 00823 memset(*bufferP, 0, result_len); 00824 00825 // remove padding 00826 while (dataP[dataLen - 1] == PRV_B64_PADDING) 00827 { 00828 dataLen--; 00829 } 00830 00831 data_index = 0; 00832 result_index = 0; 00833 while (data_index < dataLen) 00834 { 00835 prv_decodeBlock(dataP + data_index, *bufferP + result_index); 00836 data_index += 4; 00837 result_index += 3; 00838 } 00839 switch (data_index - dataLen) 00840 { 00841 case 0: 00842 break; 00843 case 2: 00844 { 00845 uint8_t tmp[2]; 00846 00847 tmp[0] = prv_b64Revert(dataP[dataLen - 2]); 00848 tmp[1] = prv_b64Revert(dataP[dataLen - 1]); 00849 00850 *bufferP[result_index - 3] = (tmp[0] << 2) | (tmp[1] >> 4); 00851 *bufferP[result_index - 2] = (tmp[1] << 4); 00852 result_len -= 2; 00853 } 00854 break; 00855 case 3: 00856 { 00857 uint8_t tmp[3]; 00858 00859 tmp[0] = prv_b64Revert(dataP[dataLen - 3]); 00860 tmp[1] = prv_b64Revert(dataP[dataLen - 2]); 00861 tmp[2] = prv_b64Revert(dataP[dataLen - 1]); 00862 00863 *bufferP[result_index - 3] = (tmp[0] << 2) | (tmp[1] >> 4); 00864 *bufferP[result_index - 2] = (tmp[1] << 4) | (tmp[2] >> 2); 00865 *bufferP[result_index - 1] = (tmp[2] << 6); 00866 result_len -= 1; 00867 } 00868 break; 00869 default: 00870 // error 00871 lwm2m_free(*bufferP); 00872 *bufferP = NULL; 00873 result_len = 0; 00874 break; 00875 } 00876 00877 return result_len; 00878 } 00879 00880 lwm2m_data_type_t utils_depthToDatatype(uri_depth_t depth) 00881 { 00882 switch (depth) 00883 { 00884 case URI_DEPTH_OBJECT: 00885 return LWM2M_TYPE_OBJECT; 00886 case URI_DEPTH_OBJECT_INSTANCE: 00887 return LWM2M_TYPE_OBJECT_INSTANCE; 00888 default: 00889 break; 00890 } 00891 00892 return LWM2M_TYPE_UNDEFINED; 00893 }
Generated on Sun Jul 17 2022 20:01:04 by
1.7.2