coap_endpoint_t * coap_new_endpoint(const coap_address_t *addr, int flags) { int sockfd = socket(addr->addr.sa.sa_family, SOCK_DGRAM, 0); int on = 1; struct coap_endpoint_t *ep; if (sockfd < 0) { coap_log(LOG_WARNING, "coap_new_endpoint: socket"); return NULL; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) coap_log(LOG_WARNING, "coap_new_endpoint: setsockopt SO_REUSEADDR"); if (bind(sockfd, &addr->addr.sa, addr->size) < 0) { coap_log(LOG_WARNING, "coap_new_endpoint: bind"); close (sockfd); return NULL; } ep = coap_malloc_posix_endpoint(); if (!ep) { coap_log(LOG_WARNING, "coap_new_endpoint: malloc"); close(sockfd); return NULL; } memset(ep, 0, sizeof(struct coap_endpoint_t)); ep->handle.fd = sockfd; ep->flags = flags; ep->addr.size = addr->size; if (getsockname(sockfd, &ep->addr.addr.sa, &ep->addr.size) < 0) { coap_log(LOG_WARNING, "coap_new_endpoint: cannot determine local address"); close (sockfd); return NULL; } #ifndef NDEBUG if (LOG_DEBUG <= coap_get_log_level()) { #ifndef INET6_ADDRSTRLEN #define INET6_ADDRSTRLEN 40 #endif unsigned char addr_str[INET6_ADDRSTRLEN+8]; if (coap_print_addr(&ep->addr, addr_str, INET6_ADDRSTRLEN+8)) { debug("created %sendpoint %s\n", ep->flags & COAP_ENDPOINT_DTLS ? "DTLS " : "", addr_str); } } #endif /* NDEBUG */ return (coap_endpoint_t *)ep; }
coap_pdu_t * coap_new_pdu(coap_transport_type transport, unsigned int size) { coap_pdu_t *pdu; #ifndef WITH_CONTIKI pdu = coap_pdu_init(0, 0, ntohs(COAP_INVALID_TID), #ifndef WITH_TCP COAP_MAX_PDU_SIZE, #else size, #endif transport); #else /* WITH_CONTIKI */ pdu = coap_pdu_init(0, 0, uip_ntohs(COAP_INVALID_TID), #ifndef WITH_TCP COAP_MAX_PDU_SIZE, #else size, #endif transport); #endif /* WITH_CONTIKI */ #ifndef NDEBUG if (!pdu) coap_log(LOG_CRIT, "coap_new_pdu: cannot allocate memory for new PDU\n"); #endif return pdu; }
int coap_insert(coap_list_t **head, coap_list_t *node) { if (!node) { coap_log(LOG_WARNING, "cannot create option Proxy-Uri\n"); } else { /* must append at the list end to avoid re-ordering of * options during sort */ LL_APPEND((*head), node); } return node != NULL; }
coap_async_state_t * coap_register_async(coap_context_t *context, coap_address_t *peer, coap_pdu_t *request, unsigned char flags, void *data) { coap_async_state_t *s; coap_tid_t id; coap_transaction_id(peer, request, &id); LL_SEARCH_SCALAR(context->async_state, s, id, id); if (s != NULL) { /* We must return NULL here as the caller must know that he is * responsible for releasing @p data. */ debug("asynchronous state for transaction %d already registered\n", id); return NULL; } /* store information for handling the asynchronous task */ s = (coap_async_state_t *) coap_malloc(sizeof(coap_async_state_t) + request->hdr->token_length); if (!s) { coap_log(LOG_CRIT, "coap_register_async: insufficient memory\n"); return NULL; } memset(s, 0, sizeof(coap_async_state_t) + request->hdr->token_length); /* set COAP_ASYNC_CONFIRM according to request's type */ s->flags = flags & ~COAP_ASYNC_CONFIRM; if (request->hdr->type == COAP_MESSAGE_CON) s->flags |= COAP_ASYNC_CONFIRM; s->appdata = data; memcpy(&s->peer, peer, sizeof(coap_address_t)); if (request->hdr->token_length) { s->tokenlen = request->hdr->token_length; memcpy(s->token, request->hdr->token, request->hdr->token_length); } memcpy(&s->id, &id, sizeof(coap_tid_t)); coap_touch_async(s); LL_PREPEND(context->async_state, s); return s; }
str *coap_new_string(size_t size) { str *s = coap_malloc(sizeof(str) + size + 1); if ( !s ) { #ifndef NDEBUG coap_log(LOG_CRIT, "coap_new_string: malloc\n"); #endif return NULL; } memset(s, 0, sizeof(str)); s->s = ((unsigned char *)s) + sizeof(str); return s; }
coap_pdu_t * coap_new_pdu(void) { coap_pdu_t *pdu; #ifndef WITH_CONTIKI pdu = coap_pdu_init(0, 0, ntohs((unsigned short)COAP_INVALID_TID), COAP_MAX_PDU_SIZE); #else /* WITH_CONTIKI */ pdu = coap_pdu_init(0, 0, uip_ntohs(COAP_INVALID_TID), COAP_MAX_PDU_SIZE); #endif /* WITH_CONTIKI */ #ifndef NDEBUG if (!pdu) coap_log(LOG_CRIT, "coap_new_pdu: cannot allocate memory for new PDU\n"); #endif return pdu; }
coap_list_t * coap_new_listnode(void *data, void (*delete_func)(void *)) { coap_list_t *node = (coap_list_t *) coap_malloc( sizeof(coap_list_t) ); if (!node) { #ifndef NDEBUG coap_log(LOG_CRIT, "coap_new_listnode: malloc\n"); #endif return NULL; } memset(node, 0, sizeof(coap_list_t)); node->data = data; node->delete_func = delete_func; return node; }
void init_resources(coap_context_t *ctx) { coap_resource_t *r; coap_payload_t *test_payload; test_payload = coap_new_payload(200); if (!test_payload) coap_log(LOG_CRIT, "cannot allocate resource /test"); else { test_payload->length = 13; memcpy(test_payload->data, "put data here", test_payload->length); /* test_payload->media_type is 0 anyway */ r = coap_resource_init((unsigned char *)"test", 4, 0); coap_register_handler(r, COAP_REQUEST_GET, hnd_get_resource); coap_register_handler(r, COAP_REQUEST_POST, hnd_post_test); coap_register_handler(r, COAP_REQUEST_PUT, hnd_put_test); coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_test); coap_add_attr(r, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0); coap_add_attr(r, (unsigned char *)"rt", 2, (unsigned char *)"test", 4, 0); coap_add_attr(r, (unsigned char *)"if", 2, (unsigned char *)"core#b", 6, 0); #if 0 coap_add_attr(r, (unsigned char *)"obs", 3, NULL, 0, 0); #endif coap_add_resource(ctx, r); coap_add_payload(r->key, test_payload, NULL); } /* TD_COAP_BLOCK_01 * TD_COAP_BLOCK_02 */ test_payload = make_large("etsi_iot_01_largedata.txt"); if (!test_payload) coap_log(LOG_CRIT, "cannot allocate resource /large\n"); else { r = coap_resource_init((unsigned char *)"large", 5, 0); coap_register_handler(r, COAP_REQUEST_GET, hnd_get_resource); coap_add_attr(r, (unsigned char *)"ct", 2, (unsigned char *)"41", 2, 0); coap_add_attr(r, (unsigned char *)"rt", 2, (unsigned char *)"large", 5, 0); coap_add_resource(ctx, r); test_payload->flags |= REQUIRE_ETAG; coap_add_payload(r->key, test_payload, NULL); } /* For TD_COAP_CORE_12 */ test_payload = coap_new_payload(20); if (!test_payload) coap_log(LOG_CRIT, "cannot allocate resource /seg1/seg2/seg3\n"); else { test_payload->length = 10; memcpy(test_payload->data, "segsegseg!", test_payload->length); /* test_payload->media_type is 0 anyway */ r = coap_resource_init((unsigned char *)"seg1/seg2/seg3", 14, 0); coap_register_handler(r, COAP_REQUEST_GET, hnd_get_resource); coap_add_attr(r, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0); coap_add_resource(ctx, r); coap_add_payload(r->key, test_payload, NULL); } /* For TD_COAP_CORE_13 */ r = coap_resource_init((unsigned char *)"query", 5, 0); coap_register_handler(r, COAP_REQUEST_GET, hnd_get_query); coap_add_attr(r, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0); coap_add_resource(ctx, r); /* For TD_COAP_CORE_16 */ r = coap_resource_init((unsigned char *)"separate", 8, 0); coap_register_handler(r, COAP_REQUEST_GET, hnd_get_separate); coap_add_attr(r, (unsigned char *)"ct", 2, (unsigned char *)"0", 1, 0); coap_add_attr(r, (unsigned char *)"rt", 2, (unsigned char *)"separate", 8, 0); coap_add_resource(ctx, r); }
void hnd_post_test(coap_context_t *ctx, struct coap_resource_t *resource, coap_address_t *peer, coap_pdu_t *request, str *token, coap_pdu_t *response) { coap_opt_iterator_t opt_iter; coap_opt_t *option; coap_payload_t *test_payload; size_t len; size_t l = 6 + sizeof(void *); coap_dynamic_uri_t *uri; unsigned char *data; #define BUFSIZE 20 int res; unsigned char _buf[BUFSIZE]; unsigned char *buf = _buf; size_t buflen = BUFSIZE; (void)resource; (void)peer; (void)token; coap_get_data(request, &len, &data); /* allocate storage for resource and to hold URI */ test_payload = coap_new_payload(len); uri = (coap_dynamic_uri_t *)coap_malloc(sizeof(coap_dynamic_uri_t) + l); if (!(test_payload && uri)) { coap_log(LOG_CRIT, "cannot allocate new resource under /test"); response->hdr->code = COAP_RESPONSE_CODE(500); coap_free(test_payload); coap_free(uri); } else { coap_resource_t *r; memset(uri, 0, sizeof(coap_dynamic_uri_t)); uri->length = min(l, (size_t)snprintf((char *)uri->data, l, "test/%p", (void*)test_payload)); test_payload->length = len; memcpy(test_payload->data, data, len); r = coap_resource_init(uri->data, uri->length, 0); coap_register_handler(r, COAP_REQUEST_GET, hnd_get_resource); coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_resource); /* set media_type if available */ option = coap_check_option(request, COAP_OPTION_CONTENT_TYPE, &opt_iter); if (option) { test_payload->media_type = coap_decode_var_bytes(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option)); } coap_add_resource(ctx, r); coap_add_payload(r->key, test_payload, uri); /* add Location-Path */ res = coap_split_path(uri->data, uri->length, buf, &buflen); while (res--) { coap_add_option(response, COAP_OPTION_LOCATION_PATH, COAP_OPT_LENGTH(buf), COAP_OPT_VALUE(buf)); buf += COAP_OPT_SIZE(buf); } response->hdr->code = COAP_RESPONSE_CODE(201); } }
coap_async_state_t *coap_register_async(coap_context_t *context, coap_address_t *peer, coap_pdu_t *request, unsigned char flags, void *data) { coap_async_state_t *s; coap_tid_t id; coap_transport_t transport = COAP_UDP; unsigned char *token; unsigned int token_len = 0; switch(context->protocol) { case COAP_PROTO_UDP: case COAP_PROTO_DTLS: transport = COAP_UDP; break; case COAP_PROTO_TCP: case COAP_PROTO_TLS: transport = coap_get_tcp_header_type_from_initbyte(((unsigned char *)request->transport_hdr)[0] >> 4); break; default: break; } coap_transaction_id2(peer, request, &id, context->protocol); LL_SEARCH_SCALAR(context->async_state, s, id, id); coap_get_token2(request->transport_hdr, transport, &token, &token_len); if (token_len > 8) { debug("coap_register_async : invalied length of token\n"); return NULL; } if (s != NULL) { /* We must return NULL here as the caller must know that he is * responsible for releasing @p data. */ debug("coap_register_async : asynchronous state for transaction %d already registered\n", id); return NULL; } /* store information for handling the asynchronous task */ s = (coap_async_state_t *)coap_malloc(sizeof(coap_async_state_t) + token_len); if (!s) { coap_log(LOG_CRIT, "coap_register_async : insufficient memory\n"); return NULL; } memset(s, 0, sizeof(coap_async_state_t) + token_len); /* set COAP_ASYNC_CONFIRM according to request's type */ s->flags = flags & ~COAP_ASYNC_CONFIRM; if (context->protocol == COAP_PROTO_UDP || context->protocol == COAP_PROTO_TCP) { if (request->transport_hdr->udp.type == COAP_MESSAGE_CON) { s->flags |= COAP_ASYNC_CONFIRM; } } s->appdata = data; memcpy(&s->peer, peer, sizeof(coap_address_t)); if (token_len) { s->tokenlen = token_len; memcpy(s->token, token, token_len); } memcpy(&s->id, &id, sizeof(coap_tid_t)); coap_touch_async(s); LL_PREPEND(context->async_state, s); return s; }