void* CoAPWrapper::CreateResource(std::string uri, CoAP_Attr& attr, CoAPResource::method_handler_t& method_handler, CoAPResource *app_context) { coap_resource_t *r; str copy = {0, NULL}; copy.s = (unsigned char*)coap_malloc(uri.length()); copy.length = uri.length(); memcpy(copy.s, uri.c_str(), copy.length); r = coap_resource_init_with_app_context(copy.s, copy.length, COAP_ATTR_FLAGS_RELEASE_NAME, (void*)app_context); if (r == 0 ) { ACE_DEBUG((LM_DEBUG, "Failed to allocate %s resource\n", uri.c_str())); return 0; } coap_register_handler(r, COAP_REQUEST_GET, (coap_method_handler_t)method_handler.handler_get); coap_register_handler(r, COAP_REQUEST_POST, (coap_method_handler_t)method_handler.handler_post); coap_register_handler(r, COAP_REQUEST_PUT, (coap_method_handler_t)method_handler.handler_put); coap_register_handler(r, COAP_REQUEST_DELETE, (coap_method_handler_t)method_handler.handler_delete); CoAP_Attr::iterator e = attr.begin(); for (; e != attr.end(); ++e) { str k = {0, NULL}, v={0, NULL}; std::string key = e->first; std::string value = e->second; k.s = (unsigned char*)coap_malloc(key.length()); k.length = key.length(); v.s = (unsigned char*)coap_malloc(value.length()); v.length = value.length(); memcpy(k.s, key.c_str(), k.length); memcpy(v.s, value.c_str(), v.length); coap_add_attr(r, k.s, k.length, v.s, v.length, COAP_ATTR_FLAGS_RELEASE_NAME); } coap_add_resource(coap_ctx_, r); return r; }
dtls_session_t *_DTLSSession_init() { dtls_session_t *p_dtls_session = NULL; p_dtls_session = coap_malloc(sizeof(dtls_session_t)); mbedtls_debug_set_threshold(0); mbedtls_platform_set_calloc_free(_DTLSCalloc_wrapper, _DTLSFree_wrapper); if (NULL != p_dtls_session) { mbedtls_net_init(&p_dtls_session->fd); mbedtls_ssl_init(&p_dtls_session->context); mbedtls_ssl_config_init(&p_dtls_session->conf); mbedtls_net_init(&p_dtls_session->fd); mbedtls_ssl_cookie_init(&p_dtls_session->cookie_ctx); #ifdef MBEDTLS_X509_CRT_PARSE_C mbedtls_x509_crt_init(&p_dtls_session->cacert); #endif mbedtls_ctr_drbg_init(&p_dtls_session->ctr_drbg); mbedtls_entropy_init(&p_dtls_session->entropy); DTLS_INFO("HAL_DTLSSession_init success\r\n"); } return p_dtls_session; }
rd_t * make_rd(coap_address_t *peer, coap_pdu_t *pdu) { rd_t *rd; unsigned char *data; coap_opt_iterator_t opt_iter; coap_opt_t *etag; rd = rd_new(); if (!rd) { debug("hnd_get_rd: cannot allocate storage for rd\n"); return NULL; } if (coap_get_data(pdu, &rd->data.length, &data)) { rd->data.s = (unsigned char *)coap_malloc(rd->data.length); if (!rd->data.s) { debug("hnd_get_rd: cannot allocate storage for rd->data\n"); rd_delete(rd); return NULL; } memcpy(rd->data.s, data, rd->data.length); } etag = coap_check_option(pdu, COAP_OPTION_ETAG, &opt_iter); if (etag) { rd->etag_len = min(COAP_OPT_LENGTH(etag), sizeof(rd->etag)); memcpy(rd->etag, COAP_OPT_VALUE(etag), rd->etag_len); } return rd; }
inline rd_t * rd_new(void) { rd_t *rd; rd = (rd_t *)coap_malloc(sizeof(rd_t)); if (rd) memset(rd, 0, sizeof(rd_t)); return rd; }
coap_list_t *CACreateNewOptionNode(uint16_t key, uint32_t length, const char *data) { OIC_LOG(DEBUG, TAG, "IN"); if (!data) { OIC_LOG(ERROR, TAG, "invalid pointer parameter"); return NULL; } coap_option *option = coap_malloc(sizeof(coap_option) + length + 1); if (!option) { OIC_LOG(ERROR, TAG, "Out of memory"); return NULL; } memset(option, 0, sizeof(coap_option) + length + 1); COAP_OPTION_KEY(*option) = key; coap_option_def_t* def = coap_opt_def(key); if (NULL != def && coap_is_var_bytes(def)) { if (length > def->max) { // make sure we shrink the value so it fits the coap option definition // by truncating the value, disregard the leading bytes. OIC_LOG_V(DEBUG, TAG, "Option [%d] data size [%d] shrunk to [%d]", def->key, length, def->max); data = &(data[length-def->max]); length = def->max; } // Shrink the encoding length to a minimum size for coap // options that support variable length encoding. COAP_OPTION_LENGTH(*option) = coap_encode_var_bytes( COAP_OPTION_DATA(*option), coap_decode_var_bytes((unsigned char *)data, length)); } else { COAP_OPTION_LENGTH(*option) = length; memcpy(COAP_OPTION_DATA(*option), data, length); } /* we can pass NULL here as delete function since option is released automatically */ coap_list_t *node = coap_new_listnode(option, NULL); if (!node) { OIC_LOG(ERROR, TAG, "node is NULL"); coap_free(option); return NULL; } OIC_LOG(DEBUG, TAG, "OUT"); return node; }
static void *_DTLSCalloc_wrapper(size_t n, size_t s) { void *ptr = NULL; size_t len = n * s; ptr = coap_malloc(len); if (NULL != ptr) { memset(ptr, 0x00, len); } return ptr; }
void add_source_address(struct coap_resource_t *resource, coap_address_t *peer) { #define BUFSIZE 64 char *buf; size_t n = 1; buf = (char *)coap_malloc(BUFSIZE); if (!buf) return; buf[0] = '"'; switch(peer->addr.sa.sa_family) { case AF_INET: /* FIXME */ break; case AF_INET6: n += snprintf(buf + n, BUFSIZE - n, "[%02x%02x:%02x%02x:%02x%02x:%02x%02x" \ ":%02x%02x:%02x%02x:%02x%02x:%02x%02x]", peer->addr.sin6.sin6_addr.s6_addr[0], peer->addr.sin6.sin6_addr.s6_addr[1], peer->addr.sin6.sin6_addr.s6_addr[2], peer->addr.sin6.sin6_addr.s6_addr[3], peer->addr.sin6.sin6_addr.s6_addr[4], peer->addr.sin6.sin6_addr.s6_addr[5], peer->addr.sin6.sin6_addr.s6_addr[6], peer->addr.sin6.sin6_addr.s6_addr[7], peer->addr.sin6.sin6_addr.s6_addr[8], peer->addr.sin6.sin6_addr.s6_addr[9], peer->addr.sin6.sin6_addr.s6_addr[10], peer->addr.sin6.sin6_addr.s6_addr[11], peer->addr.sin6.sin6_addr.s6_addr[12], peer->addr.sin6.sin6_addr.s6_addr[13], peer->addr.sin6.sin6_addr.s6_addr[14], peer->addr.sin6.sin6_addr.s6_addr[15]); if (peer->addr.sin6.sin6_port != htons(COAP_DEFAULT_PORT)) { n += snprintf(buf + n, BUFSIZE - n, ":%d", peer->addr.sin6.sin6_port); } break; default: ; } if (n < BUFSIZE) buf[n++] = '"'; coap_add_attr(resource, (unsigned char *)"A", 1, (unsigned char *)buf, n, COAP_ATTR_FLAGS_RELEASE_VALUE); #undef BUFSIZE }
coap_payload_t * coap_new_payload(size_t size) { coap_payload_t *p; p = (coap_payload_t *)coap_malloc(sizeof(coap_payload_t) + size); if (p) { memset(p, 0, sizeof(coap_payload_t)); p->max_data = size; } return p; }
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_list_t * coap_new_listnode(void *data, void (*delete_func)(void *) ) { coap_list_t *node = coap_malloc( sizeof(coap_list_t) ); if ( ! node ) { perror ("coap_new_listnode: malloc"); return NULL; } memset(node, 0, sizeof(coap_list_t)); node->data = data; node->delete_func = delete_func; return node; }
coap_pdu_t * coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t size) { coap_pdu_t *pdu; #ifdef WITH_LWIP struct pbuf *p; #endif assert(size <= COAP_MAX_PDU_SIZE); /* Size must be large enough to fit the header. */ if (size < sizeof(coap_hdr_t) || size > COAP_MAX_PDU_SIZE) return NULL; /* size must be large enough for hdr */ #ifdef WITH_POSIX pdu = coap_malloc(sizeof(coap_pdu_t) + size); #endif #ifdef WITH_CONTIKI pdu = (coap_pdu_t *)memb_alloc(&pdu_storage); #endif #ifdef WITH_LWIP p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); if (p != NULL) { u8_t header_error = pbuf_header(p, sizeof(coap_pdu_t)); /* we could catch that case and allocate larger memory in advance, but then * again, we'd run into greater trouble with incoming packages anyway */ LWIP_ASSERT("CoAP PDU header does not fit in transport header", header_error == 0); pdu = p->payload; } else { pdu = NULL; } #endif if (pdu) { coap_pdu_clear(pdu, size); pdu->hdr->id = id; pdu->hdr->type = type; pdu->hdr->code = code; #ifdef WITH_LWIP pdu->pbuf = p; #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; }
coap_uri_t * coap_new_uri(const unsigned char *uri, unsigned int length) { unsigned char *result; result = coap_malloc(length + 1 + sizeof(coap_uri_t)); if (!result) return NULL; memcpy(URI_DATA(result), uri, length); URI_DATA(result)[length] = '\0'; /* make it zero-terminated */ if (coap_split_uri(URI_DATA(result), length, (coap_uri_t *)result) < 0) { free(result); return NULL; } return (coap_uri_t *)result; }
coap_subscription_t * coap_new_subscription(coap_context_t *context, const coap_uri_t *resource, const struct sockaddr_in6 *subscriber, time_t expiry) { coap_subscription_t *result; if ( !context || !resource || !subscriber || !(result = coap_malloc(sizeof(coap_subscription_t)))) return NULL; result->resource = coap_uri_hash(resource); result->expires = expiry; memcpy( &result->subscriber, subscriber, sizeof(struct sockaddr_in6) ); memset(&result->token, 0, sizeof(str)); return result; }
coap_uri_t * coap_clone_uri(const coap_uri_t *uri) { coap_uri_t *result; if (!uri) return NULL; result = (coap_uri_t *) coap_malloc( uri->query.length + uri->host.length + uri->path.length + sizeof(coap_uri_t) + 1); if (!result) return NULL; memset(result, 0, sizeof(coap_uri_t)); result->port = uri->port; if (uri->host.length) { result->host.s = URI_DATA(result); result->host.length = uri->host.length; memcpy(result->host.s, uri->host.s, uri->host.length); } if (uri->path.length) { result->path.s = URI_DATA(result) + uri->host.length; result->path.length = uri->path.length; memcpy(result->path.s, uri->path.s, uri->path.length); } if (uri->query.length) { result->query.s = URI_DATA(result) + uri->host.length + uri->path.length; result->query.length = uri->query.length; memcpy(result->query.s, uri->query.s, uri->query.length); } return result; }
static coap_list_t * new_option_node(unsigned short key, unsigned char *data, unsigned int length) { coap_option *option; coap_list_t *node; option = coap_malloc(sizeof(coap_option) + length); if ( !option ) return NULL; COAP_OPTION_KEY(*option) = key; COAP_OPTION_LENGTH(*option) = length; memcpy(COAP_OPTION_DATA(*option), data, length); /* we can pass NULL here as delete function since option is released automatically */ node = coap_new_listnode(option, free); if (!node) coap_free(option); return node; }
coap_list_t* CACreateNewOptionNode(const uint16_t key, const uint32_t length, const uint8_t *data) { coap_option *option; coap_list_t *node; option = coap_malloc(sizeof(coap_option) + length); if (!option) goto error; COAP_OPTION_KEY(*option) = key; COAP_OPTION_LENGTH(*option) = length; memcpy(COAP_OPTION_DATA(*option), data, length); /* we can pass NULL here as delete function since option is released automatically */ node = coap_new_listnode(option, NULL); if (node) return node; error: perror("new_option_node: malloc"); coap_free( option); return NULL; }
/* define generic KTINFO for IPv6 */ #ifdef IPV6_RECVPKTINFO # define GEN_IPV6_PKTINFO IPV6_RECVPKTINFO #elif defined(IPV6_PKTINFO) # define GEN_IPV6_PKTINFO IPV6_PKTINFO #else # error "Need IPV6_PKTINFO or IPV6_RECVPKTINFO to request ancillary data from OS." #endif /* IPV6_RECVPKTINFO */ struct coap_packet_t { coap_if_handle_t hnd; /**< the interface handle */ coap_address_t src; /**< the packet's source address */ coap_address_t dst; /**< the packet's destination address */ const coap_endpoint_t *interface; int ifindex; void *session; /**< opaque session data */ size_t length; /**< length of payload */ unsigned char payload[]; /**< payload */ }; #endif #ifndef CUSTOM_COAP_NETWORK_ENDPOINT #ifdef WITH_CONTIKI static int ep_initialized = 0; static inline struct coap_endpoint_t * coap_malloc_contiki_endpoint() { static struct coap_endpoint_t ep; if (ep_initialized) { return NULL; } else { ep_initialized = 1; return &ep; } } static inline void coap_free_contiki_endpoint(struct coap_endpoint_t *ep) { ep_initialized = 0; } coap_endpoint_t * coap_new_endpoint(const coap_address_t *addr, int flags) { struct coap_endpoint_t *ep = coap_malloc_contiki_endpoint(); if (ep) { memset(ep, 0, sizeof(struct coap_endpoint_t)); ep->handle.conn = udp_new(NULL, 0, NULL); if (!ep->handle.conn) { coap_free_endpoint(ep); return NULL; } coap_address_init(&ep->addr); uip_ipaddr_copy(&ep->addr.addr, &addr->addr); ep->addr.port = addr->port; udp_bind((struct uip_udp_conn *)ep->handle.conn, addr->port); } return ep; } void coap_free_endpoint(coap_endpoint_t *ep) { if (ep) { if (ep->handle.conn) { uip_udp_remove((struct uip_udp_conn *)ep->handle.conn); } coap_free_contiki_endpoint(ep); } } #else /* WITH_CONTIKI */ static inline struct coap_endpoint_t * coap_malloc_posix_endpoint(void) { return (struct coap_endpoint_t *)coap_malloc(sizeof(struct coap_endpoint_t)); }
coap_pdu_t * coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t size, coap_transport_type transport) { coap_pdu_t *pdu; #ifdef WITH_LWIP struct pbuf *p; #endif unsigned int length = 0; switch(transport) { case coap_udp: length = sizeof(pdu->hdr->coap_hdr_udp_t); break; #ifdef WITH_TCP case coap_tcp: length = COAP_TCP_HEADER_NO_FIELD; break; case coap_tcp_8bit: length = COAP_TCP_HEADER_8_BIT; break; case coap_tcp_16bit: length = COAP_TCP_HEADER_16_BIT; break; case coap_tcp_32bit: length = COAP_TCP_HEADER_32_BIT; break; #endif default: debug("it has wrong type\n"); } #ifndef WITH_TCP assert(size <= COAP_MAX_PDU_SIZE); /* Size must be large enough to fit the header. */ if (size < length || size > COAP_MAX_PDU_SIZE) return NULL; #endif /* size must be large enough for hdr */ #if defined(WITH_POSIX) || defined(WITH_ARDUINO) pdu = (coap_pdu_t *) coap_malloc(sizeof(coap_pdu_t) + size); #endif #ifdef WITH_CONTIKI pdu = (coap_pdu_t *)memb_alloc(&pdu_storage); #endif #ifdef WITH_LWIP p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); if (p != NULL) { u8_t header_error = pbuf_header(p, sizeof(coap_pdu_t)); /* we could catch that case and allocate larger memory in advance, but then * again, we'd run into greater trouble with incoming packages anyway */ LWIP_ASSERT("CoAP PDU header does not fit in transport header", header_error == 0); pdu = p->payload; } else { pdu = NULL; } #endif if (pdu) { coap_pdu_clear(pdu, size, transport, length); switch(transport) { case coap_udp: pdu->hdr->coap_hdr_udp_t.id = id; pdu->hdr->coap_hdr_udp_t.type = type; pdu->hdr->coap_hdr_udp_t.code = code; break; #ifdef WITH_TCP case coap_tcp: pdu->hdr->coap_hdr_tcp_t.header_data[0] = 0; pdu->hdr->coap_hdr_tcp_t.header_data[1] = code; break; case coap_tcp_8bit: pdu->hdr->coap_hdr_tcp_8bit_t.header_data[0] = COAP_TCP_LENGTH_FIELD_NUM_8_BIT << 4; pdu->hdr->coap_hdr_tcp_8bit_t.header_data[2] = code; break; case coap_tcp_16bit: pdu->hdr->coap_hdr_tcp_16bit_t.header_data[0] = COAP_TCP_LENGTH_FIELD_NUM_16_BIT << 4; pdu->hdr->coap_hdr_tcp_16bit_t.header_data[3] = code; break; case coap_tcp_32bit: pdu->hdr->coap_hdr_tcp_32bit_t.header_data[0] = COAP_TCP_LENGTH_FIELD_NUM_32_BIT << 4; pdu->hdr->coap_hdr_tcp_32bit_t.header_data[5] = code; break; #endif default: debug("it has wrong type\n"); } #ifdef WITH_LWIP pdu->pbuf = p; #endif } return pdu; }
void hnd_put_resource(coap_context_t *ctx, struct coap_resource_t *resource, const coap_endpoint_t *local_interface, coap_address_t *peer, coap_pdu_t *request, str *token, coap_pdu_t *response) { #if 1 response->hdr->code = COAP_RESPONSE_CODE(501); #else /* FIXME */ coap_opt_iterator_t opt_iter; coap_opt_t *token, *etag; coap_pdu_t *response; size_t size = sizeof(coap_hdr_t); int type = (request->hdr->type == COAP_MESSAGE_CON) ? COAP_MESSAGE_ACK : COAP_MESSAGE_NON; rd_t *rd = NULL; unsigned char code; /* result code */ unsigned char *data; str tmp; HASH_FIND(hh, resources, resource->key, sizeof(coap_key_t), rd); if (rd) { /* found resource object, now check Etag */ etag = coap_check_option(request, COAP_OPTION_ETAG, &opt_iter); if (!etag || (COAP_OPT_LENGTH(etag) != rd->etag_len) || memcmp(COAP_OPT_VALUE(etag), rd->etag, rd->etag_len) != 0) { if (coap_get_data(request, &tmp.length, &data)) { tmp.s = (unsigned char *)coap_malloc(tmp.length); if (!tmp.s) { debug("hnd_put_rd: cannot allocate storage for new rd\n"); code = COAP_RESPONSE_CODE(503); goto finish; } coap_free(rd->data.s); rd->data.s = tmp.s; rd->data.length = tmp.length; memcpy(rd->data.s, data, rd->data.length); } } if (etag) { rd->etag_len = min(COAP_OPT_LENGTH(etag), sizeof(rd->etag)); memcpy(rd->etag, COAP_OPT_VALUE(etag), rd->etag_len); } code = COAP_RESPONSE_CODE(204); /* FIXME: update lifetime */ } else { code = COAP_RESPONSE_CODE(503); } finish: /* FIXME: do not create a new response but use the old one instead */ response = coap_pdu_init(type, code, request->hdr->id, size); if (!response) { debug("cannot create response for message %d\n", request->hdr->id); return; } if (request->hdr->token_length) coap_add_token(response, request->hdr->token_length, request->hdr->token); if (coap_send(ctx, peer, response) == COAP_INVALID_TID) { debug("hnd_get_rd: cannot send response for message %d\n", request->hdr->id); } coap_delete_pdu(response); #endif }
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); } }
void hnd_post_rd(coap_context_t *ctx, struct coap_resource_t *resource, const coap_endpoint_t *local_interface, coap_address_t *peer, coap_pdu_t *request, str *token, coap_pdu_t *response) { size_t len=0; unsigned char *databuf; unsigned char strBuf[100]; unsigned char s[100]; coap_print_addr(peer, s, 100); if (coap_get_data(request, &len, &databuf)){ memcpy(strBuf, databuf, len); strBuf[len]='\0'; fprintf(stdout, "%s %s\n", s, strBuf); }else{ fprintf(stdout, "%s\n", s); } fflush(stdout); coap_resource_t *r; coap_opt_iterator_t opt_iter; coap_opt_t *query; #define LOCSIZE 68 unsigned char *loc; size_t loc_size; str h = {0, NULL}, ins = {0, NULL}, rt = {0, NULL}, lt = {0, NULL}; /* store query parameters */ unsigned char *buf; loc = (unsigned char *)coap_malloc(LOCSIZE); if (!loc) { response->hdr->code = COAP_RESPONSE_CODE(500); return; } memcpy(loc, RD_ROOT_STR, RD_ROOT_SIZE); loc_size = RD_ROOT_SIZE; loc[loc_size++] = '/'; /* store query parameters for later use */ query = coap_check_option(request, COAP_OPTION_URI_QUERY, &opt_iter); if (query) { parse_param((unsigned char *)"h", 1, COAP_OPT_VALUE(query), COAP_OPT_LENGTH(query), &h); parse_param((unsigned char *)"ins", 3, COAP_OPT_VALUE(query), COAP_OPT_LENGTH(query), &ins); parse_param((unsigned char *)"lt", 2, COAP_OPT_VALUE(query), COAP_OPT_LENGTH(query), <); parse_param((unsigned char *)"rt", 2, COAP_OPT_VALUE(query), COAP_OPT_LENGTH(query), &rt); } if (h.length) { /* client has specified a node name */ memcpy(loc + loc_size, h.s, min(h.length, LOCSIZE - loc_size - 1)); loc_size += min(h.length, LOCSIZE - loc_size - 1); if (ins.length && loc_size > 1) { loc[loc_size++] = '-'; memcpy((char *)(loc + loc_size), ins.s, min(ins.length, LOCSIZE - loc_size - 1)); loc_size += min(ins.length, LOCSIZE - loc_size - 1); } } else { /* generate node identifier */ loc_size += snprintf((char *)(loc + loc_size), LOCSIZE - loc_size - 1, "%x", request->hdr->id); if (loc_size > 1) { if (ins.length) { loc[loc_size++] = '-'; memcpy((char *)(loc + loc_size), ins.s, min(ins.length, LOCSIZE - loc_size - 1)); loc_size += min(ins.length, LOCSIZE - loc_size - 1); } else { coap_tick_t now; coap_ticks(&now); loc_size += snprintf((char *)(loc + loc_size), LOCSIZE - loc_size - 1, "-%x", now); } } } /* TODO: * - use lt to check expiration */ r = coap_resource_init(loc, loc_size, COAP_RESOURCE_FLAGS_RELEASE_URI); coap_register_handler(r, COAP_REQUEST_GET, hnd_get_resource); coap_register_handler(r, COAP_REQUEST_PUT, hnd_put_resource); coap_register_handler(r, COAP_REQUEST_DELETE, hnd_delete_resource); if (ins.s) { buf = (unsigned char *)coap_malloc(ins.length + 2); if (buf) { /* add missing quotes */ buf[0] = '"'; memcpy(buf + 1, ins.s, ins.length); buf[ins.length + 1] = '"'; coap_add_attr(r, (unsigned char *)"ins", 3, buf, ins.length + 2, COAP_ATTR_FLAGS_RELEASE_VALUE); } } if (rt.s) { buf = (unsigned char *)coap_malloc(rt.length + 2); if (buf) { /* add missing quotes */ buf[0] = '"'; memcpy(buf + 1, rt.s, rt.length); buf[rt.length + 1] = '"'; coap_add_attr(r, (unsigned char *)"rt", 2, buf, rt.length + 2, COAP_ATTR_FLAGS_RELEASE_VALUE); } } add_source_address(r, peer); { rd_t *rd; rd = make_rd(peer, request); if (rd) { coap_hash_path(loc, loc_size, rd->key); HASH_ADD(hh, resources, key, sizeof(coap_key_t), rd); } else { /* FIXME: send error response and delete r */ } } coap_add_resource(ctx, r); /* create response */ response->hdr->code = COAP_RESPONSE_CODE(201); { /* split path into segments and add Location-Path options */ unsigned char _b[LOCSIZE]; unsigned char *b = _b; size_t buflen = sizeof(_b); int nseg; nseg = coap_split_path(loc, loc_size, b, &buflen); while (nseg--) { coap_add_option(response, COAP_OPTION_LOCATION_PATH, COAP_OPT_LENGTH(b), COAP_OPT_VALUE(b)); b += COAP_OPT_SIZE(b); } } }
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; }