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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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);
  }

}
Esempio n. 10
0
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;
}