static void test_raw_expected(const char * uriStr, const char * testBuf, size_t testLen, const char * expectBuf, size_t expectLen, lwm2m_media_type_t format, const char * id) { lwm2m_data_t * tlvP; lwm2m_uri_t uri; int size; if (uriStr != NULL) { lwm2m_stringToUri(uriStr, strlen(uriStr), &uri); } size = lwm2m_data_parse((uriStr != NULL) ? &uri : NULL, (uint8_t *)testBuf, testLen, format, &tlvP); CU_ASSERT_TRUE_FATAL(size>0); // Serialize to the same format and compare to the input buffer test_data_and_compare(uriStr, format, tlvP, size, id, (uint8_t*)expectBuf, expectLen); // Serialize to the other format respectivly. if (format == LWM2M_CONTENT_TLV) test_data(uriStr, LWM2M_CONTENT_JSON, tlvP, size, id); else if (format == LWM2M_CONTENT_JSON) test_data(uriStr, LWM2M_CONTENT_TLV, tlvP, size, id); }
coap_status_t object_write(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, size_t length) { coap_status_t result = NO_ERROR; lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) { result = COAP_404_NOT_FOUND; } else if (NULL == targetP->writeFunc) { result = COAP_405_METHOD_NOT_ALLOWED; } else { size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); if (size == 0) { result = COAP_406_NOT_ACCEPTABLE; } } if (result == NO_ERROR) { result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP); lwm2m_data_free(size, dataP); } return result; }
static void test_JSON(char * testBuf, size_t testLen, char * id) { lwm2m_data_t * tlvP; int size; int length; uint8_t * buffer; lwm2m_media_type_t format = LWM2M_CONTENT_JSON; size = lwm2m_data_parse((uint8_t *)testBuf, testLen, format, &tlvP); if (size <= 0) { printf("\n\nJSON buffer %s decoding failed !\n", id); return; } else printf("\n\nJSON buffer %s decoding:\n", id); dump_tlv(stdout, size, tlvP, 0); length = lwm2m_data_serialize(size, tlvP, &format, &buffer); dump_json(buffer, length); lwm2m_data_free(size, tlvP); lwm2m_free(buffer); }
/** * @brief Parses the testBuf to an array of lwm2m_data_t objects and serializes the result * to TLV and JSON and if applicable compares it to the original testBuf. * @param testBuf The input buffer. * @param testLen The length of the input buffer. * @param format The format of the testBuf. Maybe LWM2M_CONTENT_TLV or LWM2M_CONTENT_JSON at the moment. * @param id The test object id for debug out. */ static void test_raw(const char * uriStr, const char * testBuf, size_t testLen, lwm2m_media_type_t format, const char * id) { lwm2m_data_t * tlvP; lwm2m_uri_t uri; int size; if (uriStr != NULL) { lwm2m_stringToUri(uriStr, strlen(uriStr), &uri); } size = lwm2m_data_parse((uriStr != NULL) ? &uri : NULL, (uint8_t *)testBuf, testLen, format, &tlvP); CU_ASSERT_TRUE_FATAL(size>0); // Serialize to the same format and compare to the input buffer test_data_and_compare(uriStr, format, tlvP, size, id, (uint8_t*)testBuf, testLen); // Serialize to the TLV format // the reverse is not possible as TLV format loses the data type information if (format == LWM2M_CONTENT_JSON) { test_data(uriStr, LWM2M_CONTENT_TLV, tlvP, size, id); } }
coap_status_t object_create(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, size_t length) { lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; uint8_t result; if (length == 0 || buffer == 0) { return COAP_400_BAD_REQUEST; } targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (NULL == targetP->createFunc) return COAP_405_METHOD_NOT_ALLOWED; size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); if (size <= 0) return COAP_400_BAD_REQUEST; switch (dataP[0].type) { case LWM2M_TYPE_OBJECT: result = COAP_400_BAD_REQUEST; goto exit; case LWM2M_TYPE_OBJECT_INSTANCE: if (size != 1) { result = COAP_400_BAD_REQUEST; goto exit; } if (NULL != lwm2m_list_find(targetP->instanceList, dataP[0].id)) { // Instance already exists result = COAP_406_NOT_ACCEPTABLE; goto exit; } result = targetP->createFunc(dataP[0].id, dataP[0].value.asChildren.count, dataP[0].value.asChildren.array, targetP); uriP->instanceId = dataP[0].id; uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; break; default: uriP->instanceId = lwm2m_list_newId(targetP->instanceList); uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; result = targetP->createFunc(uriP->instanceId, size, dataP, targetP); break; } exit: lwm2m_data_free(size, dataP); return result; }
coap_status_t object_write(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, size_t length) { coap_status_t result = NO_ERROR; lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; targetP = prv_find_object(contextP, uriP->objectId); if (NULL == targetP) { result = NOT_FOUND_4_04; } else if (NULL == targetP->writeFunc) { result = METHOD_NOT_ALLOWED_4_05; } else { if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { size = 1; dataP = lwm2m_data_new(size); if (dataP == NULL) { return COAP_500_INTERNAL_SERVER_ERROR; } dataP->flags = LWM2M_TLV_FLAG_TEXT_FORMAT | LWM2M_TLV_FLAG_STATIC_DATA; dataP->type = LWM2M_TYPE_RESOURCE; dataP->id = uriP->resourceId; dataP->length = length; dataP->value = (uint8_t *)buffer; } else { size = lwm2m_data_parse(buffer, length, format, &dataP); if (size == 0) { result = COAP_500_INTERNAL_SERVER_ERROR; } } } if (result == NO_ERROR) { result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP); lwm2m_data_free(size, dataP); } return result; }
static void test_1(void) { const char buffer[] = {0x03, 0x0A, 0xC1, 0x01, 0x14, 0x03, 0x0B, 0xC1, 0x01, 0x15, 0x03, 0x0C, 0xC1, 0x01, 0x16}; int testLen = sizeof(buffer); lwm2m_media_type_t format = LWM2M_CONTENT_TLV; lwm2m_data_t * tlvP; int size = lwm2m_data_parse(NULL, (uint8_t *)buffer, testLen, format, &tlvP); CU_ASSERT_TRUE_FATAL(size>0); // Serialize to the same format and compare to the input buffer test_data_and_compare(NULL, format, tlvP, size, "1", (uint8_t*)buffer, testLen); }
coap_status_t ICACHE_FLASH_ATTR object_create(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, size_t length) { lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; uint8_t result; if (length == 0 || buffer == 0) { return BAD_REQUEST_4_00; } targetP = prv_find_object(contextP, uriP->objectId); if (NULL == targetP) return NOT_FOUND_4_04; if (NULL == targetP->createFunc) return METHOD_NOT_ALLOWED_4_05; if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { if (NULL != lwm2m_list_find(targetP->instanceList, uriP->instanceId)) { // Instance already exists return COAP_406_NOT_ACCEPTABLE; } } else { uriP->instanceId = lwm2m_list_newId(targetP->instanceList); uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; } size = lwm2m_data_parse(buffer, length, format, &dataP); if (size == 0) return COAP_500_INTERNAL_SERVER_ERROR; #ifdef ICACHE_FLASH_ATTR if (contextP->bsState == BOOTSTRAP_PENDING) { dataP->flags |= LWM2M_TLV_FLAG_BOOTSTRAPPING; } #endif result = targetP->createFunc(uriP->instanceId, size, dataP, targetP); lwm2m_data_free(size, dataP); return result; }
static void test_TLV(char * testBuf, size_t testLen, char * id) { lwm2m_data_t * tlvP; int size; int length; uint8_t * buffer; lwm2m_media_type_t format = LWM2M_CONTENT_TLV; printf("Buffer %s:\n", id); decode(testBuf, testLen, 0); printf("\n\nBuffer %s using lwm2m_data_t:\n", id); size = lwm2m_data_parse((uint8_t *)testBuf, testLen, format, &tlvP); dump_tlv(stdout, size, tlvP, 0); length = lwm2m_data_serialize(size, tlvP, &format, &buffer); if (length != testLen) { printf("\n\nSerialize Buffer %s to TLV failed: %d bytes instead of %d\n", id, length, testLen); } else if (memcmp(buffer, testBuf, length) != 0) { printf("\n\nSerialize Buffer %s to TLV failed:\n", id); output_buffer(stdout, buffer, length, 0); printf("\ninstead of:\n"); output_buffer(stdout, testBuf, length, 0); } else { printf("\n\nSerialize Buffer %s to TLV OK\n", id); } lwm2m_free(buffer); format = LWM2M_CONTENT_JSON; length = lwm2m_data_serialize(size, tlvP, &format, &buffer); if (length <= 0) { printf("\n\nSerialize Buffer %s to JSON failed.\n", id); } else { dump_json(buffer, length); lwm2m_free(buffer); } lwm2m_data_free(size, tlvP); }
coap_status_t object_create(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, size_t length) { lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; uint8_t result; if (length == 0 || buffer == 0) { return COAP_400_BAD_REQUEST; } targetP = (lwm2m_object_t *)LWM2M_LIST_FIND(contextP->objectList, uriP->objectId); if (NULL == targetP) return COAP_404_NOT_FOUND; if (NULL == targetP->createFunc) return COAP_405_METHOD_NOT_ALLOWED; if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { if (NULL != lwm2m_list_find(targetP->instanceList, uriP->instanceId)) { // Instance already exists return COAP_406_NOT_ACCEPTABLE; } } else { uriP->instanceId = lwm2m_list_newId(targetP->instanceList); uriP->flag |= LWM2M_URI_FLAG_INSTANCE_ID; } size = lwm2m_data_parse(uriP, buffer, length, format, &dataP); if (size == 0) return COAP_500_INTERNAL_SERVER_ERROR; result = targetP->createFunc(uriP->instanceId, size, dataP, targetP); lwm2m_data_free(size, dataP); return result; }
uint8_t bootstrap_handleCommand(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_server_t * serverP, coap_packet_t * message, coap_packet_t * response) { uint8_t result; lwm2m_media_type_t format; LOG_ARG("Code: %02X", message->code); LOG_URI(uriP); format = utils_convertMediaType(message->content_type); result = prv_checkServerStatus(serverP); if (result != COAP_NO_ERROR) return result; switch (message->code) { case COAP_PUT: { if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { if (object_isInstanceNew(contextP, uriP->objectId, uriP->instanceId)) { result = object_create(contextP, uriP, format, message->payload, message->payload_len); if (COAP_201_CREATED == result) { result = COAP_204_CHANGED; } } else { result = object_write(contextP, uriP, format, message->payload, message->payload_len); if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID && result == COAP_204_CHANGED) { prv_tagServer(contextP, uriP->instanceId); } } } else { lwm2m_data_t * dataP = NULL; int size = 0; int i; if (message->payload_len == 0 || message->payload == 0) { result = COAP_400_BAD_REQUEST; } else { size = lwm2m_data_parse(uriP, message->payload, message->payload_len, format, &dataP); if (size == 0) { result = COAP_500_INTERNAL_SERVER_ERROR; break; } for (i = 0 ; i < size ; i++) { if(dataP[i].type == LWM2M_TYPE_OBJECT_INSTANCE) { if (object_isInstanceNew(contextP, uriP->objectId, dataP[i].id)) { result = object_createInstance(contextP, uriP, &dataP[i]); if (COAP_201_CREATED == result) { result = COAP_204_CHANGED; } } else { result = object_writeInstance(contextP, uriP, &dataP[i]); if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID && result == COAP_204_CHANGED) { prv_tagServer(contextP, dataP[i].id); } } if(result != COAP_204_CHANGED) // Stop object create or write when result is error { break; } } else { result = COAP_400_BAD_REQUEST; } } lwm2m_data_free(size, dataP); } } } break; case COAP_DELETE: { if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { result = COAP_400_BAD_REQUEST; } else { result = object_delete(contextP, uriP); if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID && result == COAP_202_DELETED) { if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { prv_tagServer(contextP, uriP->instanceId); } else { prv_tagAllServer(contextP, NULL); } } } } break; case COAP_GET: case COAP_POST: default: result = COAP_400_BAD_REQUEST; break; } if (result == COAP_202_DELETED || result == COAP_204_CHANGED) { if (serverP->status != STATE_BS_PENDING) { serverP->status = STATE_BS_PENDING; contextP->state = STATE_BOOTSTRAPPING; } } LOG_ARG("Server status: %s", STR_STATUS(serverP->status)); return result; }
coap_status_t ICACHE_FLASH_ATTR object_write(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t format, uint8_t * buffer, size_t length) { coap_status_t result = NO_ERROR; lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; targetP = prv_find_object(contextP, uriP->objectId); if (NULL == targetP) { result = NOT_FOUND_4_04; } else if (NULL == targetP->writeFunc) { result = METHOD_NOT_ALLOWED_4_05; } else { if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { size = 1; dataP = lwm2m_data_new(size); if (dataP == NULL) { return COAP_500_INTERNAL_SERVER_ERROR; } dataP->flags = LWM2M_TLV_FLAG_TEXT_FORMAT | LWM2M_TLV_FLAG_STATIC_DATA; dataP->type = LWM2M_TYPE_RESOURCE; dataP->id = uriP->resourceId; dataP->length = length; dataP->value = (uint8_t *)buffer; } else { size = lwm2m_data_parse(buffer, length, format, &dataP); if (size == 0) { result = COAP_500_INTERNAL_SERVER_ERROR; } } } if (result == NO_ERROR) { #ifdef ICACHE_FLASH_ATTR if (contextP->bsState == BOOTSTRAP_PENDING) { dataP->flags |= LWM2M_TLV_FLAG_BOOTSTRAPPING; } #endif result = targetP->writeFunc(uriP->instanceId, size, dataP, targetP); lwm2m_data_free(size, dataP); } #ifdef ICACHE_FLASH_ATTR if (contextP->bsState == BOOTSTRAP_PENDING) { if (result == COAP_204_CHANGED) { reset_bootstrap_timer(contextP); } else { bootstrap_failed(contextP); } } #endif return result; }