void dump_test_results(const test_data_s *test_data) { printf("\tURL: %s\n",test_data->url); if(test_data->inbound_code) printf("\tinbound_code: %s (%d)\n", coap_code_to_cstr(test_data->inbound_code), COAP_TO_HTTP_CODE(test_data->inbound_code)); if(test_data->error || test_data->failed) { if(test_data->error) printf("\terror: %s (%d)\n", smcp_status_to_cstr(test_data->error), test_data->error); } { smcp_cms_t duration = smcp_plat_timestamp_diff(test_data->stop_time,test_data->start_time); printf("\tduration: %dms\n", (int)duration); } if(test_data->has_block1_option) { struct coap_block_info_s block_info; coap_decode_block(&block_info, test_data->block1_option); printf("\tblock1: %d/%d/%d\n", block_info.block_offset,block_info.block_m,block_info.block_size); } if(test_data->has_block2_option) { struct coap_block_info_s block_info; coap_decode_block(&block_info, test_data->block2_option); printf("\tblock2: %d/%d/%d\n", block_info.block_offset,block_info.block_m,block_info.block_size); } printf("\tlast_msg_id: 0x%04X\n", (int)test_data->msg_id); printf("\tinbound_content_len: %d\n", (int)test_data->inbound_content_len); if(test_data->inbound_packets!=1) { printf("\tinbound_packets: %d\n", test_data->inbound_packets); } if(test_data->inbound_dupe_packets!=0) { printf("\tinbound_dupes: %d\n", test_data->inbound_dupe_packets); } if(test_data->outbound_attempts!=1) { printf("\toutbound_attempts: %d\n", test_data->outbound_attempts); } if(test_data->response[0]!=0) { printf("\tresponse: \"%s\"\n", test_data->response); } }
smcp_status_t resend_test_request(void* context) { test_data_s* test_data = context; smcp_status_t status = 0; status = smcp_outbound_begin(smcp_get_current_instance(),test_data->outbound_code, test_data->outbound_tt); require_noerr(status,bail); status = smcp_outbound_set_uri(test_data->url, 0); require_noerr(status,bail); if (test_data->outbound_content_type != COAP_CONTENT_TYPE_UNKNOWN) { status = smcp_outbound_add_option_uint(COAP_OPTION_CONTENT_TYPE, test_data->outbound_content_type); require_noerr(status,bail); } if (test_data->extra & EXT_BLOCK_01) { struct coap_block_info_s block1_info; uint32_t resource_length = 200; uint32_t block_stop; coap_decode_block(&block1_info, test_data->block1_option + (1<<4)); block_stop = block1_info.block_offset+block1_info.block_size; if (block1_info.block_offset < resource_length) { if (block_stop >= resource_length) { test_data->block1_option &= ~(1<<3); } else { test_data->block1_option |= (1<<3); } if (test_data->has_block1_option) { test_data->block1_option += (1<<4); } smcp_outbound_add_option_uint(COAP_OPTION_BLOCK1, test_data->block1_option); if (block1_info.block_m) { coap_size_t max_len = 0; uint32_t i; uint32_t block_stop; char* content = NULL; content = smcp_outbound_get_content_ptr(&max_len); if (!content) { status = SMCP_STATUS_FAILURE; goto bail; } block_stop = block1_info.block_offset+block1_info.block_size; for (i = block1_info.block_offset; i < block_stop; i++) { if (!((i + 1) % 64)) { content[i-block1_info.block_offset] = '\n'; } else { content[i-block1_info.block_offset] = '0'+(i%10); } } status = smcp_outbound_set_content_len(MIN((coap_code_t)(block_stop-block1_info.block_offset),(coap_code_t)(resource_length-block1_info.block_offset))); require_noerr(status,bail); } } } if(test_data->extra & EXT_BLOCK_02) { smcp_outbound_add_option_uint(COAP_OPTION_BLOCK2, 1); // 32 byte block size. } status = smcp_outbound_send(); if(status) { check_noerr(status); fprintf(stderr, "smcp_outbound_send() returned error %d(%s).\n", status, smcp_status_to_cstr(status)); goto bail; } else { test_data->outbound_attempts++; } bail: return status; }
smcp_status_t plugtest_large_handler( smcp_node_t node ) { smcp_status_t ret = SMCP_STATUS_NOT_ALLOWED; char* content = NULL; coap_size_t max_len = 0; smcp_method_t method = smcp_inbound_get_code(); uint32_t block_option = 0x03; uint32_t block_start = 0; uint32_t block_stop = 0; uint32_t resource_length = 2000; if(method==COAP_METHOD_GET) { ret = 0; } require_noerr(ret,bail); { const uint8_t* value; coap_size_t value_len; coap_option_key_t key; while((key=smcp_inbound_next_option(&value, &value_len))!=COAP_OPTION_INVALID) { if(key == COAP_OPTION_BLOCK2) { uint8_t i; block_option = 0; for(i = 0; i < value_len; i++) block_option = (block_option << 8) + value[i]; } } } ret = smcp_outbound_begin_response(COAP_RESULT_205_CONTENT); require_noerr(ret,bail); ret = smcp_outbound_add_option_uint(COAP_OPTION_CONTENT_TYPE, COAP_CONTENT_TYPE_TEXT_PLAIN); require_noerr(ret,bail); ret = smcp_outbound_add_option_uint(COAP_OPTION_MAX_AGE,60*60); require_noerr(ret,bail); max_len = smcp_outbound_get_space_remaining()-2; // Here we are making sure our data will fit, // and adjusting our block-option size accordingly. do { struct coap_block_info_s block_info; coap_decode_block(&block_info, block_option); block_start = block_info.block_offset; block_stop = block_info.block_offset + block_info.block_size; if(max_len<(block_stop-block_start) && block_option!=0 && !block_info.block_offset) { block_option--; block_stop = 0; continue; } } while(0==block_stop); require_action(block_start<resource_length,bail,ret=SMCP_STATUS_INVALID_ARGUMENT); if(block_stop>=resource_length) block_option &= ~(1<<3); else block_option |= (1<<3); ret = smcp_outbound_add_option_uint(COAP_OPTION_BLOCK2,block_option); require_noerr(ret,bail); content = smcp_outbound_get_content_ptr(&max_len); require_action(NULL!=content, bail, ret = SMCP_STATUS_FAILURE); require_action(max_len>(block_stop-block_start), bail, ret = SMCP_STATUS_MESSAGE_TOO_BIG); { uint32_t i; for(i=block_start;i<block_stop;i++) { if(!((i+1)%64)) content[i-block_start] = '\n'; else content[i-block_start] = '0'+(i%10); } } ret = smcp_outbound_set_content_len((coap_size_t)MIN(block_stop-block_start,resource_length-block_start)); if(ret) goto bail; ret = smcp_outbound_send(); bail: return ret; }