smcp_t smcp_init( smcp_t self, uint16_t port ) { SMCP_EMBEDDED_SELF_HOOK; require(self != NULL, bail); if(port == 0) port = COAP_DEFAULT_PORT; #if SMCP_USE_BSD_SOCKETS struct sockaddr_in6 saddr = { #if SOCKADDR_HAS_LENGTH_FIELD .sin6_len = sizeof(struct sockaddr_in6), #endif .sin6_family = AF_INET6, .sin6_port = htons(port), }; #endif // Clear the entire structure. memset(self, 0, sizeof(*self)); // Set up the UDP port for listening. #if SMCP_USE_BSD_SOCKETS uint16_t attempts = 0x7FFF; self->mcfd = -1; self->fd = -1; errno = 0; self->fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); int prev_errno = errno; require_action_string( self->fd >= 0, bail, ( smcp_release(self), self = NULL ), strerror(prev_errno) ); // Keep attempting to bind until we find a port that works. while(bind(self->fd, (struct sockaddr*)&saddr, sizeof(saddr)) != 0) { // We should only continue trying if errno == EADDRINUSE. require_action_string(errno == EADDRINUSE, bail, { DEBUG_PRINTF(CSTR("errno=%d"), errno); smcp_release( self); self = NULL; }, "Failed to bind socket"); port++; // Make sure we aren't in an infinite loop. require_action_string(--attempts, bail, { DEBUG_PRINTF(CSTR("errno=%d"), errno); smcp_release( self); self = NULL; }, "Failed to bind socket (ran out of ports)");
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; }
int main(void) { smcp_t instance = smcp_create(0); if(!instance) { perror("Unable to create SMCP instance"); abort(); } printf("Listening on port %d\n",smcp_get_port(instance)); smcp_set_default_request_handler(instance, &request_handler, NULL); while(1) { smcp_process(instance, CMS_DISTANT_FUTURE); } smcp_release(instance); return 0; }
int tool_cmd_get_url(void *thingML_context) { ThingMLCOAPContext* context = (ThingMLCOAPContext*) thingML_context; get_show_headers = context->client_coap_config.get_show_headers; next_len = context->client_coap_config.next_len; redirect_count = context->client_coap_config.redirect_count; size_request = context->client_coap_config.size_request; get_observe = context->client_coap_config.get_observe; get_keep_alive = context->client_coap_config.get_keep_alive; get_timeout = context->client_coap_config.get_timeout; // Default timeout is 30 seconds. last_observe_value = context->client_coap_config.last_observe_value; request_accept_type = context->client_coap_config.request_accept_type; observe_once = context->client_coap_config.observe_once; observe_ignore_first = context->client_coap_config.observe_ignore_first; get_tt = context->client_coap_config.get_tt; smcp_t gSMCPInstance = smcp_create(((ThingMLCOAPContext*) thingML_context)->port); gRet = ERRORCODE_INPROGRESS; require(send_get_request(gSMCPInstance, NULL, 0, thingML_context), bail); while(ERRORCODE_INPROGRESS == gRet) { smcp_wait(gSMCPInstance,1000); smcp_process(gSMCPInstance); } bail: smcp_transaction_end(gSMCPInstance,&transaction); if(gSMCPInstance) smcp_release(gSMCPInstance); return gRet; }
smcp_t smcp_init( smcp_t self, uint16_t port ) { #if SMCP_EMBEDDED smcp_t self = smcp_get_current_instance(); #endif require(self != NULL, bail); if(port == 0) port = COAP_DEFAULT_PORT; smcp_sockaddr_t saddr = { #if SOCKADDR_HAS_LENGTH_FIELD .___smcp_len = sizeof(smcp_sockaddr_t), #endif .___smcp_family = SMCP_BSD_SOCKETS_NET_FAMILY, .smcp_port = htons(port), }; // Clear the entire structure. memset(self, 0, sizeof(*self)); // Set up the UDP port for listening. uint16_t attempts = 0x7FFF; self->mcfd = -1; self->fd = -1; errno = 0; self->fd = socket(SMCP_BSD_SOCKETS_NET_FAMILY, SOCK_DGRAM, IPPROTO_UDP); int prev_errno = errno; require_action_string( self->fd >= 0, bail, ( smcp_release(self), self = NULL ), strerror(prev_errno) ); #if defined(IPV6_V6ONLY) && SMCP_BSD_SOCKETS_NET_FAMILY==AF_INET6 { int value = 0; /* explicitly allow ipv4 traffic too (required on bsd and some debian installations) */ if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_V6ONLY, &value, sizeof(value)) < 0) { DEBUG_PRINTF(CSTR("Socket won't allow IPv4 connections")); } } #endif // Keep attempting to bind until we find a port that works. while(bind(self->fd, (struct sockaddr*)&saddr, sizeof(saddr)) != 0) { // We should only continue trying if errno == EADDRINUSE. require_action_string(errno == EADDRINUSE, bail, { DEBUG_PRINTF(CSTR("errno=%d"), errno); smcp_release( self); self = NULL; }, "Failed to bind socket"); port++; // Make sure we aren't in an infinite loop. require_action_string(--attempts, bail, { DEBUG_PRINTF(CSTR("errno=%d"), errno); smcp_release( self); self = NULL; }, "Failed to bind socket (ran out of ports)");