coap_status_t object_read(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t * formatP, uint8_t ** bufferP, size_t * lengthP) { coap_status_t result; lwm2m_data_t * dataP = NULL; int size = 0; result = object_readData(contextP, uriP, &size, &dataP); if (result == COAP_205_CONTENT) { *lengthP = lwm2m_data_serialize(uriP, size, dataP, formatP, bufferP); if (*lengthP == 0) { if (*formatP != LWM2M_CONTENT_TEXT || size != 1 || dataP->type != LWM2M_TYPE_STRING || dataP->value.asBuffer.length != 0) { result = COAP_500_INTERNAL_SERVER_ERROR; } } } 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); }
static void test_data(const char * uriStr, lwm2m_media_type_t format, lwm2m_data_t * tlvP, int size, const char * id) { lwm2m_uri_t uri; uint8_t * buffer; int length; if (uriStr != NULL) { lwm2m_stringToUri(uriStr, strlen(uriStr), &uri); } length = lwm2m_data_serialize((uriStr != NULL) ? &uri : NULL, size, tlvP, &format, &buffer); if (length <= 0) { printf("Serialize lwm2m_data_t %s to %s failed.\n", id, format==LWM2M_CONTENT_JSON?"JSON":"TLV"); //dump_data_t(stdout, size, tlvP, 0); CU_TEST_FATAL(CU_FALSE); } else { //printf("\n\nSerialize lwm2m_data_t %s:\n", id); //output_buffer(stdout, buffer, length, 0); lwm2m_free(buffer); } }
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); }
static void test_data_and_compare(const char * uriStr, lwm2m_media_type_t format, lwm2m_data_t * tlvP, int size, const char * id, uint8_t* original_buffer, size_t original_length) { lwm2m_uri_t uri; uint8_t * buffer; int length; if (uriStr != NULL) { lwm2m_stringToUri(uriStr, strlen(uriStr), &uri); } length = lwm2m_data_serialize((uriStr != NULL) ? &uri : NULL, size, tlvP, &format, &buffer); if (length <= 0) { printf("(Serialize lwm2m_data_t %s to TLV failed.)\t", id); //dump_data_t(stdout, size, tlvP, 0); CU_TEST_FATAL(CU_FALSE); return; } if (format != LWM2M_CONTENT_JSON) { CU_ASSERT_EQUAL(original_length, length); if ((original_length != (size_t)length) || (memcmp(original_buffer, buffer, length) != 0)) { printf("Comparing buffer after parse/serialize failed for %s:\n", id); output_buffer(stdout, buffer, length, 0); printf("\ninstead of:\n"); output_buffer(stdout, original_buffer, original_length, 0); CU_TEST_FATAL(CU_FALSE); } } lwm2m_free(buffer); }
coap_status_t object_read(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t * formatP, uint8_t ** bufferP, size_t * lengthP) { coap_status_t result; lwm2m_data_t * dataP = NULL; int size = 0; result = object_readData(contextP, uriP, &size, &dataP); if (result == COAP_205_CONTENT) { *lengthP = lwm2m_data_serialize(uriP, size, dataP, formatP, bufferP); if (*lengthP == 0) result = COAP_500_INTERNAL_SERVER_ERROR; } lwm2m_data_free(size, dataP); return result; }
void observe_step(lwm2m_context_t * contextP, time_t currentTime, time_t * timeoutP) { lwm2m_observed_t * targetP; for (targetP = contextP->observedList ; targetP != NULL ; targetP = targetP->next) { lwm2m_watcher_t * watcherP; uint8_t * buffer = NULL; size_t length = 0; lwm2m_data_t * dataP = NULL; int size = 0; double floatValue = 0; int64_t integerValue = 0; bool storeValue = false; lwm2m_media_type_t format = LWM2M_CONTENT_TEXT; coap_packet_t message[1]; time_t interval; if (LWM2M_URI_IS_SET_RESOURCE(&targetP->uri)) { if (COAP_205_CONTENT != object_readData(contextP, &targetP->uri, &size, &dataP)) continue; switch (dataP->type) { case LWM2M_TYPE_INTEGER: if (1 != lwm2m_data_decode_int(dataP, &integerValue)) continue; storeValue = true; break; case LWM2M_TYPE_FLOAT: if (1 != lwm2m_data_decode_float(dataP, &floatValue)) continue; storeValue = true; break; default: break; } } for (watcherP = targetP->watcherList ; watcherP != NULL ; watcherP = watcherP->next) { if (watcherP->active == true) { bool notify = false; if (watcherP->update == true) { // value changed, should we notify the server ? if (watcherP->parameters == NULL || watcherP->parameters->toSet == 0) { // no conditions notify = true; LOG("observation_step(/%d/%d/%d) notify[1] = TRUE\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId); } if (notify == false && watcherP->parameters != NULL && (watcherP->parameters->toSet & ATTR_FLAG_NUMERIC) != 0) { if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_LESS_THAN) != 0) { // Did we cross the lower treshold ? switch (dataP->type) { case LWM2M_TYPE_INTEGER: if ((integerValue <= watcherP->parameters->lessThan && watcherP->lastValue.asInteger > watcherP->parameters->lessThan) || (integerValue >= watcherP->parameters->lessThan && watcherP->lastValue.asInteger < watcherP->parameters->lessThan)) { notify = true; } break; case LWM2M_TYPE_FLOAT: if ((floatValue <= watcherP->parameters->lessThan && watcherP->lastValue.asFloat > watcherP->parameters->lessThan) || (floatValue >= watcherP->parameters->lessThan && watcherP->lastValue.asFloat < watcherP->parameters->lessThan)) { notify = true; } break; default: break; } LOG("observation_step(/%d/%d/%d) notify[2] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE"); } if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_GREATER_THAN) != 0) { // Did we cross the upper treshold ? switch (dataP->type) { case LWM2M_TYPE_INTEGER: if ((integerValue <= watcherP->parameters->greaterThan && watcherP->lastValue.asInteger > watcherP->parameters->greaterThan) || (integerValue >= watcherP->parameters->greaterThan && watcherP->lastValue.asInteger < watcherP->parameters->greaterThan)) { notify = true; } break; case LWM2M_TYPE_FLOAT: if ((floatValue <= watcherP->parameters->greaterThan && watcherP->lastValue.asFloat > watcherP->parameters->greaterThan) || (floatValue >= watcherP->parameters->greaterThan && watcherP->lastValue.asFloat < watcherP->parameters->greaterThan)) { notify = true; } break; default: break; } LOG("observation_step(/%d/%d/%d) notify[3] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE"); } if ((watcherP->parameters->toSet & LWM2M_ATTR_FLAG_STEP) != 0) { switch (dataP->type) { case LWM2M_TYPE_INTEGER: { int64_t diff; diff = integerValue - watcherP->lastValue.asInteger; if ((diff < 0 && (0 - diff) >= watcherP->parameters->step) || (diff >= 0 && diff >= watcherP->parameters->step)) { notify = true; } } break; case LWM2M_TYPE_FLOAT: { double diff; diff = floatValue - watcherP->lastValue.asFloat; if ((diff < 0 && (0 - diff) >= watcherP->parameters->step) || (diff >= 0 && diff >= watcherP->parameters->step)) { notify = true; } } break; default: break; } LOG("observation_step(/%d/%d/%d) notify[4] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify? "TRUE" : "FALSE"); } } if (watcherP->parameters != NULL && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MIN_PERIOD) != 0) { if (watcherP->lastTime + watcherP->parameters->minPeriod > currentTime) { // Minimum Period did not elapse yet interval = watcherP->lastTime + watcherP->parameters->minPeriod - currentTime; if (*timeoutP > interval) *timeoutP = interval; notify = false; } else { notify = true; } LOG("observation_step(/%d/%d/%d) notify[5] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE"); } } // Is the Maximum Period reached ? if (notify == false && watcherP->parameters != NULL && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) != 0) { if (watcherP->lastTime + watcherP->parameters->maxPeriod <= currentTime) { notify = true; } LOG("observation_step(/%d/%d/%d) notify[6] = %s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, notify ? "TRUE" : "FALSE"); } if (notify == true) { if (buffer == NULL) { if (dataP != NULL) { length = lwm2m_data_serialize(&targetP->uri, size, dataP, &format, &buffer); if (length == 0) break; } else { if (COAP_205_CONTENT != object_read(contextP, &targetP->uri, &format, &buffer, &length)) { buffer = NULL; break; } } coap_init_message(message, COAP_TYPE_NON, COAP_205_CONTENT, 0); coap_set_header_content_type(message, format); coap_set_payload(message, buffer, length); LOG("Observe Update[/%d/%d/%d]: %.*s\n", targetP->uri.objectId, targetP->uri.instanceId, targetP->uri.resourceId, length, buffer); } watcherP->lastTime = currentTime; watcherP->lastMid = contextP->nextMID++; message->mid = watcherP->lastMid; coap_set_header_token(message, watcherP->token, watcherP->tokenLen); coap_set_header_observe(message, watcherP->counter++); (void)message_send(contextP, message, watcherP->server->sessionH); watcherP->update = false; } // Store this value if (notify == true && storeValue == true) { switch (dataP->type) { case LWM2M_TYPE_INTEGER: watcherP->lastValue.asInteger = integerValue; break; case LWM2M_TYPE_FLOAT: watcherP->lastValue.asFloat = floatValue; break; default: break; } } if (watcherP->parameters != NULL && (watcherP->parameters->toSet & LWM2M_ATTR_FLAG_MAX_PERIOD) != 0) { // update timers interval = watcherP->lastTime + watcherP->parameters->maxPeriod - currentTime; if (*timeoutP > interval) *timeoutP = interval; } } } if (dataP != NULL) lwm2m_data_free(size, dataP); if (buffer != NULL) lwm2m_free(buffer); } }
static void prv_create_client(char * buffer, void * user_data) { lwm2m_context_t * lwm2mH = (lwm2m_context_t *) user_data; uint16_t clientId; lwm2m_uri_t uri; char * end = NULL; int result; int64_t value; uint8_t * temp_buffer = NULL; int temp_length = 0; lwm2m_media_type_t format = LWM2M_CONTENT_TEXT; //Get Client ID result = prv_read_id(buffer, &clientId); if (result != 1) goto syntax_error; //Get Uri buffer = get_next_arg(buffer, &end); if (buffer[0] == 0) goto syntax_error; result = lwm2m_stringToUri(buffer, end - buffer, &uri); if (result == 0) goto syntax_error; //Get Data to Post buffer = get_next_arg(end, &end); if (buffer[0] == 0) goto syntax_error; if (!check_end_of_args(end)) goto syntax_error; // TLV /* Client dependent part */ if (uri.objectId == 1024) { lwm2m_data_t * dataP; dataP = lwm2m_data_new(1); if (dataP == NULL) { fprintf(stdout, "Allocation error !"); return; } lwm2m_data_encode_int(value, dataP); dataP->id = 1; format = LWM2M_CONTENT_TLV; temp_length = lwm2m_data_serialize(NULL, 1, dataP, &format, &temp_buffer); } /* End Client dependent part*/ //Create result = lwm2m_dm_create(lwm2mH, clientId, &uri, format, temp_buffer, temp_length, prv_result_callback, NULL); if (result == 0) { fprintf(stdout, "OK"); } else { prv_print_error(result); } return; syntax_error: fprintf(stdout, "Syntax error !"); }
static int prv_add_server(bs_info_t * infoP, read_server_t * dataP) { lwm2m_data_t * tlvP; int size; bs_server_tlv_t * serverP; lwm2m_media_type_t format; switch (dataP->securityMode) { case LWM2M_SECURITY_MODE_NONE: size = 4; break; case LWM2M_SECURITY_MODE_PRE_SHARED_KEY: size = 6; break; case LWM2M_SECURITY_MODE_RAW_PUBLIC_KEY: case LWM2M_SECURITY_MODE_CERTIFICATE: size = 7; break; default: return -1; } serverP = (bs_server_tlv_t *)lwm2m_malloc(sizeof(bs_server_tlv_t)); if (serverP == NULL) return -1; memset(serverP, 0, sizeof(bs_server_tlv_t)); serverP->id = dataP->id; tlvP = lwm2m_data_new(size); if (tlvP == NULL) goto error; // LWM2M Server URI tlvP[0].id = LWM2M_SECURITY_URI_ID; lwm2m_data_encode_string(dataP->uri, tlvP); // Bootstrap Server tlvP[1].id = LWM2M_SECURITY_BOOTSTRAP_ID; lwm2m_data_encode_bool(dataP->isBootstrap, tlvP + 1); // Short Server ID tlvP[2].id = LWM2M_SECURITY_SHORT_SERVER_ID; lwm2m_data_encode_int(dataP->id, tlvP + 2); // Security Mode tlvP[3].id = LWM2M_SECURITY_SECURITY_ID; lwm2m_data_encode_int(dataP->securityMode, tlvP + 3); if (size > 4) { tlvP[4].id = LWM2M_SECURITY_PUBLIC_KEY_ID; lwm2m_data_encode_opaque(dataP->publicKey, dataP->publicKeyLen, tlvP + 4); tlvP[5].id = LWM2M_SECURITY_SECRET_KEY_ID; lwm2m_data_encode_opaque(dataP->secretKey, dataP->secretKeyLen, tlvP + 5); if (size == 7) { tlvP[6].id = LWM2M_SECURITY_SERVER_PUBLIC_KEY_ID; lwm2m_data_encode_opaque(dataP->serverKey, dataP->serverKeyLen, tlvP + 5); } } format = LWM2M_CONTENT_TLV; serverP->securityLen = lwm2m_data_serialize(NULL, size, tlvP, &format, &(serverP->securityData)); if (serverP->securityLen <= 0) goto error; lwm2m_data_free(size, tlvP); if (dataP->isBootstrap == false) { size = 4; tlvP = lwm2m_data_new(size); if (tlvP == NULL) goto error; // Short Server ID tlvP[0].id = LWM2M_SERVER_SHORT_ID_ID; lwm2m_data_encode_int(dataP->id, tlvP); // Lifetime tlvP[1].id = LWM2M_SERVER_LIFETIME_ID; lwm2m_data_encode_int(dataP->lifetime, tlvP + 1); // Notification Storing tlvP[2].id = LWM2M_SERVER_STORING_ID; lwm2m_data_encode_bool(false, tlvP + 2); // Binding tlvP[3].id = LWM2M_SERVER_BINDING_ID; lwm2m_data_encode_string("U", tlvP + 3); serverP->serverLen = lwm2m_data_serialize(NULL, size, tlvP, &format, &(serverP->serverData)); if (serverP->serverLen <= 0) goto error; lwm2m_data_free(size, tlvP); } infoP->serverList = (bs_server_tlv_t *)LWM2M_LIST_ADD(infoP->serverList, serverP); return 0; error: if (tlvP != NULL) lwm2m_data_free(size, tlvP); if (serverP->securityData != NULL) lwm2m_free(serverP->securityData); if (serverP->serverData != NULL) lwm2m_free(serverP->serverData); lwm2m_free(serverP); return -1; }
uint8_t dm_handleRequest(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, server status: %s", message->code, STR_STATUS(serverP->status)); LOG_URI(uriP); if (IS_OPTION(message, COAP_OPTION_CONTENT_TYPE)) { format = utils_convertMediaType(message->content_type); } else { format = LWM2M_CONTENT_TLV; } if (uriP->objectId == LWM2M_SECURITY_OBJECT_ID) { return COAP_404_NOT_FOUND; } if (serverP->status != STATE_REGISTERED && serverP->status != STATE_REG_UPDATE_NEEDED && serverP->status != STATE_REG_FULL_UPDATE_NEEDED && serverP->status != STATE_REG_UPDATE_PENDING) { return COAP_IGNORE; } // TODO: check ACL switch (message->code) { case COAP_GET: { uint8_t * buffer = NULL; size_t length = 0; int res; if (IS_OPTION(message, COAP_OPTION_OBSERVE)) { lwm2m_data_t * dataP = NULL; int size = 0; result = object_readData(contextP, uriP, &size, &dataP); if (COAP_205_CONTENT == result) { result = observe_handleRequest(contextP, uriP, serverP, size, dataP, message, response); if (COAP_205_CONTENT == result) { if (IS_OPTION(message, COAP_OPTION_ACCEPT)) { format = utils_convertMediaType(message->accept[0]); } else { format = LWM2M_CONTENT_TLV; } res = lwm2m_data_serialize(uriP, size, dataP, &format, &buffer); if (res < 0) { result = COAP_500_INTERNAL_SERVER_ERROR; } else { length = (size_t)res; LOG_ARG("Observe Request[/%d/%d/%d]: %.*s\n", uriP->objectId, uriP->instanceId, uriP->resourceId, length, buffer); } } lwm2m_data_free(size, dataP); } } else if (IS_OPTION(message, COAP_OPTION_ACCEPT) && message->accept_num == 1 && message->accept[0] == APPLICATION_LINK_FORMAT) { format = LWM2M_CONTENT_LINK; result = object_discover(contextP, uriP, serverP, &buffer, &length); } else { if (IS_OPTION(message, COAP_OPTION_ACCEPT)) { format = utils_convertMediaType(message->accept[0]); } result = object_read(contextP, uriP, &format, &buffer, &length); } if (COAP_205_CONTENT == result) { coap_set_header_content_type(response, format); coap_set_payload(response, buffer, length); // lwm2m_handle_packet will free buffer } else { lwm2m_free(buffer); } } break; case COAP_POST: { if (!LWM2M_URI_IS_SET_INSTANCE(uriP)) { result = object_create(contextP, uriP, format, message->payload, message->payload_len); if (result == COAP_201_CREATED) { //longest uri is /65535/65535 = 12 + 1 (null) chars char location_path[13] = ""; //instanceId expected if ((uriP->flag & LWM2M_URI_FLAG_INSTANCE_ID) == 0) { result = COAP_500_INTERNAL_SERVER_ERROR; break; } if (sprintf(location_path, "/%d/%d", uriP->objectId, uriP->instanceId) < 0) { result = COAP_500_INTERNAL_SERVER_ERROR; break; } coap_set_header_location_path(response, location_path); lwm2m_update_registration(contextP, 0, true); } } else if (!LWM2M_URI_IS_SET_RESOURCE(uriP)) { result = object_write(contextP, uriP, format, message->payload, message->payload_len); } else { result = object_execute(contextP, uriP, message->payload, message->payload_len); } } break; case COAP_PUT: { if (IS_OPTION(message, COAP_OPTION_URI_QUERY)) { lwm2m_attributes_t attr; if (0 != prv_readAttributes(message->uri_query, &attr)) { result = COAP_400_BAD_REQUEST; } else { result = observe_setParameters(contextP, uriP, serverP, &attr); } } else if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { result = object_write(contextP, uriP, format, message->payload, message->payload_len); } else { result = COAP_400_BAD_REQUEST; } } break; case COAP_DELETE: { if (!LWM2M_URI_IS_SET_INSTANCE(uriP) || LWM2M_URI_IS_SET_RESOURCE(uriP)) { result = COAP_400_BAD_REQUEST; } else { result = object_delete(contextP, uriP); if (result == COAP_202_DELETED) { lwm2m_update_registration(contextP, 0, true); } } } break; default: result = COAP_400_BAD_REQUEST; break; } return result; }
coap_status_t ICACHE_FLASH_ATTR object_read(lwm2m_context_t * contextP, lwm2m_uri_t * uriP, lwm2m_media_type_t * formatP, uint8_t ** bufferP, size_t * lengthP) { coap_status_t result; lwm2m_object_t * targetP; lwm2m_data_t * dataP = NULL; int size = 0; #ifdef ICACHE_FLASH_ATTR if (contextP->bsState == BOOTSTRAP_PENDING) return METHOD_NOT_ALLOWED_4_05; #endif targetP = prv_find_object(contextP, uriP->objectId); if (NULL == targetP) return NOT_FOUND_4_04; if (NULL == targetP->readFunc) return METHOD_NOT_ALLOWED_4_05; if (targetP->instanceList == NULL) { // this is a single instance object if (LWM2M_URI_IS_SET_INSTANCE(uriP) && (uriP->instanceId != 0)) { return COAP_404_NOT_FOUND; } } else { if (LWM2M_URI_IS_SET_INSTANCE(uriP)) { if (NULL == lwm2m_list_find(targetP->instanceList, uriP->instanceId)) { return COAP_404_NOT_FOUND; } } else { // multiple object instances read lwm2m_list_t * instanceP; int i; size = 0; for (instanceP = targetP->instanceList; instanceP != NULL ; instanceP = instanceP->next) { size++; } dataP = lwm2m_data_new(size); if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; result = COAP_205_CONTENT; instanceP = targetP->instanceList; i = 0; while (instanceP != NULL && result == COAP_205_CONTENT) { result = targetP->readFunc(instanceP->id, (int*)&(dataP[i].length), (lwm2m_data_t **)&(dataP[i].value), targetP); dataP[i].type = LWM2M_TYPE_OBJECT_INSTANCE; dataP[i].id = instanceP->id; i++; instanceP = instanceP->next; } if (result == COAP_205_CONTENT) { *lengthP = lwm2m_data_serialize(size, dataP, formatP, bufferP); if (*lengthP == 0) result = COAP_500_INTERNAL_SERVER_ERROR; } lwm2m_data_free(size, dataP); return result; } } // single instance read if (LWM2M_URI_IS_SET_RESOURCE(uriP)) { size = 1; dataP = lwm2m_data_new(size); if (dataP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; dataP->type = LWM2M_TYPE_RESOURCE; dataP->flags = LWM2M_TLV_FLAG_TEXT_FORMAT; dataP->id = uriP->resourceId; } result = targetP->readFunc(uriP->instanceId, &size, &dataP, targetP); if (result == COAP_205_CONTENT) { if (size == 1 && dataP->type == LWM2M_TYPE_RESOURCE && (dataP->flags && LWM2M_TLV_FLAG_TEXT_FORMAT) != 0 ) { *bufferP = (uint8_t *)c_zalloc(dataP->length); if (*bufferP == NULL) { result = COAP_500_INTERNAL_SERVER_ERROR; } else { c_memcpy(*bufferP, dataP->value, dataP->length); *lengthP = dataP->length; } } else { *lengthP = lwm2m_data_serialize(size, dataP, formatP, bufferP); if (*lengthP == 0) result = COAP_500_INTERNAL_SERVER_ERROR; } } lwm2m_data_free(size, dataP); return result; }
static void test_data_and_compare(const char * uriStr, lwm2m_media_type_t format, lwm2m_data_t * tlvP, int size, const char * id, const uint8_t* original_buffer, size_t original_length) { lwm2m_uri_t uri; uint8_t * buffer; size_t length; if (uriStr != NULL) { lwm2m_stringToUri(uriStr, strlen(uriStr), &uri); } length = lwm2m_data_serialize((uriStr != NULL) ? &uri : NULL, size, tlvP, &format, &buffer); if (length <= 0) { printf("Serialize lwm2m_data_t %s to TLV failed.\n", id); //dump_data_t(stdout, size, tlvP, 0); CU_TEST_FATAL(CU_FALSE); return; } char* original_compact; if (format == LWM2M_CONTENT_JSON) { // Remove white spaces from original_buffer if not in a "" context // so that the original input string can be compared to the serialized data output, // which does not contain additional white spaces. original_compact= malloc(original_length); char* s = (char*)original_buffer; char* d = original_compact; uint8_t in_string_context = 0; do { *d = *s; // Toggle "in_string_context" flag if " has been detected and if " is not escaped if (*d == '"' && *(d-1) != '\\') in_string_context = !in_string_context; if(in_string_context || !isspace(*d)) d++; } while(*s++ != 0); original_length = strlen(original_compact); } else { // No JSON format? Just use the original buffer original_compact = (char*)original_buffer; } CU_ASSERT_EQUAL(original_length, length); if ((original_length != length) || (memcmp(original_compact, buffer, length) != 0)) { printf("Comparing buffer after parse/serialize failed for %s:\n", id); output_buffer(stdout, buffer, length, 0); printf("\ninstead of:\n"); output_buffer(stdout, (uint8_t*)original_compact, original_length, 0); CU_TEST_FATAL(CU_FALSE); } // Free the compact representation of the original buffer if (original_compact != (char*)original_buffer) free(original_compact); lwm2m_free(buffer); }