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.
uri.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 * Bosch Software Innovations GmbH - Please refer to git log 00018 * Pascal Rieux - Please refer to git log 00019 * 00020 *******************************************************************************/ 00021 00022 /* 00023 Copyright (c) 2013, 2014 Intel Corporation 00024 00025 Redistribution and use in source and binary forms, with or without modification, 00026 are permitted provided that the following conditions are met: 00027 00028 * Redistributions of source code must retain the above copyright notice, 00029 this list of conditions and the following disclaimer. 00030 * Redistributions in binary form must reproduce the above copyright notice, 00031 this list of conditions and the following disclaimer in the documentation 00032 and/or other materials provided with the distribution. 00033 * Neither the name of Intel Corporation nor the names of its contributors 00034 may be used to endorse or promote products derived from this software 00035 without specific prior written permission. 00036 00037 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00038 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00039 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00040 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00041 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00042 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00043 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00044 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00045 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 00046 THE POSSIBILITY OF SUCH DAMAGE. 00047 00048 David Navarro <david.navarro@intel.com> 00049 00050 */ 00051 00052 #include "internals.h" 00053 #include <stdlib.h> 00054 #include <string.h> 00055 #include <ctype.h> 00056 00057 00058 static int prv_parseNumber(uint8_t * uriString, 00059 size_t uriLength, 00060 size_t * headP) 00061 { 00062 int result = 0; 00063 00064 if (uriString[*headP] == '/') 00065 { 00066 // empty Object Instance ID with resource ID is not allowed 00067 return -1; 00068 } 00069 while (*headP < uriLength && uriString[*headP] != '/') 00070 { 00071 if ('0' <= uriString[*headP] && uriString[*headP] <= '9') 00072 { 00073 result += uriString[*headP] - '0'; 00074 result *= 10; 00075 } 00076 else 00077 { 00078 return -1; 00079 } 00080 *headP += 1; 00081 } 00082 00083 result /= 10; 00084 return result; 00085 } 00086 00087 00088 int uri_getNumber(uint8_t * uriString, 00089 size_t uriLength) 00090 { 00091 size_t index = 0; 00092 00093 return prv_parseNumber(uriString, uriLength, &index); 00094 } 00095 00096 00097 lwm2m_uri_t * uri_decode(char * altPath, 00098 multi_option_t *uriPath) 00099 { 00100 lwm2m_uri_t * uriP; 00101 int readNum; 00102 00103 LOG_ARG("altPath: \"%s\"", altPath); 00104 00105 uriP = (lwm2m_uri_t *)lwm2m_malloc(sizeof(lwm2m_uri_t)); 00106 if (NULL == uriP) return NULL; 00107 00108 memset(uriP, 0, sizeof(lwm2m_uri_t)); 00109 00110 // Read object ID 00111 if (NULL != uriPath 00112 && URI_REGISTRATION_SEGMENT_LEN == uriPath->len 00113 && 0 == strncmp(URI_REGISTRATION_SEGMENT, (char *)uriPath->data, uriPath->len)) 00114 { 00115 uriP->flag |= LWM2M_URI_FLAG_REGISTRATION; 00116 uriPath = uriPath->next; 00117 if (uriPath == NULL) return uriP; 00118 } 00119 else if (NULL != uriPath 00120 && URI_BOOTSTRAP_SEGMENT_LEN == uriPath->len 00121 && 0 == strncmp(URI_BOOTSTRAP_SEGMENT, (char *)uriPath->data, uriPath->len)) 00122 { 00123 uriP->flag |= LWM2M_URI_FLAG_BOOTSTRAP; 00124 uriPath = uriPath->next; 00125 if (uriPath != NULL) goto error; 00126 return uriP; 00127 } 00128 00129 if ((uriP->flag & LWM2M_URI_MASK_TYPE) != LWM2M_URI_FLAG_REGISTRATION) 00130 { 00131 // Read altPath if any 00132 if (altPath != NULL) 00133 { 00134 int i; 00135 if (NULL == uriPath) 00136 { 00137 lwm2m_free(uriP); 00138 return NULL; 00139 } 00140 for (i = 0 ; i < uriPath->len ; i++) 00141 { 00142 if (uriPath->data[i] != altPath[i+1]) 00143 { 00144 lwm2m_free(uriP); 00145 return NULL; 00146 } 00147 } 00148 uriPath = uriPath->next; 00149 } 00150 if (NULL == uriPath || uriPath->len == 0) 00151 { 00152 uriP->flag |= LWM2M_URI_FLAG_DELETE_ALL; 00153 return uriP; 00154 } 00155 } 00156 00157 readNum = uri_getNumber(uriPath->data, uriPath->len); 00158 if (readNum < 0 || readNum > LWM2M_MAX_ID) goto error; 00159 uriP->objectId = (uint16_t)readNum; 00160 uriP->flag |= LWM2M_URI_FLAG_OBJECT_ID; 00161 uriPath = uriPath->next; 00162 00163 if ((uriP->flag & LWM2M_URI_MASK_TYPE) == LWM2M_URI_FLAG_REGISTRATION) 00164 { 00165 if (uriPath != NULL) goto error; 00166 return uriP; 00167 } 00168 uriP->flag |= LWM2M_URI_FLAG_DM; 00169 00170 if (uriPath == NULL) return uriP; 00171 00172 // Read object instance 00173 if (uriPath->len != 0) 00174 { 00175 readNum = uri_getNumber(uriPath->data, uriPath->len); 00176 if (readNum < 0 || readNum >= LWM2M_MAX_ID) goto error; 00177 uriP->instanceId = (uint16_t)readNum; 00178 uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; 00179 } 00180 uriPath = uriPath->next; 00181 00182 if (uriPath == NULL) return uriP; 00183 00184 // Read resource ID 00185 if (uriPath->len != 0) 00186 { 00187 // resource ID without an instance ID is not allowed 00188 if ((uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0) goto error; 00189 00190 readNum = uri_getNumber(uriPath->data, uriPath->len); 00191 if (readNum < 0 || readNum > LWM2M_MAX_ID) goto error; 00192 uriP->resourceId = (uint16_t)readNum; 00193 uriP->flag |= LWM2M_URI_FLAG_RESOURCE_ID; 00194 } 00195 00196 // must be the last segment 00197 if (NULL == uriPath->next) 00198 { 00199 LOG_URI(uriP); 00200 return uriP; 00201 } 00202 00203 error: 00204 LOG("Exiting on error"); 00205 lwm2m_free(uriP); 00206 return NULL; 00207 } 00208 00209 int lwm2m_stringToUri(const char * buffer, 00210 size_t buffer_len, 00211 lwm2m_uri_t * uriP) 00212 { 00213 size_t head; 00214 int readNum; 00215 00216 LOG_ARG("buffer_len: %u, buffer: \"%.*s\"", buffer_len, buffer_len, buffer); 00217 00218 if (buffer == NULL || buffer_len == 0 || uriP == NULL) return 0; 00219 00220 memset(uriP, 0, sizeof(lwm2m_uri_t)); 00221 00222 // Skip any white space 00223 head = 0; 00224 while (head < buffer_len && isspace(buffer[head]&0xFF)) 00225 { 00226 head++; 00227 } 00228 if (head == buffer_len) return 0; 00229 00230 // Check the URI start with a '/' 00231 if (buffer[head] != '/') return 0; 00232 head++; 00233 if (head == buffer_len) return 0; 00234 00235 // Read object ID 00236 readNum = prv_parseNumber((uint8_t *)buffer, buffer_len, &head); 00237 if (readNum < 0 || readNum > LWM2M_MAX_ID) return 0; 00238 uriP->objectId = (uint16_t)readNum; 00239 uriP->flag |= LWM2M_URI_FLAG_OBJECT_ID; 00240 00241 if (buffer[head] == '/') head += 1; 00242 if (head >= buffer_len) 00243 { 00244 LOG_ARG("Parsed characters: %u", head); 00245 LOG_URI(uriP); 00246 return head; 00247 } 00248 00249 readNum = prv_parseNumber((uint8_t *)buffer, buffer_len, &head); 00250 if (readNum < 0 || readNum >= LWM2M_MAX_ID) return 0; 00251 uriP->instanceId = (uint16_t)readNum; 00252 uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; 00253 00254 if (buffer[head] == '/') head += 1; 00255 if (head >= buffer_len) 00256 { 00257 LOG_ARG("Parsed characters: %u", head); 00258 LOG_URI(uriP); 00259 return head; 00260 } 00261 00262 readNum = prv_parseNumber((uint8_t *)buffer, buffer_len, &head); 00263 if (readNum < 0 || readNum >= LWM2M_MAX_ID) return 0; 00264 uriP->resourceId = (uint16_t)readNum; 00265 uriP->flag |= LWM2M_URI_FLAG_RESOURCE_ID; 00266 00267 if (head != buffer_len) return 0; 00268 00269 LOG_ARG("Parsed characters: %u", head); 00270 LOG_URI(uriP); 00271 00272 return head; 00273 } 00274 00275 int uri_toString(lwm2m_uri_t * uriP, 00276 uint8_t * buffer, 00277 size_t bufferLen, 00278 uri_depth_t * depthP) 00279 { 00280 size_t head; 00281 int res; 00282 00283 LOG_ARG("bufferLen: %u", bufferLen); 00284 LOG_URI(uriP); 00285 00286 buffer[0] = '/'; 00287 00288 if (uriP == NULL) 00289 { 00290 if (depthP) *depthP = URI_DEPTH_OBJECT; 00291 return 1; 00292 } 00293 00294 head = 1; 00295 00296 res = utils_intToText(uriP->objectId, buffer + head, bufferLen - head); 00297 if (res <= 0) return -1; 00298 head += res; 00299 if (head >= bufferLen - 1) return -1; 00300 if (depthP) *depthP = URI_DEPTH_OBJECT_INSTANCE; 00301 00302 if (LWM2M_URI_IS_SET_INSTANCE(uriP)) 00303 { 00304 buffer[head] = '/'; 00305 head++; 00306 res = utils_intToText(uriP->instanceId, buffer + head, bufferLen - head); 00307 if (res <= 0) return -1; 00308 head += res; 00309 if (head >= bufferLen - 1) return -1; 00310 if (depthP) *depthP = URI_DEPTH_RESOURCE; 00311 if (LWM2M_URI_IS_SET_RESOURCE(uriP)) 00312 { 00313 buffer[head] = '/'; 00314 head++; 00315 res = utils_intToText(uriP->resourceId, buffer + head, bufferLen - head); 00316 if (res <= 0) return -1; 00317 head += res; 00318 if (head >= bufferLen - 1) return -1; 00319 if (depthP) *depthP = URI_DEPTH_RESOURCE_INSTANCE; 00320 } 00321 } 00322 00323 buffer[head] = '/'; 00324 head++; 00325 00326 LOG_ARG("length: %u, buffer: \"%.*s\"", head, head, buffer); 00327 00328 return head; 00329 }
Generated on Thu Jul 14 2022 09:09:49 by
1.7.2