int json_serialize(lwm2m_uri_t * uriP, int size, lwm2m_data_t * tlvP, uint8_t ** bufferP) { int index; size_t head; uint8_t bufferJSON[PRV_JSON_BUFFER_SIZE]; uint8_t baseUriStr[URI_MAX_STRING_LEN]; int baseUriLen; uri_depth_t rootLevel; int num; lwm2m_data_t * targetP; LOG_ARG("size: %d", size); LOG_URI(uriP); if (size != 0 && tlvP == NULL) return -1; baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, &rootLevel); if (baseUriLen < 0) return -1; num = prv_findAndCheckData(uriP, rootLevel, size, tlvP, &targetP); if (num < 0) return -1; while (num == 1 && (targetP->type == LWM2M_TYPE_OBJECT || targetP->type == LWM2M_TYPE_OBJECT_INSTANCE || targetP->type == LWM2M_TYPE_MULTIPLE_RESOURCE)) { int res; res = utils_intToText(targetP->id, baseUriStr + baseUriLen, URI_MAX_STRING_LEN - baseUriLen); if (res <= 0) return 0; baseUriLen += res; if (baseUriLen >= URI_MAX_STRING_LEN -1) return 0; num = targetP->value.asChildren.count; targetP = targetP->value.asChildren.array; baseUriStr[baseUriLen] = '/'; baseUriLen++; } if (baseUriLen > 0) { memcpy(bufferJSON, JSON_BN_HEADER_1, JSON_BN_HEADER_1_SIZE); head = JSON_BN_HEADER_1_SIZE; memcpy(bufferJSON + head, baseUriStr, baseUriLen); head += baseUriLen; memcpy(bufferJSON + head, JSON_BN_HEADER_2, JSON_BN_HEADER_2_SIZE); head += JSON_BN_HEADER_2_SIZE; } else { memcpy(bufferJSON, JSON_HEADER, JSON_HEADER_SIZE); head = JSON_HEADER_SIZE; } for (index = 0 ; index < num && head < PRV_JSON_BUFFER_SIZE ; index++) { int res; res = prv_serializeData(targetP + index, NULL, 0, bufferJSON + head, PRV_JSON_BUFFER_SIZE - head); if (res < 0) return res; head += res; } if (head + JSON_FOOTER_SIZE - 1 > PRV_JSON_BUFFER_SIZE) return 0; if (num > 0) head = head - 1; memcpy(bufferJSON + head, JSON_FOOTER, JSON_FOOTER_SIZE); head = head + JSON_FOOTER_SIZE; *bufferP = (uint8_t *)lwm2m_malloc(head); if (*bufferP == NULL) return -1; memcpy(*bufferP, bufferJSON, head); return head; }
int discover_serialize(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, int size, lwm2m_data_t * dataP, uint8_t ** bufferP) { uint8_t bufferLink[PRV_LINK_BUFFER_SIZE]; uint8_t baseUriStr[URI_MAX_STRING_LEN]; int baseUriLen; int index; size_t head; int res; lwm2m_uri_t tempUri; baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, NULL); if (baseUriLen < 0) return -1; baseUriLen -= 1; head = 0; memset(&tempUri, 0, sizeof(lwm2m_uri_t)); // get object level attributes PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_START, LINK_ITEM_START_SIZE); PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE); res = utils_intToText(uriP->objectId, bufferLink + head, PRV_LINK_BUFFER_SIZE - head); if (res <= 0) return -1; head += res; PRV_CONCAT_STR(bufferLink, PRV_LINK_BUFFER_SIZE, head, LINK_ITEM_END, LINK_ITEM_END_SIZE); tempUri.objectId = uriP->objectId; res = prv_serializeAttributes(contextP, &tempUri, bufferLink, head - 1, PRV_LINK_BUFFER_SIZE); if (res < 0) return -1; // careful, 0 is valid if (res == 0) head = 0; // rewind else head += res - 1; if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { size_t subHead; // get object instance level attributes subHead = 0; PRV_CONCAT_STR(bufferLink + head, PRV_LINK_BUFFER_SIZE - head, subHead, LINK_ITEM_START, LINK_ITEM_START_SIZE); PRV_CONCAT_STR(bufferLink + head, PRV_LINK_BUFFER_SIZE - head, subHead, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE); res = utils_intToText(uriP->objectId, bufferLink + head + subHead, PRV_LINK_BUFFER_SIZE - head - subHead); if (res <= 0) return -1; subHead += res; PRV_CONCAT_STR(bufferLink + head, PRV_LINK_BUFFER_SIZE - head, subHead, LINK_URI_SEPARATOR, LINK_URI_SEPARATOR_SIZE); res = utils_intToText(uriP->instanceId, bufferLink + head + subHead, PRV_LINK_BUFFER_SIZE - head - subHead); if (res <= 0) return -1; subHead += res; PRV_CONCAT_STR(bufferLink + head, PRV_LINK_BUFFER_SIZE - head, subHead, LINK_ITEM_END, LINK_ITEM_END_SIZE); tempUri.instanceId = uriP->instanceId; tempUri.flag = LWM2M_URI_FLAG_INSTANCE_ID; res = prv_serializeAttributes(contextP, &tempUri, bufferLink + head, head + subHead - 1, PRV_LINK_BUFFER_SIZE); if (res < 0) return -1; // careful, 0 is valid if (res == 0) subHead = 0; // rewind else subHead += res - 1; head += subHead; } for (index = 0; index < size && head < PRV_LINK_BUFFER_SIZE; index++) { res = prv_serializeLinkData(contextP, dataP + index, uriP, baseUriStr, baseUriLen, bufferLink + head, PRV_LINK_BUFFER_SIZE - head); if (res < 0) return -1; head += res; } if (head > 0) { head -= 1; *bufferP = (uint8_t *)lwm2m_malloc(head); if (*bufferP == NULL) return 0; memcpy(*bufferP, bufferLink, head); } return (int)head; }
int senml_json_serialize(const lwm2m_uri_t * uriP, int size, const lwm2m_data_t * tlvP, uint8_t ** bufferP) { int index; size_t head; uint8_t bufferJSON[PRV_JSON_BUFFER_SIZE]; uint8_t baseUriStr[URI_MAX_STRING_LEN]; int baseUriLen; uri_depth_t rootLevel; uri_depth_t baseLevel; int num; lwm2m_data_t * targetP; const uint8_t *parentUriStr = NULL; size_t parentUriLen = 0; LOG_ARG("size: %d", size); LOG_URI(uriP); if (size != 0 && tlvP == NULL) return -1; baseUriLen = uri_toString(uriP, baseUriStr, URI_MAX_STRING_LEN, &baseLevel); if (baseUriLen < 0) return -1; if (baseUriLen > 1 && baseLevel != URI_DEPTH_RESOURCE && baseLevel != URI_DEPTH_RESOURCE_INSTANCE) { if (baseUriLen >= URI_MAX_STRING_LEN -1) return 0; baseUriStr[baseUriLen++] = '/'; } num = json_findAndCheckData(uriP, json_decreaseLevel(baseLevel), size, tlvP, &targetP); if (num < 0) return -1; switch (tlvP->type) { case LWM2M_TYPE_OBJECT: rootLevel = URI_DEPTH_OBJECT; break; case LWM2M_TYPE_OBJECT_INSTANCE: rootLevel = URI_DEPTH_OBJECT_INSTANCE; break; case LWM2M_TYPE_MULTIPLE_RESOURCE: if (baseUriLen > 1 && baseUriStr[baseUriLen - 1] != '/') { if (baseUriLen >= URI_MAX_STRING_LEN -1) return 0; baseUriStr[baseUriLen++] = '/'; } rootLevel = URI_DEPTH_RESOURCE_INSTANCE; break; default: if (baseLevel == URI_DEPTH_RESOURCE_INSTANCE) { rootLevel = URI_DEPTH_RESOURCE_INSTANCE; } else { rootLevel = URI_DEPTH_RESOURCE; } break; } if (!baseUriLen || baseUriStr[baseUriLen - 1] != '/') { parentUriStr = (const uint8_t *)"/"; parentUriLen = 1; } head = 0; bufferJSON[head++] = JSON_HEADER; bool baseNameOutput = false; for (index = 0 ; index < num && head < PRV_JSON_BUFFER_SIZE ; index++) { int res; if (index != 0) { if (head + 1 > PRV_JSON_BUFFER_SIZE) return 0; bufferJSON[head++] = JSON_SEPARATOR; } res = prv_serializeData(targetP + index, baseUriStr, baseUriLen, baseLevel, parentUriStr, parentUriLen, rootLevel, &baseNameOutput, bufferJSON + head, PRV_JSON_BUFFER_SIZE - head); if (res < 0) return res; head += res; } if (head + 1 > PRV_JSON_BUFFER_SIZE) return 0; bufferJSON[head++] = JSON_FOOTER; *bufferP = (uint8_t *)lwm2m_malloc(head); if (*bufferP == NULL) return -1; memcpy(*bufferP, bufferJSON, head); return head; }