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.
discover.c
00001 /******************************************************************************* 00002 * 00003 * Copyright (c) 2015 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 * 00016 *******************************************************************************/ 00017 00018 00019 #include "internals.h" 00020 00021 #define PRV_LINK_BUFFER_SIZE 1024 00022 00023 00024 #define PRV_CONCAT_STR(buf, len, index, str, str_len) \ 00025 { \ 00026 if ((len)-(index) < (str_len)) return -1; \ 00027 memcpy((buf)+(index), (str), (str_len)); \ 00028 (index) += (str_len); \ 00029 } 00030 00031 00032 #ifdef LWM2M_CLIENT_MODE 00033 00034 static lwm2m_attributes_t * prv_findAttributes(lwm2m_context_t * contextP, 00035 lwm2m_uri_t * uriP, 00036 lwm2m_server_t * serverP) 00037 { 00038 lwm2m_observed_t * observedP; 00039 lwm2m_watcher_t * watcherP; 00040 lwm2m_attributes_t * paramP; 00041 00042 paramP = NULL; 00043 00044 if (contextP == NULL) return NULL; 00045 if (serverP == NULL) return NULL; 00046 00047 observedP = observe_findByUri(contextP, uriP); 00048 if (observedP == NULL || observedP->watcherList == NULL) return NULL; 00049 00050 for (watcherP = observedP->watcherList; watcherP != NULL; watcherP = watcherP->next) 00051 { 00052 if (watcherP->server == serverP) 00053 { 00054 paramP = watcherP->parameters; 00055 } 00056 } 00057 00058 return paramP; 00059 } 00060 00061 static int prv_serializeAttributes(lwm2m_context_t * contextP, 00062 lwm2m_uri_t * uriP, 00063 lwm2m_server_t * serverP, 00064 lwm2m_attributes_t * objectParamP, 00065 uint8_t * buffer, 00066 size_t uriLen, 00067 size_t bufferLen) 00068 { 00069 int head; 00070 int res; 00071 lwm2m_attributes_t * paramP; 00072 00073 head = 0; 00074 00075 paramP = prv_findAttributes(contextP, uriP, serverP); 00076 if (paramP == NULL) paramP = objectParamP; 00077 00078 if (paramP != NULL) 00079 { 00080 head = uriLen; 00081 00082 if (paramP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) 00083 { 00084 PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE); 00085 PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN); 00086 00087 res = utils_intToText(paramP->minPeriod, buffer + head, bufferLen - head); 00088 if (res <= 0) return -1; 00089 head += res; 00090 } 00091 else if (objectParamP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) 00092 { 00093 PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE); 00094 PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MIN_PERIOD_STR, ATTR_MIN_PERIOD_LEN); 00095 00096 res = utils_intToText(objectParamP->minPeriod, buffer + head, bufferLen - head); 00097 if (res <= 0) return -1; 00098 head += res; 00099 } 00100 00101 if (paramP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) 00102 { 00103 PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE); 00104 PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN); 00105 00106 res = utils_intToText(paramP->maxPeriod, buffer + head, bufferLen - head); 00107 if (res <= 0) return -1; 00108 head += res; 00109 } 00110 else if (objectParamP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) 00111 { 00112 PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE); 00113 PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_MAX_PERIOD_STR, ATTR_MAX_PERIOD_LEN); 00114 00115 res = utils_intToText(objectParamP->maxPeriod, buffer + head, bufferLen - head); 00116 if (res <= 0) return -1; 00117 head += res; 00118 } 00119 00120 if (paramP->toSet & LWM2M_ATTR_FLAG_GREATER_THAN) 00121 { 00122 PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE); 00123 PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_GREATER_THAN_STR, ATTR_GREATER_THAN_LEN); 00124 00125 res = utils_floatToText(paramP->greaterThan, buffer + head, bufferLen - head); 00126 if (res <= 0) return -1; 00127 head += res; 00128 } 00129 if (paramP->toSet & LWM2M_ATTR_FLAG_LESS_THAN) 00130 { 00131 PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE); 00132 PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_LESS_THAN_STR, ATTR_LESS_THAN_LEN); 00133 00134 res = utils_floatToText(paramP->lessThan, buffer + head, bufferLen - head); 00135 if (res <= 0) return -1; 00136 head += res; 00137 } 00138 if (paramP->toSet & LWM2M_ATTR_FLAG_STEP) 00139 { 00140 PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ATTR_SEPARATOR, LINK_ATTR_SEPARATOR_SIZE); 00141 PRV_CONCAT_STR(buffer, bufferLen, head, ATTR_STEP_STR, ATTR_STEP_LEN); 00142 00143 res = utils_floatToText(paramP->step, buffer + head, bufferLen - head); 00144 if (res <= 0) return -1; 00145 head += res; 00146 } 00147 PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ITEM_ATTR_END, LINK_ITEM_ATTR_END_SIZE); 00148 } 00149 00150 if (head > 0) head -= uriLen + 1; 00151 00152 return head; 00153 } 00154 00155 static int prv_serializeLinkData(lwm2m_context_t * contextP, 00156 lwm2m_data_t * tlvP, 00157 lwm2m_server_t * serverP, 00158 lwm2m_attributes_t * objectParamP, 00159 lwm2m_uri_t * parentUriP, 00160 uint8_t * parentUriStr, 00161 size_t parentUriLen, 00162 uint8_t * buffer, 00163 size_t bufferLen) 00164 { 00165 int head; 00166 int res; 00167 lwm2m_uri_t uri; 00168 00169 head = 0; 00170 00171 switch (tlvP->type) 00172 { 00173 case LWM2M_TYPE_UNDEFINED: 00174 case LWM2M_TYPE_STRING: 00175 case LWM2M_TYPE_OPAQUE: 00176 case LWM2M_TYPE_INTEGER: 00177 case LWM2M_TYPE_FLOAT: 00178 case LWM2M_TYPE_BOOLEAN: 00179 case LWM2M_TYPE_OBJECT_LINK: 00180 case LWM2M_TYPE_MULTIPLE_RESOURCE: 00181 if (bufferLen < LINK_ITEM_START_SIZE) return -1; 00182 memcpy(buffer + head, LINK_ITEM_START, LINK_ITEM_START_SIZE); 00183 head = LINK_ITEM_START_SIZE; 00184 00185 if (parentUriLen > 0) 00186 { 00187 if (bufferLen - head < parentUriLen) return -1; 00188 memcpy(buffer + head, parentUriStr, parentUriLen); 00189 head += parentUriLen; 00190 } 00191 00192 if (bufferLen - head < LINK_URI_SEPARATOR_SIZE) return -1; 00193 memcpy(buffer + head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE); 00194 head += LINK_URI_SEPARATOR_SIZE; 00195 00196 res = utils_intToText(tlvP->id, buffer + head, bufferLen - head); 00197 if (res <= 0) return -1; 00198 head += res; 00199 00200 if (tlvP->type == LWM2M_TYPE_MULTIPLE_RESOURCE) 00201 { 00202 if (bufferLen - head < LINK_ITEM_DIM_START_SIZE) return -1; 00203 memcpy(buffer + head, LINK_ITEM_DIM_START, LINK_ITEM_DIM_START_SIZE); 00204 head += LINK_ITEM_DIM_START_SIZE; 00205 00206 res = utils_intToText(tlvP->value.asChildren.count, buffer + head, bufferLen - head); 00207 if (res <= 0) return -1; 00208 head += res; 00209 00210 if (bufferLen - head < LINK_ITEM_ATTR_END_SIZE) return -1; 00211 memcpy(buffer + head, LINK_ITEM_ATTR_END, LINK_ITEM_ATTR_END_SIZE); 00212 head += LINK_ITEM_ATTR_END_SIZE; 00213 } 00214 else 00215 { 00216 if (bufferLen - head < LINK_ITEM_END_SIZE) return -1; 00217 memcpy(buffer + head, LINK_ITEM_END, LINK_ITEM_END_SIZE); 00218 head += LINK_ITEM_END_SIZE; 00219 } 00220 00221 if (serverP != NULL) 00222 { 00223 memcpy(&uri, parentUriP, sizeof(lwm2m_uri_t)); 00224 uri.resourceId = tlvP->id; 00225 uri.flag |= LWM2M_URI_FLAG_RESOURCE_ID; 00226 res = prv_serializeAttributes(contextP, &uri, serverP, objectParamP, buffer, head - 1, bufferLen); 00227 if (res < 0) return -1; // careful, 0 is valid 00228 if (res > 0) head += res; 00229 } 00230 break; 00231 00232 case LWM2M_TYPE_OBJECT_INSTANCE: 00233 { 00234 uint8_t uriStr[URI_MAX_STRING_LEN]; 00235 size_t uriLen; 00236 size_t index; 00237 00238 if (parentUriLen > 0) 00239 { 00240 if (URI_MAX_STRING_LEN < parentUriLen) return -1; 00241 memcpy(uriStr, parentUriStr, parentUriLen); 00242 uriLen = parentUriLen; 00243 } 00244 else 00245 { 00246 uriLen = 0; 00247 } 00248 00249 if (URI_MAX_STRING_LEN - uriLen < LINK_URI_SEPARATOR_SIZE) return -1; 00250 memcpy(uriStr + uriLen, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE); 00251 uriLen += LINK_URI_SEPARATOR_SIZE; 00252 00253 res = utils_intToText(tlvP->id, uriStr + uriLen, URI_MAX_STRING_LEN - uriLen); 00254 if (res <= 0) return -1; 00255 uriLen += res; 00256 00257 memcpy(&uri, parentUriP, sizeof(lwm2m_uri_t)); 00258 uri.instanceId = tlvP->id; 00259 uri.flag |= LWM2M_URI_FLAG_INSTANCE_ID; 00260 00261 head = 0; 00262 PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ITEM_START, LINK_ITEM_START_SIZE); 00263 PRV_CONCAT_STR(buffer, bufferLen, head, uriStr, uriLen); 00264 PRV_CONCAT_STR(buffer, bufferLen, head, LINK_ITEM_END, LINK_ITEM_END_SIZE); 00265 if (serverP != NULL) 00266 { 00267 res = prv_serializeAttributes(contextP, &uri, serverP, NULL, buffer, head - 1, bufferLen); 00268 if (res < 0) return -1; // careful, 0 is valid 00269 if (res == 0) head = 0; // rewind 00270 else head += res; 00271 } 00272 for (index = 0; index < tlvP->value.asChildren.count; index++) 00273 { 00274 res = prv_serializeLinkData(contextP, tlvP->value.asChildren.array + index, serverP, objectParamP, &uri, uriStr, uriLen, buffer + head, bufferLen - head); 00275 if (res < 0) return -1; 00276 head += res; 00277 } 00278 } 00279 break; 00280 00281 case LWM2M_TYPE_OBJECT: 00282 default: 00283 return -1; 00284 } 00285 00286 return head; 00287 } 00288 00289 int discover_serialize(lwm2m_context_t * contextP, 00290 lwm2m_uri_t * uriP, 00291 lwm2m_server_t * serverP, 00292 int size, 00293 lwm2m_data_t * dataP, 00294 uint8_t ** bufferP) 00295 { 00296 uint8_t bufferLink[PRV_LINK_BUFFER_SIZE]; 00297 uint8_t baseUriStr[URI_MAX_STRING_LEN]; 00298 int baseUriLen; 00299 int index; 00300 size_t head; 00301 int res; 00302 lwm2m_uri_t parentUri; 00303 lwm2m_attributes_t * paramP; 00304 lwm2m_attributes_t mergedParam; 00305 00306 LOG_ARG("size: %d", size); 00307 LOG_URI(uriP); 00308 00309 head = 0; 00310 memset(&parentUri, 0, sizeof(lwm2m_uri_t)); 00311 parentUri.objectId = uriP->objectId; 00312 parentUri.flag = LWM2M_URI_FLAG_OBJECT_ID; 00313 00314 if (LWM2M_URI_IS_SET_RESOURCE(uriP)) 00315 { 00316 lwm2m_uri_t tempUri; 00317 lwm2m_attributes_t * objParamP; 00318 lwm2m_attributes_t * instParamP; 00319 00320 memset(&parentUri, 0, sizeof(lwm2m_uri_t)); 00321 tempUri.objectId = uriP->objectId; 00322 tempUri.flag = LWM2M_URI_FLAG_OBJECT_ID; 00323 00324 // get object level attributes 00325 objParamP = prv_findAttributes(contextP, &tempUri, serverP); 00326 00327 // get object instance level attributes 00328 tempUri.instanceId = uriP->instanceId; 00329 tempUri.flag = LWM2M_URI_FLAG_INSTANCE_ID; 00330 instParamP = prv_findAttributes(contextP, &tempUri, serverP); 00331 00332 if (objParamP != NULL) 00333 { 00334 if (instParamP != NULL) 00335 { 00336 memset(&mergedParam, 0, sizeof(lwm2m_attributes_t)); 00337 mergedParam.toSet = objParamP->toSet | instParamP->toSet; 00338 if (mergedParam.toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) 00339 { 00340 if (instParamP->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) 00341 { 00342 mergedParam.minPeriod = instParamP->minPeriod; 00343 } 00344 else 00345 { 00346 mergedParam.minPeriod = objParamP->minPeriod; 00347 } 00348 } 00349 if (mergedParam.toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) 00350 { 00351 if (instParamP->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) 00352 { 00353 mergedParam.maxPeriod = instParamP->maxPeriod; 00354 } 00355 else 00356 { 00357 mergedParam.maxPeriod = objParamP->maxPeriod; 00358 } 00359 } 00360 paramP = &mergedParam; 00361 } 00362 else 00363 { 00364 paramP = objParamP; 00365 } 00366 } 00367 else 00368 { 00369 paramP = instParamP; 00370 } 00371 uriP->flag &= ~LWM2M_URI_FLAG_RESOURCE_ID; 00372 } 00373 else 00374 { 00375 paramP = NULL; 00376 00377 if (LWM2M_URI_IS_SET_INSTANCE(uriP)) 00378 { 00379 PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_START, LINK_ITEM_START_SIZE); 00380 PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE); 00381 res = utils_intToText(uriP->objectId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head); 00382 if (res <= 0) return -1; 00383 head += res; 00384 PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE); 00385 res = utils_intToText(uriP->instanceId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head); 00386 if (res <= 0) return -1; 00387 head += res; 00388 PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_END, LINK_ITEM_END_SIZE); 00389 parentUri.instanceId = uriP->instanceId; 00390 parentUri.flag = LWM2M_URI_FLAG_INSTANCE_ID; 00391 if (serverP != NULL) 00392 { 00393 res = prv_serializeAttributes(contextP, &parentUri, serverP, NULL, bufferLink, head - 1, PRV_LINK_BUFFER_SIZE); 00394 if (res < 0) return -1; // careful, 0 is valid 00395 } 00396 else 00397 { 00398 res = 0; 00399 } 00400 head += res; 00401 } 00402 else 00403 { 00404 PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_START, LINK_ITEM_START_SIZE); 00405 PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE); 00406 res = utils_intToText(uriP->objectId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head); 00407 if (res <= 0) return -1; 00408 head += res; 00409 PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_END, LINK_ITEM_END_SIZE); 00410 00411 if (serverP != NULL) 00412 { 00413 res = prv_serializeAttributes(contextP, &parentUri, serverP, NULL, bufferLink, head - 1, PRV_LINK_BUFFER_SIZE); 00414 if (res < 0) return -1; // careful, 0 is valid 00415 head += res; 00416 } 00417 } 00418 } 00419 00420 baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, NULL); 00421 if (baseUriLen < 0) return -1; 00422 baseUriLen -= 1; 00423 00424 for (index = 0; index < size && head < PRV_LINK_BUFFER_SIZE; index++) 00425 { 00426 res = prv_serializeLinkData(contextP, dataP + index, serverP, paramP, uriP, baseUriStr, baseUriLen, bufferLink + head, PRV_LINK_BUFFER_SIZE - head); 00427 if (res < 0) return -1; 00428 head += res; 00429 } 00430 00431 if (head > 0) 00432 { 00433 head -= 1; 00434 00435 *bufferP = (uint8_t *)lwm2m_malloc(head); 00436 if (*bufferP == NULL) return 0; 00437 memcpy(*bufferP, bufferLink, head); 00438 } 00439 00440 return (int)head; 00441 } 00442 #endif
Generated on Thu Jul 14 2022 09:09:49 by
1.7.2