bool unabto_buffer_test(void) { char * raw_test_string = "asjdhc#21?(!?(92814skzjbcasa"; uint8_t data[7 + 2 + strlen(raw_test_string)]; unabto_buffer buf, raw_string_buf; buffer_write_t w_buf; buffer_read_t r_buf; uint32_t t32; uint16_t t16; uint8_t t8; uint8_t raw_string_data[strlen(raw_test_string) + 1]; buffer_init(&raw_string_buf, (uint8_t*)raw_test_string, strlen(raw_test_string)); buffer_init(&buf, data, sizeof(data)); buffer_write_init(&w_buf, &buf); if (! (buffer_write_uint32(&w_buf, 0x12345678) && buffer_write_uint16(&w_buf, 0x1234) && buffer_write_uint8(&w_buf, 0x12) && buffer_write_raw(&w_buf, &raw_string_buf) ) ) { NABTO_LOG_ERROR(("Buffer write test failed")); return false; } buffer_read_init(&r_buf, &buf); memset(raw_string_data, 0, sizeof(raw_string_data) + 1); buffer_init(&raw_string_buf, raw_string_data, sizeof(raw_string_data)); bool t = false; if (! ( buffer_read_uint32(&r_buf, &t32) && t32 == 0x12345678 && buffer_read_uint16(&r_buf, &t16) && t16 == 0x1234 && buffer_read_uint8(&r_buf, &t8) && t8 == 0x12 && (t = buffer_read_raw(&r_buf, &raw_string_buf)) && buffer_get_size(&raw_string_buf) == strlen(raw_test_string) && 0 == strncmp((char*)buffer_get_data(&raw_string_buf), raw_test_string, strlen(raw_test_string)) )) { NABTO_LOG_ERROR(("Failed read test failed")); return false; } if (buffer_read_uint32(&r_buf, &t32) || buffer_read_uint16(&r_buf, &t16) || buffer_read_uint8(&r_buf, &t8) || buffer_read_raw(&w_buf, &raw_string_buf) || buffer_write_uint32(&w_buf, 0x12345678) || buffer_write_uint16(&w_buf, 0x1234) || buffer_write_uint8(&w_buf, 0x12) || buffer_write_raw(&w_buf, &raw_string_buf) ) { NABTO_LOG_ERROR(("Some function should have returned false but returned true")); return false; } return true; }
application_event_result application_event(application_request* request, buffer_read_t* r_b, buffer_write_t* w_b) { // As an example - and for testing: // This implementation replies immediately to every second request whereas // the rest is saved to be answered on one of the next polls from unabto. // However, before saving a request, if another request is already saved (thus in progress), // the response will be a AER_REQ_OUT_OF_RESOURCES // static int test_xxx = 0; int test_respond_now = ((++test_xxx) & 1); if (request->isLocal || test_respond_now) { PGR_LOG_APPREQ(application_event, "Respond immedeately"); return weather_station_application(request, r_b, w_b); } else if (saved_app_req) { PGR_LOG_APPREQ(application_event, "No ressources"); return AER_REQ_OUT_OF_RESOURCES; } else { PGR_LOG_APPREQ(application_event, "Accept request"); saved_app_req = request; // IMPORTANT: w_b cannot be used when saving the request for later completion! // the buffer designated by w_b may be overridden by the caller. { size_t sz = buffer_read_available(r_b); if (sz > sizeof(saved_params.data)) { return AER_REQ_TOO_LARGE; } else { // saves raw bytes from buffer (including already read data) into same type of data-holder, // because weather_station_application() neads a buffer_read_t* parameter // more realistic example would read/interpret parameters and copy to own structure. memcpy(saved_params.data, r_b->buffer->data, sz); buffer_init(&saved_params.buf, saved_params.data, (int)sz); buffer_read_init(&saved_params.r_b, &saved_params.buf, sz); saved_params.r_b.position = r_b->position; // skip already read data } } return AER_REQ_ACCEPTED; } }