コード例 #1
0
ファイル: example-1.c プロジェクト: paulobrizolara/smcp
int
main(void)
{
	smcp_t instance;

	SMCP_LIBRARY_VERSION_CHECK();

	// Create our instance on the default CoAP port. If the port
	// is already in use, we will pick the next available port number.
	instance = smcp_create();

	if (!instance) {
		perror("Unable to create SMCP instance");
		exit(EXIT_FAILURE);
	}

	smcp_plat_bind_to_port(instance, SMCP_SESSION_TYPE_UDP, COAP_DEFAULT_PORT);

	printf("Listening on port %d\n",smcp_plat_get_port(instance));

	// SMCP will always respond to requests with METHOD_NOT_IMPLEMENTED
	// unless a request handler is set. Unless your program is only
	// making CoAP requests, you'll need a line like the following
	// in your program. The request handler may either handle the
	// request itself or route the request to the appropriate handler.
	smcp_set_default_request_handler(instance, &request_handler, NULL);

	// Loop forever. This is the most simple kind of main loop you
	// can haave with SMCP. It is appropriate for simple CoAP servers
	// and clients which do not need asynchronous I/O.
	while (1) {
		smcp_plat_wait(instance, CMS_DISTANT_FUTURE);
		smcp_plat_process(instance);
	}

	// We won't actually get to this line with the above loop, but it
	// is always a good idea to clean up when you are done. If you
	// provide a way to gracefully exit from your own main loop, you
	// can tear down the SMCP instance using the following command.
	smcp_release(instance);

	return EXIT_SUCCESS;
}
コード例 #2
0
ファイル: main-client.c プロジェクト: paulobrizolara/smcp
int
main(int argc, char * argv[]) {
	smcp_t smcp;
	const char* url = "coap://localhost/";
	int errorcount = 0;
	int round_count = 1;
	int round = 0;
	test_data_s test_data;

	SMCP_LIBRARY_VERSION_CHECK();

	smcp = smcp_create();

	smcp_plat_bind_to_port(smcp, SMCP_SESSION_TYPE_UDP, 0);


//	url = "coap://contiki.local./";
//	url = "coap://coap.me/";
//	url = "coap://vs0.inf.ethz.ch/";

	if (argc > 1) url = argv[1];
	if (!smcp) {
		fprintf(stderr,"Unable to allocate smcp instance\n");
		exit(-1);
	}

	if (argc > 2) {
		round_count = atoi(argv[2]);
	}

	printf("Client using port %d. Will test %d rounds.\n", smcp_plat_get_port(smcp), round_count);

#define do_test(x)	do { printf("%s: Testing...\n",#x); if(test_ ## x(smcp,url,&test_data)) { dump_test_results(&test_data); printf("\tresult = OK\n"); } else { dump_test_results(&test_data); printf("\tresult = FAIL\n"); errorcount++; } } while(0)

#define do_test_expect_fail(x)	do { printf("%s: Testing...\n",#x); if(test_ ## x(smcp,url,&test_data)) { dump_test_results(&test_data); printf("\tresult = OK (Unexpected)\n"); } else { dump_test_results(&test_data); printf("\tresult = FAIL (Expected)\n"); } } while(0)

	for(round = 0;round<round_count && errorcount==0;round++) {
		printf("\n## Round %d...\n",round+1);

		do_test(TD_COAP_CORE_01);
		do_test(TD_COAP_CORE_02);
		do_test(TD_COAP_CORE_03);
		do_test(TD_COAP_CORE_04);
		do_test(TD_COAP_CORE_05);
		do_test(TD_COAP_CORE_06);
		do_test(TD_COAP_CORE_07);
		do_test(TD_COAP_CORE_08);
		do_test(TD_COAP_CORE_09);

		do_test(TD_COAP_CORE_13);
		do_test(TD_COAP_CORE_14);
		do_test(TD_COAP_CORE_17);
		do_test(TD_COAP_CORE_31);

		do_test(TD_COAP_LINK_01);

		do_test(TD_COAP_BLOCK_01);
		do_test(TD_COAP_BLOCK_02);

		do_test_expect_fail(TD_COAP_BLOCK_03);
		do_test_expect_fail(TD_COAP_BLOCK_04);
		do_test_expect_fail(TD_COAP_BLOCK_05);
		do_test(TD_COAP_OBS_01);
	}

	if (errorcount == 0) {
		printf("\nPASS\n");
	} else {
		printf("\nFAIL\n");
	}

	return errorcount;
}
コード例 #3
0
ファイル: smcp-outbound.c プロジェクト: robbie-cao/smcp
smcp_status_t
smcp_outbound_set_uri(
	const char* uri, char flags
) {
	smcp_status_t ret = SMCP_STATUS_OK;
	smcp_t const self = smcp_get_current_instance();
	SMCP_NON_RECURSIVE struct url_components_s components;
	SMCP_NON_RECURSIVE uint16_t toport;
	SMCP_NON_RECURSIVE char* uri_copy;

	memset((void*)&components, 0, sizeof(components));
	toport = COAP_DEFAULT_PORT;
	smcp_plat_set_session_type(SMCP_SESSION_TYPE_UDP);
	uri_copy = NULL;

	require_action(uri, bail, ret = SMCP_STATUS_INVALID_ARGUMENT);

	{
#if HAVE_ALLOCA
		uri_copy = alloca(strlen(uri) + 1);
		strcpy(uri_copy, uri);
#elif SMCP_AVOID_MALLOC
		// Well, we can't use the stack and we can't
		// use malloc. Let's use what room we have left
		// in the packet buffer, since this is temporary anyway...
		// It helps a bunch that we know the user hasn't written
		// any content yet (because that would be an API violation)
		if (smcp_outbound_get_space_remaining() > strlen(uri) + 8) {
			uri_copy = self->outbound.content_ptr + self->outbound.content_len;

			// The options section may be expanding as we parse this, so
			// we should move ahead by a few bytes. We are helped out
			// by the fact that we will be writing the options in the
			// same order they appear in the URL.
			uri_copy += 8;

			strcpy(uri_copy, uri);
		}
#else
		uri_copy = strdup(uri);
#endif

		require_action(uri_copy != NULL, bail, ret = SMCP_STATUS_MALLOC_FAILURE);

		// Parse the URI.
		require_action_string(
			url_parse(
				uri_copy,
				&components
			),
			bail,
			ret = SMCP_STATUS_URI_PARSE_FAILURE,
			"Unable to parse URL"
		);

		if(!components.protocol && !components.host) {
			// Talking to ourself.
			components.protocol = "coap";
			components.host = "::1";
			toport = smcp_plat_get_port(smcp_get_current_instance());
			flags |= SMCP_MSG_SKIP_AUTHORITY;
		} else if(components.port) {
			toport = (uint16_t)atoi(components.port);
		}

		DEBUG_PRINTF(
			"URI Parse: \"%s\" -> host=\"%s\" port=\"%u\" path=\"%s\"",
			uri,
			components.host,
			toport,
			components.path
		);
	}

	if (components.protocol) {
		smcp_session_type_t session_type = smcp_session_type_from_uri_scheme(components.protocol);
		smcp_plat_set_session_type(session_type);

		if (NULL == components.port) {
			toport = smcp_default_port_from_session_type(session_type);
		}

		if (session_type == SMCP_SESSION_TYPE_NIL) {
			require_action_string(
				self->proxy_url,
				bail,
				ret=SMCP_STATUS_INVALID_ARGUMENT,
				"No proxy URL configured"
			);
			require_action(uri != self->proxy_url,bail,ret = SMCP_STATUS_INVALID_ARGUMENT);

			ret = smcp_outbound_add_option(COAP_OPTION_PROXY_URI, uri, SMCP_CSTR_LEN);
			require_noerr(ret, bail);
			ret = smcp_outbound_set_uri(self->proxy_url,flags);
			goto bail;
		}
	}

	if (!(flags & SMCP_MSG_SKIP_AUTHORITY)) {
		if(components.host && !string_contains_colons(components.host)) {
			ret = smcp_outbound_add_option(COAP_OPTION_URI_HOST, components.host, SMCP_CSTR_LEN);
			require_noerr(ret, bail);
		}
		if(components.port) {
			ret = smcp_outbound_add_option_uint(COAP_OPTION_URI_PORT, toport);
			require_noerr(ret, bail);
		}
	}


	if ( !(flags & SMCP_MSG_SKIP_DESTADDR)
	  && components.host && components.host[0]!=0
	) {
		ret = smcp_set_remote_sockaddr_from_host_and_port(
			components.host,
			toport
		);
		require_noerr(ret, bail);
	}

	if (components.path) {
		SMCP_NON_RECURSIVE char* component;
		const bool has_trailing_slash = components.path[0]?('/' == components.path[strlen(components.path)-1]):false;

		// Move past any preceding slashes.
		while (components.path[0] == '/') {
			components.path++;
		}

		while (url_path_next_component(&components.path,&component)) {
			ret = smcp_outbound_add_option(COAP_OPTION_URI_PATH, component, SMCP_CSTR_LEN);
			require_noerr(ret,bail);
		}

		if (has_trailing_slash) {
			ret = smcp_outbound_add_option(COAP_OPTION_URI_PATH, NULL, 0);
			require_noerr(ret,bail);
		}
	}

	if (components.query) {
		SMCP_NON_RECURSIVE char* key;

		while (url_form_next_value(&components.query, &key, NULL)) {
			coap_size_t len = (coap_size_t)strlen(key);

			if (len) {
				ret = smcp_outbound_add_option(COAP_OPTION_URI_QUERY, key, len);
			}
			require_noerr(ret,bail);
		}
	}

bail:
	if(ret) {
		DEBUG_PRINTF("URI Parse failed for URI: \"%s\"",uri);
	}

#if !HAVE_ALLOCA && !SMCP_AVOID_MALLOC
	free(uri_copy);
#endif

	return ret;
}