static smcp_status_t delete_response_handler( int statuscode, void* context ) { if (statuscode >= 0) { char* content = (char*)smcp_inbound_get_content_ptr(); coap_size_t content_length = smcp_inbound_get_content_len(); if(content_length>(smcp_inbound_get_packet_length()-4)) { fprintf(stderr, "INTERNAL ERROR: CONTENT_LENGTH LARGER THAN PACKET_LENGTH-4! (content_length=%u, packet_length=%u)\n",content_length,smcp_inbound_get_packet_length()); gRet = ERRORCODE_UNKNOWN; goto bail; } if (delete_show_headers) { coap_dump_header( stdout, NULL, smcp_inbound_get_packet(), smcp_inbound_get_packet_length() ); } if(!coap_verify_packet((void*)smcp_inbound_get_packet(), smcp_inbound_get_packet_length())) { fprintf(stderr, "INTERNAL ERROR: CALLBACK GIVEN INVALID PACKET!\n"); gRet = ERRORCODE_UNKNOWN; goto bail; } if (statuscode != COAP_RESULT_202_DELETED) { fprintf(stderr, "delete: Result code = %d (%s)\n", statuscode, (statuscode < 0) ? smcp_status_to_cstr( statuscode) : coap_code_to_cstr(statuscode)); } if(content && content_length) { char contentBuffer[500]; content_length = ((content_length > sizeof(contentBuffer) - 2) ? sizeof(contentBuffer) - 2 : content_length); memcpy(contentBuffer, content, content_length); contentBuffer[content_length] = 0; if(content_length && (contentBuffer[content_length - 1] == '\n')) contentBuffer[--content_length] = 0; printf("%s\n", contentBuffer); } } bail: if (gRet == ERRORCODE_INPROGRESS) { gRet = 0; } return SMCP_STATUS_OK; }
smcp_status_t smcp_outbound_send() { smcp_status_t ret = SMCP_STATUS_FAILURE; smcp_t const self = smcp_get_current_instance(); coap_size_t header_len = (coap_size_t)(smcp_outbound_get_content_ptr(NULL)-(char*)self->outbound.packet); // Remove the start-of-payload marker if we have no payload. if (!smcp_get_current_instance()->outbound.content_len) { header_len--; } #if DEBUG { DEBUG_PRINTF("Outbound packet size: %d, %d remaining",header_len+smcp_get_current_instance()->outbound.content_len, smcp_outbound_get_space_remaining()); assert(header_len+smcp_get_current_instance()->outbound.content_len<=self->outbound.max_packet_len); assert(coap_verify_packet((char*)self->outbound.packet,header_len+smcp_get_current_instance()->outbound.content_len)); } #endif // DEBUG if (self->current_transaction) { self->current_transaction->sent_code = self->outbound.packet->code; self->current_transaction->sockaddr_remote = *smcp_plat_get_remote_sockaddr(); self->current_transaction->multicast = SMCP_IS_ADDR_MULTICAST(&self->current_transaction->sockaddr_remote.smcp_addr); } #if defined(SMCP_DEBUG_OUTBOUND_DROP_PERCENT) if(SMCP_DEBUG_OUTBOUND_DROP_PERCENT*SMCP_RANDOM_MAX>SMCP_FUNC_RANDOM_UINT32()) { DEBUG_PRINTF("Dropping outbound packet for debugging!"); if(smcp_get_current_instance()->is_responding) smcp_get_current_instance()->did_respond = true; smcp_get_current_instance()->is_responding = false; ret = SMCP_STATUS_OK; goto bail; } #endif if ((self->outbound.packet->tt == COAP_TRANS_TYPE_ACK) && smcp_session_type_is_reliable(smcp_plat_get_session_type()) ) { // If the session type is reliable, we don't bother // sending acks. } else { ret = smcp_plat_outbound_finish( self, (const uint8_t*)self->outbound.packet, header_len + self->outbound.content_len, 0 // FLAGS ); } require(ret == SMCP_STATUS_OK, bail); if (self->is_responding) { self->did_respond = true; } self->is_responding = false; ret = SMCP_STATUS_OK; bail: return ret; }
static smcp_status_t get_response_handler(int statuscode, void* context) { ThingMLCOAPContext * thingml_context = (ThingMLCOAPContext *) context; const char* content = (const char*)smcp_inbound_get_content_ptr(); coap_size_t content_length = smcp_inbound_get_content_len(); if(statuscode>=0) { if(content_length>(smcp_inbound_get_packet_length()-4)) { fprintf(stderr, "INTERNAL ERROR: CONTENT_LENGTH LARGER THAN PACKET_LENGTH-4! (content_length=%u, packet_length=%u)\n",content_length,smcp_inbound_get_packet_length()); gRet = ERRORCODE_UNKNOWN; thingml_context->fn_onerror_callback(thingml_context->thing_instance, gRet); goto bail; } if((statuscode >= 0) && get_show_headers) { if(next_len != ((coap_size_t)(-1))) fprintf(stdout, "\n\n"); coap_dump_header( stdout, NULL, smcp_inbound_get_packet(), smcp_inbound_get_packet_length() ); } if(!coap_verify_packet((void*)smcp_inbound_get_packet(), smcp_inbound_get_packet_length())) { fprintf(stderr, "INTERNAL ERROR: CALLBACK GIVEN INVALID PACKET!\n"); gRet = ERRORCODE_UNKNOWN; thingml_context->fn_onerror_callback(thingml_context->thing_instance, gRet); goto bail; } } if(statuscode == SMCP_STATUS_TRANSACTION_INVALIDATED) { gRet = 0; } if(observe_ignore_first) { observe_ignore_first = false; goto bail; } if( ((statuscode < COAP_RESULT_200) ||(statuscode >= COAP_RESULT_400)) && (statuscode != SMCP_STATUS_TRANSACTION_INVALIDATED) && (statuscode != HTTP_TO_COAP_CODE(HTTP_RESULT_CODE_PARTIAL_CONTENT)) ) { if(get_observe && statuscode == SMCP_STATUS_TIMEOUT) { gRet = 0; } else { gRet = (statuscode == SMCP_STATUS_TIMEOUT)?ERRORCODE_TIMEOUT:ERRORCODE_COAP_ERROR; fprintf(stderr, "get: Result code = %d (%s)\n", statuscode, (statuscode < 0) ? smcp_status_to_cstr( statuscode) : coap_code_to_cstr(statuscode)); thingml_context->fn_onerror_callback(thingml_context->thing_instance, gRet); } } if((statuscode>0) && content && content_length) { coap_option_key_t key; const uint8_t* value; coap_size_t value_len; bool last_block = true; int32_t observe_value = -1; while((key=smcp_inbound_next_option(&value, &value_len))!=COAP_OPTION_INVALID) { if(key == COAP_OPTION_BLOCK2) { last_block = !(value[value_len-1]&(1<<3)); } else if(key == COAP_OPTION_OBSERVE) { if(value_len) observe_value = value[0]; else observe_value = 0; } } thingml_context->fn_onmsgrcv_callback(thingml_context->thing_instance, content, content_length); last_observe_value = observe_value; } if(observe_once) { gRet = 0; goto bail; } bail: return SMCP_STATUS_OK; }