Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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), &lt);
    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);
    }
  }
}