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; }
void coap_dump_packet(coap_packet_t *pkt) { coap_dump_header(&pkt->header); coap_dump_options(pkt->opts, pkt->numopts); printf("Payload: "); coap_dump_buffer(pkt->payload.p, pkt->payload.len, true); printf("\n"); }
static smcp_status_t smcp_outbound_add_option_( coap_option_key_t key, const char* value, size_t len ) { smcp_t const self = smcp_get_current_instance(); if( ( self->outbound.content_ptr - (char*)self->outbound.packet + len + 10 ) > SMCP_MAX_PACKET_LENGTH ) { // We ran out of room! return SMCP_STATUS_MESSAGE_TOO_BIG; } if(key<self->outbound.last_option_key) { assert_printf("warning: Out of order header: %s",coap_option_key_to_cstr(key, self->is_responding)); } if(len == SMCP_CSTR_LEN) len = strlen(value); if(self->outbound.content_ptr!=(char*)self->outbound.packet->token+self->outbound.packet->token_len) self->outbound.content_ptr--; // remove end-of-options marker self->outbound.content_ptr += coap_insert_option( (uint8_t*)self->outbound.packet->token+self->outbound.packet->token_len, (uint8_t*)self->outbound.content_ptr, key, (const uint8_t*)value, len ); if(key>self->outbound.last_option_key) self->outbound.last_option_key = key; *self->outbound.content_ptr++ = 0xFF; // Add end-of-options marker #if OPTION_DEBUG coap_dump_header( SMCP_DEBUG_OUT_FILE, "Option-Debug >>> ", self->outbound.packet, self->outbound.content_ptr-(char*)self->outbound.packet ); #endif return SMCP_STATUS_OK; }
static smcp_status_t retry_sending_event(struct smcp_observer_s* observer) { smcp_status_t status; smcp_t const self = smcp_get_current_instance(); status = smcp_outbound_begin_response(COAP_RESULT_205_CONTENT); require_noerr(status,bail); status = smcp_outbound_set_async_response(&observer->async_response); require_noerr(status,bail); status = smcp_outbound_add_option_uint(COAP_OPTION_OBSERVE,observer->seq); require_noerr(status,bail); self->outbound.packet->tt = SHOULD_CONFIRM_EVENT_FOR_OBSERVER(observer)?COAP_TRANS_TYPE_CONFIRMABLE:COAP_TRANS_TYPE_NONCONFIRMABLE; self->inbound.has_observe_option = true; self->is_responding = true; self->force_current_outbound_code = true; self->is_processing_message = true; self->did_respond = false; #if VERBOSE_DEBUG coap_dump_header( SMCP_DEBUG_OUT_FILE, "FAKE Inbound:\t", self->inbound.packet, self->inbound.packet_len ); #endif status = smcp_handle_request(self); require(!status||status==SMCP_STATUS_NOT_FOUND||status==SMCP_STATUS_NOT_ALLOWED,bail); if(status) { smcp_outbound_set_content_len(0); smcp_outbound_send(); } bail: self->is_processing_message = false; self->did_respond = false; return status; }
static smcp_status_t pair_response_handler( int statuscode, void* context ) { // smcp_t const self = smcp_get_current_instance(); char* content = (char*)smcp_inbound_get_content_ptr(); coap_size_t content_length = smcp_inbound_get_content_len(); if((statuscode >= COAP_RESULT_100) && show_headers) { fprintf(stdout, "\n"); coap_dump_header( stdout, "NULL", smcp_inbound_get_packet(), 0 ); } if(((statuscode < COAP_RESULT_200) || (statuscode >= COAP_RESULT_300)) && (statuscode != SMCP_STATUS_TRANSACTION_INVALIDATED)) fprintf(stderr, "pair: 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); } if(gRet == ERRORCODE_INPROGRESS) gRet = ERRORCODE_OK; free(context); return SMCP_STATUS_OK; }
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; }
smcp_status_t device_func( smcp_variable_node_t node, uint8_t action, uint8_t i, char* value ) { smcp_status_t ret = 0; if(action==SMCP_VAR_GET_KEY) { switch(i) { case 0: strcpy(value,"loadavg"); break; case 1: strcpy(value,"clock"); break; case 2: strcpy(value,"action"); break; default: ret = SMCP_STATUS_NOT_FOUND; break; } } else if(action==SMCP_VAR_GET_MAX_AGE && i==0) { strcpy(value,"5"); } else if(action==SMCP_VAR_GET_VALUE) { switch(i) { case 0: { double loadavg[3] = { }; require_action( 0 < getloadavg(loadavg, sizeof(loadavg) / sizeof(*loadavg)), bail, ret = SMCP_STATUS_FAILURE ); require_action( (size_t)snprintf( value, SMCP_VARIABLE_MAX_VALUE_LENGTH, "%0.2f", loadavg[0] ) <= SMCP_VARIABLE_MAX_VALUE_LENGTH, bail, ret = SMCP_STATUS_FAILURE ); } break; case 1: require_action( (size_t)snprintf( value, SMCP_VARIABLE_MAX_VALUE_LENGTH, "%d", (int)clock() ) <= SMCP_VARIABLE_MAX_VALUE_LENGTH, bail, ret = SMCP_STATUS_FAILURE ); break; case 2: ret = SMCP_STATUS_NOT_ALLOWED; break; default: ret = SMCP_STATUS_NOT_FOUND; break; } } else if(action==SMCP_VAR_SET_VALUE) { switch(i) { case 0: ret = SMCP_STATUS_NOT_ALLOWED; break; case 1: ret = SMCP_STATUS_NOT_ALLOWED; break; case 2: fprintf(stdout," *** Received Action!\n"); coap_dump_header( stdout, " * ", smcp_inbound_get_packet(), 0 ); break; default: ret = SMCP_STATUS_NOT_FOUND; break; } } else { ret = SMCP_STATUS_NOT_IMPLEMENTED; } bail: return ret; }
smcp_status_t smcp_plat_outbound_finish(smcp_t self,const uint8_t* data_ptr, coap_size_t data_len, int flags) { SMCP_EMBEDDED_SELF_HOOK; smcp_status_t ret = SMCP_STATUS_FAILURE; ssize_t sent_bytes = -1; int fd; #if SMCP_DTLS if (smcp_plat_get_session_type() == SMCP_SESSION_TYPE_DTLS) { ret = smcp_plat_ssl_outbound_packet_process(self, data_ptr, data_len); } else #endif if (smcp_plat_get_session_type() == SMCP_SESSION_TYPE_UDP) { fd = smcp_get_current_instance()->plat.fd_udp; assert(fd >= 0); require(data_len > 0, bail); #if VERBOSE_DEBUG { char addr_str[50] = "???"; uint16_t port = ntohs(smcp_plat_get_remote_sockaddr()->smcp_port); SMCP_ADDR_NTOP(addr_str,sizeof(addr_str),&smcp_plat_get_remote_sockaddr()->smcp_addr); DEBUG_PRINTF("smcp(%p): Outbound packet to [%s]:%d", self,addr_str,(int)port); coap_dump_header( SMCP_DEBUG_OUT_FILE, "Outbound:\t", (struct coap_header_s*)data_ptr, (coap_size_t)data_len ); } #endif sent_bytes = sendtofrom( fd, data_ptr, data_len, 0, (struct sockaddr *)smcp_plat_get_remote_sockaddr(), sizeof(smcp_sockaddr_t), (struct sockaddr *)smcp_plat_get_local_sockaddr(), sizeof(smcp_sockaddr_t) ); require_action_string( (sent_bytes >= 0), bail, ret = SMCP_STATUS_ERRNO, strerror(errno) ); require_action_string( (sent_bytes == data_len), bail, ret = SMCP_STATUS_FAILURE, "sendto() returned less than len" ); ret = SMCP_STATUS_OK; } else { ret = SMCP_STATUS_NOT_IMPLEMENTED; } bail: return ret; }