static int prv_serializeValue(lwm2m_data_t * tlvP, uint8_t * buffer, size_t bufferLen) { int res; int head; res = lwm2m_snprintf((char *)(char *)buffer, bufferLen, JSON_RES_ITEM_TEMPLATE, tlvP->id); if (res <= 0 || res >= bufferLen) return -1; switch (tlvP->dataType) { case LWM2M_TYPE_STRING: res = lwm2m_snprintf((char *)buffer, bufferLen, JSON_ITEM_STRING_BEGIN); if (res <= 0 || res >= bufferLen) return -1; head = res; if (tlvP->length >= bufferLen - head) return -1; memcpy(buffer + head, tlvP->value, tlvP->length); head += tlvP->length; res = lwm2m_snprintf((char *)buffer + head, bufferLen - head, JSON_ITEM_STRING_END); if (res <= 0 || res >= bufferLen - head) return -1; res += head; break; case LWM2M_TYPE_INTEGER: case LWM2M_TYPE_TIME: { int64_t value; if (0 == lwm2m_data_decode_int(tlvP, &value)) return -1; res = lwm2m_snprintf((char *)buffer, bufferLen, JSON_ITEM_INTEGER_TEMPLATE, value); if (res <= 0 || res >= bufferLen) return -1; } break; case LWM2M_TYPE_FLOAT: { double value; if (0 == lwm2m_data_decode_float(tlvP, &value)) return -1; res = lwm2m_snprintf((char *)buffer, bufferLen, JSON_ITEM_FLOAT_TEMPLATE, value); if (res <= 0 || res >= bufferLen) return -1; } break; case LWM2M_TYPE_BOOLEAN: { bool value; if (0 == lwm2m_data_decode_bool(tlvP, &value)) return -1; res = lwm2m_snprintf((char *)buffer, bufferLen, value?JSON_ITEM_BOOL_TRUE:JSON_ITEM_BOOL_FALSE); if (res <= 0 || res >= bufferLen) return -1; } break; case LWM2M_TYPE_OPAQUE: // TODO: base64 encoding res = lwm2m_snprintf((char *)buffer, bufferLen, JSON_ITEM_STRING_BEGIN); if (res <= 0 || res >= bufferLen) return -1; head = res; if (tlvP->length >= bufferLen - head) return -1; memcpy(buffer + head, tlvP->value, tlvP->length); head += tlvP->length; res = lwm2m_snprintf((char *)buffer + head, bufferLen - head, JSON_ITEM_STRING_END); if (res <= 0 || res >= bufferLen - head) return -1; res += head; break; case LWM2M_TYPE_OBJECT_LINK: // TODO: implement return -1; case LWM2M_TYPE_UNDEFINED: if ((tlvP->flags & LWM2M_TLV_FLAG_TEXT_FORMAT) != 0) { res = lwm2m_snprintf((char *)buffer, bufferLen, JSON_ITEM_STRING_BEGIN); if (res <= 0 || res >= bufferLen) return -1; head = res; if (tlvP->length >= bufferLen - head) return -1; memcpy(buffer + head, tlvP->value, tlvP->length); head += tlvP->length; res = lwm2m_snprintf((char *)buffer + head, bufferLen - head, JSON_ITEM_STRING_END); if (res <= 0 || res >= bufferLen - head) return -1; res += head; } else { return -1; } break; default: break; } return res; }
int object_getServers(lwm2m_context_t * contextP) { lwm2m_object_t * objectP; lwm2m_object_t * securityObjP = NULL; lwm2m_object_t * serverObjP = NULL; lwm2m_list_t * securityInstP; // instanceID of the server in the LWM2M Security Object for (objectP = contextP->objectList; objectP != NULL; objectP = objectP->next) { if (objectP->objID == LWM2M_SECURITY_OBJECT_ID) { securityObjP = objectP; } else if (objectP->objID == LWM2M_SERVER_OBJECT_ID) { serverObjP = objectP; } } if (NULL == securityObjP) return -1; securityInstP = securityObjP->instanceList; while (securityInstP != NULL) { if (LWM2M_LIST_FIND(contextP->bootstrapServerList, securityInstP->id) == NULL && LWM2M_LIST_FIND(contextP->serverList, securityInstP->id) == NULL) { // This server is new. eg created by last bootstrap lwm2m_data_t * dataP; int size; lwm2m_server_t * targetP; bool isBootstrap; int64_t value = 0; size = 3; dataP = lwm2m_data_new(size); if (dataP == NULL) return -1; dataP[0].id = LWM2M_SECURITY_BOOTSTRAP_ID; dataP[1].id = LWM2M_SECURITY_SHORT_SERVER_ID; dataP[2].id = LWM2M_SECURITY_HOLD_OFF_ID; if (securityObjP->readFunc(securityInstP->id, &size, &dataP, securityObjP) != COAP_205_CONTENT) { lwm2m_data_free(size, dataP); return -1; } targetP = (lwm2m_server_t *)lwm2m_malloc(sizeof(lwm2m_server_t)); if (targetP == NULL) { lwm2m_data_free(size, dataP); return -1; } memset(targetP, 0, sizeof(lwm2m_server_t)); targetP->secObjInstID = securityInstP->id; if (0 == lwm2m_data_decode_bool(dataP + 0, &isBootstrap)) { lwm2m_free(targetP); lwm2m_data_free(size, dataP); return -1; } if (0 == lwm2m_data_decode_int(dataP + 1, &value) || value < (isBootstrap ? 0 : 1) || value > 0xFFFF) // 0 is forbidden as a Short Server ID { lwm2m_free(targetP); lwm2m_data_free(size, dataP); return -1; } targetP->shortID = value; if (isBootstrap == true) { if (0 == lwm2m_data_decode_int(dataP + 2, &value) || value < 0 || value > 0xFFFFFFFF) // This is an implementation limit { lwm2m_free(targetP); lwm2m_data_free(size, dataP); return -1; } // lifetime of a bootstrap server is set to ClientHoldOffTime targetP->lifetime = value; contextP->bootstrapServerList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->bootstrapServerList, targetP); } else { lwm2m_list_t * serverInstP; // instanceID of the server in the LWM2M Server Object serverInstP = prv_findServerInstance(serverObjP, targetP->shortID); if (serverInstP == NULL) { lwm2m_free(targetP); lwm2m_data_free(size, dataP); return -1; } if (0 != prv_getMandatoryInfo(serverObjP, serverInstP->id, targetP)) { lwm2m_free(targetP); lwm2m_data_free(size, dataP); return -1; } targetP->status = STATE_DEREGISTERED; contextP->serverList = (lwm2m_server_t*)LWM2M_LIST_ADD(contextP->serverList, targetP); } lwm2m_data_free(size, dataP); } securityInstP = securityInstP->next; } return 0; }
static uint8_t prv_security_write(uint16_t instanceId, int numData, lwm2m_data_t * dataArray, lwm2m_object_t * objectP) { security_instance_t * targetP; int i; uint8_t result = COAP_204_CHANGED; targetP = (security_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId); if (NULL == targetP) { return COAP_404_NOT_FOUND; } i = 0; do { switch (dataArray[i].id) { case LWM2M_SECURITY_URI_ID: if (targetP->uri != NULL) lwm2m_free(targetP->uri); targetP->uri = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length + 1); memset(targetP->uri, 0, dataArray[i].value.asBuffer.length + 1); if (targetP->uri != NULL) { strncpy(targetP->uri, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length); result = COAP_204_CHANGED; } else { result = COAP_500_INTERNAL_SERVER_ERROR; } break; case LWM2M_SECURITY_BOOTSTRAP_ID: if (1 == lwm2m_data_decode_bool(dataArray + i, &(targetP->isBootstrap))) { result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; case LWM2M_SECURITY_SECURITY_ID: { int64_t value; if (1 == lwm2m_data_decode_int(dataArray + i, &value)) { if (value >= 0 && value <= 3) { targetP->securityMode = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } } break; case LWM2M_SECURITY_PUBLIC_KEY_ID: if (targetP->publicIdentity != NULL) lwm2m_free(targetP->publicIdentity); targetP->publicIdentity = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length +1); memset(targetP->publicIdentity, 0, dataArray[i].value.asBuffer.length + 1); if (targetP->publicIdentity != NULL) { memcpy(targetP->publicIdentity, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length); targetP->publicIdLen = dataArray[i].value.asBuffer.length; result = COAP_204_CHANGED; } else { result = COAP_500_INTERNAL_SERVER_ERROR; } break; case LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID: if (targetP->serverPublicKey != NULL) lwm2m_free(targetP->serverPublicKey); targetP->serverPublicKey = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length +1); memset(targetP->serverPublicKey, 0, dataArray[i].value.asBuffer.length + 1); if (targetP->serverPublicKey != NULL) { memcpy(targetP->serverPublicKey, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length); targetP->serverPublicKeyLen = dataArray[i].value.asBuffer.length; result = COAP_204_CHANGED; } else { result = COAP_500_INTERNAL_SERVER_ERROR; } break; case LWM2M_SECURITY_SECRET_KEY_ID: if (targetP->secretKey != NULL) lwm2m_free(targetP->secretKey); targetP->secretKey = (char *)lwm2m_malloc(dataArray[i].value.asBuffer.length +1); memset(targetP->secretKey, 0, dataArray[i].value.asBuffer.length + 1); if (targetP->secretKey != NULL) { memcpy(targetP->secretKey, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length); targetP->secretKeyLen = dataArray[i].value.asBuffer.length; result = COAP_204_CHANGED; } else { result = COAP_500_INTERNAL_SERVER_ERROR; } break; case LWM2M_SECURITY_SMS_SECURITY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_KEY_PARAM_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_SECRET_KEY_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SMS_SERVER_NUMBER_ID: // Let just ignore this result = COAP_204_CHANGED; break; case LWM2M_SECURITY_SHORT_SERVER_ID: { int64_t value; if (1 == lwm2m_data_decode_int(dataArray + i, &value)) { if (value >= 0 && value <= 0xFFFF) { targetP->shortID = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } } break; case LWM2M_SECURITY_HOLD_OFF_ID: { int64_t value; if (1 == lwm2m_data_decode_int(dataArray + i, &value)) { if (value >= 0 && value <= 0xFFFF) { targetP->clientHoldOffTime = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } break; } default: return COAP_404_NOT_FOUND; } i++; } while (i < numData && result == COAP_204_CHANGED); return result; }
static uint8_t prv_server_write(uint16_t instanceId, int numData, lwm2m_data_t * dataArray, lwm2m_object_t * objectP) { server_instance_t * targetP; int i; uint8_t result; targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId); if (NULL == targetP) { return COAP_404_NOT_FOUND; } i = 0; do { switch (dataArray[i].id) { case LWM2M_SERVER_SHORT_ID_ID: { uint32_t value; result = prv_set_int_value(dataArray + i, &value); if (COAP_204_CHANGED == result) { if (0 < value && value <= 0xFFFF) { targetP->shortServerId = value; } else { result = COAP_406_NOT_ACCEPTABLE; } } } break; case LWM2M_SERVER_LIFETIME_ID: result = prv_set_int_value(dataArray + i, (uint32_t *)&(targetP->lifetime)); break; case LWM2M_SERVER_DISABLE_ID: result = COAP_405_METHOD_NOT_ALLOWED; break; case LWM2M_SERVER_STORING_ID: { bool value; if (1 == lwm2m_data_decode_bool(dataArray + i, &value)) { targetP->storing = value; result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } } break; case LWM2M_SERVER_BINDING_ID: if ((dataArray[i].length > 0 && dataArray[i].length <= 3) && (strncmp((char*)dataArray[i].value, "U", dataArray[i].length) == 0 || strncmp((char*)dataArray[i].value, "UQ", dataArray[i].length) == 0 || strncmp((char*)dataArray[i].value, "S", dataArray[i].length) == 0 || strncmp((char*)dataArray[i].value, "SQ", dataArray[i].length) == 0 || strncmp((char*)dataArray[i].value, "US", dataArray[i].length) == 0 || strncmp((char*)dataArray[i].value, "UQS", dataArray[i].length) == 0)) { strncpy(targetP->binding, (char*)dataArray[i].value, dataArray[i].length); result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; case LWM2M_SERVER_UPDATE_ID: result = COAP_405_METHOD_NOT_ALLOWED; break; default: return COAP_404_NOT_FOUND; } i++; } while (i < numData && result == COAP_204_CHANGED); return result; }
static uint8_t prv_server_write(uint16_t instanceId, int numData, lwm2m_data_t * dataArray, lwm2m_object_t * objectP) { server_instance_t * targetP; int i; uint8_t result; targetP = (server_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId); if (NULL == targetP) { return COAP_404_NOT_FOUND; } i = 0; do { switch (dataArray[i].id) { case LWM2M_SERVER_SHORT_ID_ID: { uint32_t value = targetP->shortServerId; result = prv_set_int_value(dataArray + i, &value); if (COAP_204_CHANGED == result) { if (0 < value && 0xFFFF >= value) { targetP->shortServerId = value; } else { result = COAP_406_NOT_ACCEPTABLE; } } } break; case LWM2M_SERVER_LIFETIME_ID: result = prv_set_int_value(dataArray + i, (uint32_t *)&(targetP->lifetime)); break; case LWM2M_SERVER_MIN_PERIOD_ID: result = prv_set_int_value(dataArray + i, &(targetP->defaultMinPeriod)); break; case LWM2M_SERVER_MAX_PERIOD_ID: result = prv_set_int_value(dataArray + i, &(targetP->defaultMaxPeriod)); break; case LWM2M_SERVER_DISABLE_ID: result = COAP_405_METHOD_NOT_ALLOWED; break; case LWM2M_SERVER_TIMEOUT_ID: result = prv_set_int_value(dataArray + i, &(targetP->disableTimeout)); break; case LWM2M_SERVER_STORING_ID: { bool value; if (1 == lwm2m_data_decode_bool(dataArray + i, &value)) { targetP->storing = value; result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } } break; case LWM2M_SERVER_BINDING_ID: if ((dataArray[i].type == LWM2M_TYPE_STRING || dataArray[i].type == LWM2M_TYPE_OPAQUE) && dataArray[i].value.asBuffer.length > 0 && dataArray[i].value.asBuffer.length <= 3 && (strncmp((char*)dataArray[i].value.asBuffer.buffer, "U", dataArray[i].value.asBuffer.length) == 0 || strncmp((char*)dataArray[i].value.asBuffer.buffer, "UQ", dataArray[i].value.asBuffer.length) == 0 || strncmp((char*)dataArray[i].value.asBuffer.buffer, "S", dataArray[i].value.asBuffer.length) == 0 || strncmp((char*)dataArray[i].value.asBuffer.buffer, "SQ", dataArray[i].value.asBuffer.length) == 0 || strncmp((char*)dataArray[i].value.asBuffer.buffer, "US", dataArray[i].value.asBuffer.length) == 0 || strncmp((char*)dataArray[i].value.asBuffer.buffer, "UQS", dataArray[i].value.asBuffer.length) == 0)) { strncpy(targetP->binding, (char*)dataArray[i].value.asBuffer.buffer, dataArray[i].value.asBuffer.length); result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; case LWM2M_SERVER_UPDATE_ID: result = COAP_405_METHOD_NOT_ALLOWED; break; #ifndef LWM2M_VERSION_1_0 case LWM2M_SERVER_REG_ORDER_ID: { uint64_t value; if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) { if (value <= INT_MAX) { targetP->registrationPriorityOrder = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } break; } case LWM2M_SERVER_INITIAL_REG_DELAY_ID: { uint64_t value; if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) { if (value <= INT_MAX) { targetP->initialRegistrationDelayTimer = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } break; } case LWM2M_SERVER_REG_FAIL_BLOCK_ID: { bool value; if (1 == lwm2m_data_decode_bool(dataArray + i, &value)) { targetP->registrationFailureBlock = value; result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; } case LWM2M_SERVER_REG_FAIL_BOOTSTRAP_ID: { bool value; if (1 == lwm2m_data_decode_bool(dataArray + i, &value)) { targetP->bootstrapOnRegistrationFailure = value; result = COAP_204_CHANGED; } else { result = COAP_400_BAD_REQUEST; } break; } case LWM2M_SERVER_COMM_RETRY_COUNT_ID: { uint64_t value; if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) { if (value <= INT_MAX) { targetP->communicationRetryCount = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } break; } case LWM2M_SERVER_COMM_RETRY_TIMER_ID: { uint64_t value; if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) { if (value <= INT_MAX) { targetP->communicationRetryTimer = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } break; } case LWM2M_SERVER_SEQ_DELAY_TIMER_ID: { uint64_t value; if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) { if (value <= INT_MAX) { targetP->communicationSequenceDelayTimer = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } break; } case LWM2M_SERVER_SEQ_RETRY_COUNT_ID: { uint64_t value; if (1 == lwm2m_data_decode_uint(dataArray + i, &value)) { if (value <= INT_MAX) { targetP->communicationSequenceRetryCount = value; result = COAP_204_CHANGED; } else { result = COAP_406_NOT_ACCEPTABLE; } } else { result = COAP_400_BAD_REQUEST; } break; } #endif default: return COAP_404_NOT_FOUND; } i++; } while (i < numData && result == COAP_204_CHANGED); return result; }
static int prv_serializeValue(lwm2m_data_t * tlvP, uint8_t * buffer, size_t bufferLen) { int res; int head; switch (tlvP->type) { case LWM2M_TYPE_STRING: if (bufferLen < JSON_ITEM_STRING_BEGIN_SIZE) return -1; memcpy(buffer, JSON_ITEM_STRING_BEGIN, JSON_ITEM_STRING_BEGIN_SIZE); head = JSON_ITEM_STRING_BEGIN_SIZE; if (bufferLen - head < tlvP->value.asBuffer.length) return -1; memcpy(buffer + head, tlvP->value.asBuffer.buffer, tlvP->value.asBuffer.length); head += tlvP->value.asBuffer.length; if (bufferLen - head < JSON_ITEM_STRING_END_SIZE) return -1; memcpy(buffer + head, JSON_ITEM_STRING_END, JSON_ITEM_STRING_END_SIZE); head += JSON_ITEM_STRING_END_SIZE; break; case LWM2M_TYPE_INTEGER: { int64_t value; if (0 == lwm2m_data_decode_int(tlvP, &value)) return -1; if (bufferLen < JSON_ITEM_NUM_SIZE) return -1; memcpy(buffer, JSON_ITEM_NUM, JSON_ITEM_NUM_SIZE); head = JSON_ITEM_NUM_SIZE; res = utils_intToText(value, buffer + head, bufferLen - head); if (res <= 0) return -1; head += res; if (bufferLen - head < JSON_ITEM_NUM_END_SIZE) return -1; memcpy(buffer + head, JSON_ITEM_NUM_END, JSON_ITEM_NUM_END_SIZE); head += JSON_ITEM_NUM_END_SIZE; } break; case LWM2M_TYPE_FLOAT: { double value; if (0 == lwm2m_data_decode_float(tlvP, &value)) return -1; if (bufferLen < JSON_ITEM_NUM_SIZE) return -1; memcpy(buffer, JSON_ITEM_NUM, JSON_ITEM_NUM_SIZE); head = JSON_ITEM_NUM_SIZE; res = utils_floatToText(value, buffer + head, bufferLen - head); if (res <= 0) return -1; head += res; if (bufferLen - head < JSON_ITEM_NUM_END_SIZE) return -1; memcpy(buffer + head, JSON_ITEM_NUM_END, JSON_ITEM_NUM_END_SIZE); head += JSON_ITEM_NUM_END_SIZE; } break; case LWM2M_TYPE_BOOLEAN: { bool value; if (0 == lwm2m_data_decode_bool(tlvP, &value)) return -1; if (value == true) { if (bufferLen < JSON_ITEM_BOOL_TRUE_SIZE) return -1; memcpy(buffer, JSON_ITEM_BOOL_TRUE, JSON_ITEM_BOOL_TRUE_SIZE); head = JSON_ITEM_BOOL_TRUE_SIZE; } else { if (bufferLen < JSON_ITEM_BOOL_FALSE_SIZE) return -1; memcpy(buffer, JSON_ITEM_BOOL_FALSE, JSON_ITEM_BOOL_FALSE_SIZE); head = JSON_ITEM_BOOL_FALSE_SIZE; } } break; case LWM2M_TYPE_OPAQUE: if (bufferLen < JSON_ITEM_STRING_BEGIN_SIZE) return -1; memcpy(buffer, JSON_ITEM_STRING_BEGIN, JSON_ITEM_STRING_BEGIN_SIZE); head = JSON_ITEM_STRING_BEGIN_SIZE; res = utils_base64Encode(tlvP->value.asBuffer.buffer, tlvP->value.asBuffer.length, buffer+head, bufferLen - head); if (tlvP->value.asBuffer.length != 0 && res == 0) return -1; head += res; if (bufferLen - head < JSON_ITEM_STRING_END_SIZE) return -1; memcpy(buffer + head, JSON_ITEM_STRING_END, JSON_ITEM_STRING_END_SIZE); head += JSON_ITEM_STRING_END_SIZE; break; case LWM2M_TYPE_OBJECT_LINK: // TODO: implement return -1; default: return -1; } return head; }
static int prv_serializeValue(const lwm2m_data_t * tlvP, uint8_t * buffer, size_t bufferLen) { size_t res; size_t head; switch (tlvP->type) { case LWM2M_TYPE_STRING: case LWM2M_TYPE_CORE_LINK: if (bufferLen < JSON_ITEM_STRING_BEGIN_SIZE) return -1; memcpy(buffer, JSON_ITEM_STRING_BEGIN, JSON_ITEM_STRING_BEGIN_SIZE); head = JSON_ITEM_STRING_BEGIN_SIZE; res = json_escapeString(buffer + head, bufferLen - head, tlvP->value.asBuffer.buffer, tlvP->value.asBuffer.length); if (!res) return -1; head += res; if (bufferLen - head < 1) return -1; buffer[head++] = JSON_ITEM_STRING_END; break; case LWM2M_TYPE_INTEGER: { int64_t value; if (0 == lwm2m_data_decode_int(tlvP, &value)) return -1; if (bufferLen < JSON_ITEM_NUM_SIZE) return -1; memcpy(buffer, JSON_ITEM_NUM, JSON_ITEM_NUM_SIZE); head = JSON_ITEM_NUM_SIZE; res = utils_intToText(value, buffer + head, bufferLen - head); if (!res) return -1; head += res; } break; case LWM2M_TYPE_UNSIGNED_INTEGER: { uint64_t value; if (0 == lwm2m_data_decode_uint(tlvP, &value)) return -1; if (bufferLen < JSON_ITEM_NUM_SIZE) return -1; memcpy(buffer, JSON_ITEM_NUM, JSON_ITEM_NUM_SIZE); head = JSON_ITEM_NUM_SIZE; res = utils_uintToText(value, buffer + head, bufferLen - head); if (!res) return -1; head += res; } break; case LWM2M_TYPE_FLOAT: { double value; if (0 == lwm2m_data_decode_float(tlvP, &value)) return -1; if (bufferLen < JSON_ITEM_NUM_SIZE) return -1; memcpy(buffer, JSON_ITEM_NUM, JSON_ITEM_NUM_SIZE); head = JSON_ITEM_NUM_SIZE; res = utils_floatToText(value, buffer + head, bufferLen - head); if (!res) return -1; head += res; } break; case LWM2M_TYPE_BOOLEAN: { bool value; if (0 == lwm2m_data_decode_bool(tlvP, &value)) return -1; if (value) { if (bufferLen < JSON_ITEM_BOOL_SIZE + JSON_TRUE_STRING_SIZE) return -1; memcpy(buffer, JSON_ITEM_BOOL JSON_TRUE_STRING, JSON_ITEM_BOOL_SIZE + JSON_TRUE_STRING_SIZE); head = JSON_ITEM_BOOL_SIZE + JSON_TRUE_STRING_SIZE; } else { if (bufferLen < JSON_ITEM_BOOL_SIZE + JSON_FALSE_STRING_SIZE) return -1; memcpy(buffer, JSON_ITEM_BOOL JSON_FALSE_STRING, JSON_ITEM_BOOL_SIZE + JSON_FALSE_STRING_SIZE); head = JSON_ITEM_BOOL_SIZE + JSON_FALSE_STRING_SIZE; } } break; case LWM2M_TYPE_OPAQUE: if (bufferLen < JSON_ITEM_OPAQUE_BEGIN_SIZE) return -1; memcpy(buffer, JSON_ITEM_OPAQUE_BEGIN, JSON_ITEM_OPAQUE_BEGIN_SIZE); head = JSON_ITEM_OPAQUE_BEGIN_SIZE; if (tlvP->value.asBuffer.length > 0) { res = utils_base64Encode(tlvP->value.asBuffer.buffer, tlvP->value.asBuffer.length, buffer+head, bufferLen - head); if (!res) return -1; head += res; } if (bufferLen - head < 1) return -1; buffer[head++] = JSON_ITEM_OPAQUE_END; break; case LWM2M_TYPE_OBJECT_LINK: if (bufferLen < JSON_ITEM_OBJECT_LINK_BEGIN_SIZE) return -1; memcpy(buffer, JSON_ITEM_OBJECT_LINK_BEGIN, JSON_ITEM_OBJECT_LINK_BEGIN_SIZE); head = JSON_ITEM_OBJECT_LINK_BEGIN_SIZE; res = utils_objLinkToText(tlvP->value.asObjLink.objectId, tlvP->value.asObjLink.objectInstanceId, buffer + head, bufferLen - head); if (!res) return -1; head += res; if (bufferLen - head < 1) return -1; buffer[head++] = JSON_ITEM_OBJECT_LINK_END; break; default: return -1; } return (int)head; }