smcp_status_t plugtest_separate_handler( smcp_node_t node ) { struct smcp_async_response_s* async_response = NULL; smcp_transaction_t transaction = NULL; smcp_status_t ret = SMCP_STATUS_NOT_ALLOWED; smcp_method_t method = smcp_inbound_get_code(); if(method==COAP_METHOD_GET) { if(smcp_inbound_is_dupe()) { smcp_outbound_begin_response(COAP_CODE_EMPTY); smcp_outbound_send(); ret = SMCP_STATUS_OK; goto bail; } async_response = calloc(sizeof(struct smcp_async_response_s),1); if(!async_response) { ret = SMCP_STATUS_MALLOC_FAILURE; goto bail; } #if !SMCP_AVOID_PRINTF || VERBOSE_DEBUG printf("This request needs an async response. %p\n",async_response); #endif transaction = smcp_transaction_init( NULL, SMCP_TRANSACTION_DELAY_START|SMCP_TRANSACTION_ALWAYS_INVALIDATE, &plugtest_separate_async_resend_response, &plugtest_separate_async_ack_handler, (void*)async_response ); if(!transaction) { free(async_response); // TODO: Consider dropping instead...? ret = SMCP_STATUS_MALLOC_FAILURE; goto bail; } ret = smcp_transaction_begin( smcp_get_current_instance(), transaction, (smcp_inbound_get_packet()->tt==COAP_TRANS_TYPE_CONFIRMABLE)?(smcp_cms_t)(COAP_MAX_TRANSMIT_WAIT*MSEC_PER_SEC):1 ); if(SMCP_STATUS_OK != ret) { smcp_transaction_end(smcp_get_current_instance(),transaction); goto bail; } ret = smcp_start_async_response(async_response,0); if(ret) { goto bail; } async_response = NULL; } bail: return ret; }
smcp_status_t smcp_observable_trigger(smcp_observable_t context, uint8_t key, uint8_t flags) { smcp_status_t ret = SMCP_STATUS_OK; int8_t i; #if SMCP_EMBEDDED smcp_t const interface = smcp_get_current_instance(); #else smcp_t const interface = context->interface; if(!interface) goto bail; #endif if(!context->first_observer) goto bail; for(i = context->first_observer-1; i >= 0; i = observer_table[i].next - 1) { if( (observer_table[i].key != SMCP_OBSERVABLE_BROADCAST_KEY) && (key != SMCP_OBSERVABLE_BROADCAST_KEY) && (observer_table[i].key != key) ) { continue; } observer_table[i].seq++; if(observer_table[i].transaction.active) { smcp_transaction_tickle(interface, &observer_table[i].transaction); } else { smcp_transaction_init( &observer_table[i].transaction, 0, // Flags (void*)&retry_sending_event, (void*)&event_response_handler, (void*)&observer_table[i] ); ret = smcp_transaction_begin( interface, &observer_table[i].transaction, SHOULD_CONFIRM_EVENT_FOR_OBSERVER(&observer_table[i])?SMCP_OBSERVER_CON_EVENT_EXPIRATION:SMCP_OBSERVER_NON_EVENT_EXPIRATION ); } } bail: return ret; }
static smcp_transaction_t send_delete_request( smcp_t smcp, const char* url ) { smcp_transaction_t ret; gRet = ERRORCODE_INPROGRESS; ret = smcp_transaction_init( NULL, SMCP_TRANSACTION_ALWAYS_INVALIDATE, // Flags (void*)&resend_delete_request, &delete_response_handler, (void*)url ); smcp_transaction_begin(smcp, ret, 30*MSEC_PER_SEC); bail: return ret; }
bool send_get_request(smcp_t smcp, const char* next, coap_size_t nextlen, void *thingML_context) { bool ret = false; smcp_status_t status = 0; int flags = SMCP_TRANSACTION_ALWAYS_INVALIDATE; gRet = ERRORCODE_INPROGRESS; retries = 0; if(get_observe) flags |= SMCP_TRANSACTION_OBSERVE; if(get_keep_alive) flags |= SMCP_TRANSACTION_KEEPALIVE; smcp_transaction_end(smcp,&transaction); smcp_transaction_init( &transaction, flags, // Flags (void*)&resend_get_request, (void*)&get_response_handler, thingML_context ); status = smcp_transaction_begin(smcp, &transaction, get_timeout); if(status) { check(!status); fprintf(stderr, "smcp_begin_transaction_old() returned %d(%s).\n", status, smcp_status_to_cstr(status)); goto bail; } ret = true; bail: return ret; }
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; smcp_curl_request_t request = (smcp_curl_request_t)userp; require_action(realsize>=0,bail,realsize=0); // At the moment limit to one call. require_action(request->content==NULL,bail,realsize=0); request->content = realloc(request->content, request->content_len + realsize + 1); require_action(request->content!=NULL,bail,realsize=0); memcpy(&(request->content[request->content_len]), contents, realsize); request->content_len += realsize; request->content[request->content_len] = 0; smcp_transaction_init( &request->async_transaction, 0, // Flags (void*)&resend_async_response, (void*)&async_response_ack_handler, (void*)request ); smcp_transaction_begin( request->proxy_node->interface, &request->async_transaction, 10*1000 // Retry for thirty seconds. ); bail: return realsize; }
smcp_status_t cgi_node_send_next_block(cgi_node_t node,cgi_node_request_t request) { smcp_status_t ret = 0; // If we are currently asynchronous, go ahead and send an asynchronous response. // Otherwise, we don't have much to do: We will just go ahead and send // the rest of the data at the next query. // TODO: Writeme! smcp_transaction_t transaction = smcp_transaction_init( request->transaction, 0, &cgi_node_async_resend_response, &cgi_node_async_ack_handler, (void*)request ); if(!transaction) { ret = SMCP_STATUS_MALLOC_FAILURE; goto bail; } ret = smcp_transaction_begin( node->interface, transaction, 30*MSEC_PER_SEC ); if(ret) { smcp_transaction_end(smcp_get_current_instance(),transaction); goto bail; } bail: return ret; }
bool test_simple(smcp_t smcp, test_data_s *test_data, const char* url, const char* rel, coap_code_t outbound_code,coap_transaction_type_t outbound_tt,coap_code_t expected_code, int extra) { smcp_cms_t timeout = 15*MSEC_PER_SEC; smcp_status_t status; smcp_transaction_t transaction = NULL; int t_flags = SMCP_TRANSACTION_ALWAYS_INVALIDATE | SMCP_TRANSACTION_NO_AUTO_END; smcp_timestamp_t expiry = smcp_plat_cms_to_timestamp(timeout+MSEC_PER_SEC); memset(test_data,0,sizeof(*test_data)); test_data->outbound_code = outbound_code; test_data->outbound_tt = outbound_tt; test_data->expected_code = expected_code; test_data->extra = extra; test_data->outbound_content_type = COAP_CONTENT_TYPE_UNKNOWN; if (extra & EXT_BLOCK_01) { test_data->outbound_content_type = COAP_CONTENT_TYPE_TEXT_PLAIN; test_data->block1_option = (2 | (1<<3)); // 64 byte block size; } if(strlen(url) && (url[strlen(url)-1] == '/')) { snprintf(test_data->url,sizeof(test_data->url), "%s%s",url,rel); } else { snprintf(test_data->url,sizeof(test_data->url), "%s/%s",url,rel); } if (extra & EXT_OBS_01) { t_flags = SMCP_TRANSACTION_OBSERVE; } test_data->start_time = smcp_plat_cms_to_timestamp(0); transaction = smcp_transaction_init( transaction, t_flags, (void*)&resend_test_request, (void*)&response_test_handler, (void*)test_data ); test_data->transaction = transaction; status = smcp_transaction_begin( smcp, transaction, timeout ); require_noerr(status, bail); while(!test_data->finished && (smcp_plat_timestamp_to_cms(expiry)>0)) { status = smcp_plat_wait(smcp, smcp_plat_timestamp_to_cms(expiry)); require((status==SMCP_STATUS_OK) || (status==SMCP_STATUS_TIMEOUT), bail); status = smcp_plat_process(smcp); require_noerr(status, bail); } test_data->stop_time = smcp_plat_cms_to_timestamp(0); test_data->failed = true; require(smcp_plat_timestamp_to_cms(expiry)>0, bail); require(test_data->inbound_code == test_data->expected_code,bail); if (expected_code == COAP_CODE_EMPTY) { require(test_data->error == SMCP_STATUS_RESET, bail); } else { require(test_data->error == SMCP_STATUS_OK, bail); } test_data->failed = false; bail: if (transaction) { smcp_transaction_end(smcp, transaction); } return (status == SMCP_STATUS_OK) && !test_data->failed; }