Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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");
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}