Пример #1
0
/*---------------------------------------------------------------------------*/
uint8_t
sprint_ip6addr(struct in6_addr addr, char * result)
{
    unsigned char i = 0;
    unsigned char zerocnt = 0;
    unsigned char numprinted = 0;
    char * starting = result;

    *result++='[';
    while (numprinted < 8) {
        if ((addr.s6_addr16[i] == 0) && (zerocnt == 0)) {
            while(addr.s6_addr16[zerocnt + i] == 0) zerocnt++;
            if (zerocnt == 1) {
                *result++ = '0';
                numprinted++;
                break;
            }
            i += zerocnt;
            numprinted += zerocnt;
        } else {
            result += sprintf(result, "%x", (unsigned int) uip_ntohs(addr.s6_addr16[i]));
            i++;
            numprinted++;
        }
        if (numprinted != 8) *result++ = ':';
    }
    *result++=']';
    *result=0;
    return (result - starting);
}
Пример #2
0
/*---------------------------------------------------------------------------*/
void
sprint_ip6(uip_ip6addr_t addr)
{
  unsigned char i = 0;
  unsigned char zerocnt = 0;
  unsigned char numprinted = 0;
  char thestring[40];
  char * result = thestring;

  *result++='[';
  while (numprinted < 8) {
    if ((addr.u16[i] == 0) && (zerocnt == 0)) {
      while(addr.u16[zerocnt + i] == 0) zerocnt++;
      if (zerocnt == 1) {
        *result++ = '0';
         numprinted++;
         break;
      }
      i += zerocnt;
      numprinted += zerocnt;
    } else {
      result += sprintf(result, "%x", (unsigned int)(uip_ntohs(addr.u16[i])));
      i++;
      numprinted++;
    }
    if (numprinted != 8) *result++ = ':';
  }
  *result++=']';
  *result=0;
  printf("%s",thestring);
}
Пример #3
0
void
init_dtls(session_t *dst) {
  PRINTF("DTLS client started\n");

  print_local_addresses();

  dst->size = sizeof(dst->addr) + sizeof(dst->port);
  dst->port = UIP_HTONS(20220);

  set_connection_address(&dst->addr);
  client_conn = udp_new(&dst->addr, 0, NULL);
  udp_bind(client_conn, dst->port);

  PRINTF("set connection address to ");
  PRINT6ADDR(&dst->addr);
  PRINTF(":%d\n", uip_ntohs(dst->port));

  set_log_level(LOG_DEBUG);

  dtls_context = dtls_new_context(client_conn);
  if (dtls_context) {
    dtls_set_psk(dtls_context, (unsigned char *)"secretPSK", 9,
		 (unsigned char *)"Client_identity", 15);
		 
    dtls_set_cb(dtls_context, read_from_peer, read);
    dtls_set_cb(dtls_context, send_to_peer, write);
  }
}
Пример #4
0
uint8_t
httpd_sprint_ip6(const uip_ip6addr_t *addr, char *result)
{
  unsigned char i = 0;
  unsigned char zerocnt = 0;
  unsigned char numprinted = 0;
  char *starting = result;

  *result++ = '[';
  while(numprinted < 8) {
    if((addr->u16[i] == 0) && (zerocnt == 0)) {
      while(addr->u16[zerocnt + i] == 0) {
	zerocnt++;
      }
      if(zerocnt == 1) {
        *result++ = '0';
         numprinted++;
         break;
      }
      i += zerocnt;
      numprinted += zerocnt;
    } else {
      result += sprintf(result, "%x", (unsigned int)(uip_ntohs(addr->u16[i])));
      i++;
      numprinted++;
    }
    if(numprinted != 8) {
      *result++ = ':';
    }
  }
  *result++ = ']';
  *result = 0;
  return (result - starting);
}
Пример #5
0
void
init_dtls(session_t *dst) {
  static dtls_handler_t cb = {
    .write = send_to_peer,
    .read  = read_from_peer,
    .event = NULL,
    .get_key = get_key
  };
  PRINTF("DTLS client started\n");

  print_local_addresses();

  dst->size = sizeof(dst->addr) + sizeof(dst->port);
  dst->port = UIP_HTONS(20220);

  set_connection_address(&dst->addr);
  client_conn = udp_new(&dst->addr, 0, NULL);
  udp_bind(client_conn, dst->port);

  PRINTF("set connection address to ");
  PRINT6ADDR(&dst->addr);
  PRINTF(":%d\n", uip_ntohs(dst->port));

  set_log_level(LOG_DEBUG);

  dtls_context = dtls_new_context(client_conn);
  if (dtls_context)
    dtls_set_handler(dtls_context, &cb);
}
Пример #6
0
static void tcpdump(uint8_t *pkt, uint16_t len) {
	char prt[41];

	if (((struct uip_eth_hdr *)pkt)->type == UIP_HTONS(UIP_ETHTYPE_IP)) {
		tcpdump_format(pkt + 14, len - 14, prt, sizeof(prt));
		printf_P(PSTR("%s\n"), prt);
	}
	else if (((struct uip_eth_hdr *)pkt)->type == UIP_HTONS(UIP_ETHTYPE_ARP)) {
		printf_P(PSTR("ARP\n"));
	}
	else {
		printf_P(PSTR("Ethertype: %04x\n"),
			uip_ntohs(((struct uip_eth_hdr *)pkt)->type));
	}

#if TCPDUMP_RAWPKT
	for (uint8_t i = 0; i < 64; i++) {
		if (i >= len) {
			printf_P(PSTR("**"));
			break;
		}
		printf("%02x ", *(pkt + i));
		if ((i > 0) && !((i + 1) % 4)) {
			printf_P(PSTR(" "));
		}
	}
	printf("\n");
#endif
}
Пример #7
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;
}
Пример #8
0
void network_handler(ev, data){
	char buf[UIP_BUFSIZE]; // packet data buffer
	unsigned short cmd;    // 
	DataPayload *dp;
	ChannelState *state = NULL;
	uint16_t len = uip_datalen();
	PRINTF("ipaddr=%d.%d.%d.%d\n", uip_ipaddr_to_quad(&(UDP_HDR->srcipaddr)));
	PRINTF("Packet is %d bytes long\n",len);


	memcpy(buf, uip_appdata, len);
	buf[len] = '\0';

	dp = (DataPayload *)buf;
	PRINTF("Data is   %d bytes long\n",uip_ntohs(dp->dhdr.tlen));
	cmd = dp->hdr.cmd;        // only a byte so no reordering :)
	PRINTF("Received a %s command.\n", cmdnames[cmd]);
	PRINTF("Message for channel %d\n",dp->hdr.dst_chan_num);
	if (dp->hdr.dst_chan_num == HOMECHANNEL || cmd == DISCONNECT){
		if (cmd == QACK){
			state = &home_channel_state;
			copy_link_address(state);
  		}
  		else if (cmd == DISCONNECT){
  			state = get_channel_state(dp->hdr.dst_chan_num);
			if (state){
				remove_channel(state->chan_num);
			}
			state = &home_channel_state;
			copy_link_address(state);
  		}
  	}
	else{
		
		state = get_channel_state(dp->hdr.dst_chan_num);
		if (state == NULL){
			PRINTF("Channel %d doesn't exist\n", dp->hdr.dst_chan_num);
			return;
		}
		if (check_seqno(state, dp) == 0) {
			printf("OH NOES\n");
			return;
		}else { //CHECK IF RIGHT CONNECTION
			//copy_link_address(state);
		}
	}
	
	// Received a message so reset pingOUT
	state->pingOUT = 0;
	if      (cmd == QUERY)    PRINTF("I'm a controller, Ignoring QUERY\n");
	else if (cmd == CONNECT)  PRINTF("I'm a controller, Ignoring CONNECT\n");
	else if (cmd == QACK)     qack_handler(state, dp);
	else if (cmd == CACK)     cack_handler(state, dp);
	else if (cmd == RESPONSE) response_handler(state, dp);
	else if (cmd == CMDACK)   command_ack_handler(state,dp);
	else if (cmd == PING)     ping_handler(state, dp);
	else if (cmd == PACK)     pack_handler(state, dp);
	else if (cmd == DISCONNECT) close_handler(state,dp);
}
Пример #9
0
/*---------------------------------------------------------------------------*/
static int prepare_and_send_buf(coap_context_t *ctx, session_t *session,
				uint8_t *data, size_t len)
{
  struct net_buf *buf;
  int max_data_len;

  /* This net_buf gets sent to network, so it is not released
   * by this function unless there was an error and buf was
   * not actually sent.
   */
  buf = ip_buf_get_tx(ctx->net_ctx);
  if (!buf) {
    len = -ENOBUFS;
    goto out;
  }

  max_data_len = IP_BUF_MAX_DATA - UIP_IPUDPH_LEN;

  PRINTF("%s: reply to peer data %p len %d\n", __FUNCTION__, data, len);

  if (len > max_data_len) {
    PRINTF("%s: too much (%d bytes) data to send (max %d bytes)\n",
	  __FUNCTION__, len, max_data_len);
    ip_buf_unref(buf);
    len = -EINVAL;
    goto out;
  }

  /* Note that we have reversed the addresses here
   * because net_reply() will reverse them again.
   */
#ifdef CONFIG_NETWORKING_WITH_IPV6
  uip_ip6addr_copy(&NET_BUF_IP(buf)->destipaddr, (uip_ip6addr_t *)&ctx->my_addr.in6_addr);
  uip_ip6addr_copy(&NET_BUF_IP(buf)->srcipaddr,
		   (uip_ip6addr_t *)&session->addr.ipaddr);
#else
  uip_ip4addr_copy(&NET_BUF_IP(buf)->destipaddr,
		   (uip_ip4addr_t *)&ctx->my_addr.in_addr);
  uip_ip4addr_copy(&NET_BUF_IP(buf)->srcipaddr,
		   (uip_ip4addr_t *)&session->addr.ipaddr);
#endif
  NET_BUF_UDP(buf)->destport = uip_ntohs(ctx->my_port);
  NET_BUF_UDP(buf)->srcport = session->addr.port;

  uip_set_udp_conn(buf) = net_context_get_udp_connection(ctx->net_ctx);

  memcpy(net_buf_add(buf, len), data, len);
  ip_buf_appdatalen(buf) = len;
  ip_buf_appdata(buf) = buf->data + ip_buf_reserve(buf);

  if (net_reply(ctx->net_ctx, buf)) {
    ip_buf_unref(buf);
  }
out:
  return len;
}
Пример #10
0
int
get_key(struct dtls_context_t *ctx, 
	const session_t *session, 
	const unsigned char *id, size_t id_len, 
	const dtls_key_t **result) {

  static const dtls_key_t psk = {
    .type = DTLS_KEY_PSK,
    .key.psk.id = (unsigned char *)"Client_identity", 
    .key.psk.id_length = 15,
    .key.psk.key = (unsigned char *)"secretPSK", 
    .key.psk.key_length = 9
  };
   
  *result = &psk;
  return 0;
}

PROCESS(udp_server_process, "UDP server process");
AUTOSTART_PROCESSES(&udp_server_process);
/*---------------------------------------------------------------------------*/
static void
dtls_handle_read(dtls_context_t *ctx) {
  static session_t session;

  if(uip_newdata()) {
    uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr);
    session.port = UIP_UDP_BUF->srcport;
    session.size = sizeof(session.addr) + sizeof(session.port);

    ((char *)uip_appdata)[uip_datalen()] = 0;
    PRINTF("Client received message from ");
    PRINT6ADDR(&session.addr);
    PRINTF(":%d\n", uip_ntohs(session.port));

    dtls_handle_message(ctx, &session, uip_appdata, uip_datalen());
  }
}
/*---------------------------------------------------------------------------*/
static void
print_local_addresses(void)
{
  int i;
  uint8_t state;

  PRINTF("Client IPv6 addresses: ");
  for(i = 0; i < UIP_DS6_ADDR_NB; i++) {
    state = uip_ds6_if.addr_list[i].state;
    if(uip_ds6_if.addr_list[i].isused &&
       (state == ADDR_TENTATIVE || state == ADDR_PREFERRED)) {
      PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);
      PRINTF("\n");
    }
  }
}
Пример #11
0
void response_handler(ChannelState *state, DataPayload *dp){
	if (state->state != STATE_CONNECTED && state->state != STATE_PING){
		PRINTF("Not connected to device!\n");
		return;
	}
	state->ticks = 100;
	ResponseMsg *rmsg = (ResponseMsg *)dp->data;
	PRINTF("%s %d\n", rmsg->name, uip_ntohs(rmsg->data));
	/*RESET PING TIMER*/
	ctimer_restart(&(state->timer));
	process_post_synch(state->ccb.client_process, KNOT_EVENT_DATA_READY, rmsg);
}
Пример #12
0
/*---------------------------------------------------------------------------*/
void
ip64_dhcpc_configured(const struct ip64_dhcpc_state *s)
{
  uip_ip6addr_t ip6dnsaddr;
  PRINTF("DHCP Configured with %d.%d.%d.%d\n",
	 s->ipaddr.u8[0], s->ipaddr.u8[1],
	 s->ipaddr.u8[2], s->ipaddr.u8[3]);

  ip64_set_hostaddr((uip_ip4addr_t *)&s->ipaddr);
  ip64_set_netmask((uip_ip4addr_t *)&s->netmask);
  ip64_set_draddr((uip_ip4addr_t *)&s->default_router);
  if(!uip_ip4addr_cmp((uip_ip4addr_t *)&s->dnsaddr, &uip_all_zeroes_addr)) {
    //Note: Currently we assume only one DNS server
    uip_ipaddr_t * dns = uip_nameserver_get(0);
    //Only update DNS entry if it is empty or already IPv4
    if(uip_is_addr_unspecified(dns) || ip64_addr_is_ip64(dns)) {
      ip64_addr_4to6((uip_ip4addr_t *)&s->dnsaddr, &ip6dnsaddr);
      uip_nameserver_update(&ip6dnsaddr, uip_ntohs(s->lease_time[0])*65536ul + uip_ntohs(s->lease_time[1]));
    }
  }
#if CETIC_6LBR
  cetic_6lbr_ip64_dhcpc_configured(s);
#endif
}
Пример #13
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;
}
Пример #14
0
void callback(void * data){
	ResponseMsg * r = data;
	int value = uip_ntohs((int)r->data);
	printf(">>APP: %s sensor = %d\n", r->name, value);
	if (actuator == 0) return; //NO actuator connected
	if (value > 75  && lighton){
		printf("It's too bright - Turning off light\n");
		command_actuator(&actuator);
		lighton = 0;
	} else if (value <75 && !lighton){
		printf("It's too dark - Turning on light\n");
		command_actuator(&actuator);
		lighton = 1;
	}

}
Пример #15
0
/*---------------------------------------------------------------------------*/
uint8_t httpd_cgi_sprint_ip6(uip_ip6addr_t addr, char * result)
{
    unsigned char zerocnt = 0;
    unsigned char numprinted = 0;
    char * starting = result;
    unsigned char i = 0;
        while (numprinted < 8)
                {
                //Address is zero, have we used our ability to
                //replace a bunch with : yet?
                if ((addr.u16[i] == 0) && (zerocnt == 0))
                        {
                        //How mant zeros?
                        zerocnt = 0;
                        while(addr.u16[zerocnt + i] == 0)
                                zerocnt++;

                        //just one, don't waste our zeros...
                        if (zerocnt == 1)
                                {
                                *result++ = '0';
                                numprinted++;
                                break;
                                }

                        //Cool - can replace a bunch of zeros
                        i += zerocnt;
                        numprinted += zerocnt;
                        //all zeroes ?
                       if (zerocnt > 7) {*result++ = ':';*result++ = ':';}
                        }
                //Normal address, just print it
                else
                        {
                        result += sprintf(result, "%x", (unsigned int)(uip_ntohs(addr.u16[i])));
                        i++;
                        numprinted++;
                        }

                //Don't print : on last one
                if (numprinted != 8)
                        *result++ = ':';
                }

			return (result - starting);
        }
Пример #16
0
/*---------------------------------------------------------------------------*/
static void
dtls_handle_read(dtls_context_t *ctx) {
  static session_t session;

  if(uip_newdata()) {
    uip_ipaddr_copy(&session.addr, &UIP_IP_BUF->srcipaddr);
    session.port = UIP_UDP_BUF->srcport;
    session.size = sizeof(session.addr) + sizeof(session.port);

    ((char *)uip_appdata)[uip_datalen()] = 0;
    PRINTF("Client received message from ");
    PRINT6ADDR(&session.addr);
    PRINTF(":%d\n", uip_ntohs(session.port));

    dtls_handle_message(ctx, &session, uip_appdata, uip_datalen());
  }
}
Пример #17
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(ledsUDPServer_process, ev, data)
{
  static struct uip_udp_conn *localconn;

  PROCESS_BEGIN();

  /* Create a local connection structure :
   *  - Remote IP: 0.0.0.0 (all accepted).
   *  - Remote port: 0 (all accepted).
   */
  localconn = udp_new(&uip_all_zeroes_addr, 0, NULL);
  /* Bind to the local port. */
  udp_bind(localconn,uip_htons(local_port));
  PRINTF("I listen the UDP port %u\n",uip_ntohs(localconn->lport));
  while (1)
  {
    PRINTF("I wait a new request\n");
    PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event);
    /* Here, a new TCP/IP event occurred ! */
    /* A good packet is :
     *  - With data.
     *  - With at least "preambleSize + 1" bytes.
     *  - Packet start with the good preamble.
     */
    if(uip_newdata() &&
       uip_datalen() >= (preambleSize + 1) &&
       !strncmp(uip_appdata,preamble,preambleSize))
    {
      PRINTF("I received a LED toggling request.\n");
      {
        char *data = (char *)uip_appdata;
        int led = 0;
        switch (data[4]) {
          case '1': led = LEDS_BLUE;  break;
          case '2': led = LEDS_GREEN; break;
          case '3': led = LEDS_RED;   break;
          default : PRINTF("I can't find the good LED...\n"); continue;
        }
        leds_toggle(led);
      }
    }
  }

  PROCESS_END();
}
Пример #18
0
/*---------------------------------------------------------------------------*/
static void
multicast_send(void)
{
  uint32_t id;

  id = uip_htonl(seq_id);
  memset(buf, 0, MAX_PAYLOAD_LEN);
  memcpy(buf, &id, sizeof(seq_id));

  PRINTF("Send to: ");
  PRINT6ADDR(&mcast_conn->ripaddr);
  PRINTF(" Remote Port %u,", uip_ntohs(mcast_conn->rport));
  PRINTF(" (msg=0x%08lx)", (unsigned long)uip_ntohl(*((uint32_t *)buf)));
  PRINTF(" %lu bytes\n", (unsigned long)sizeof(id));

  seq_id++;
  uip_udp_packet_send(mcast_conn, buf, sizeof(id));
}
Пример #19
0
/*---------------------------------------------------------------------------*/
int
coap_context_connect(coap_context_t *coap_ctx, uip_ipaddr_t *addr, uint16_t port)
{
  session_t session;

  if(coap_ctx == NULL || coap_ctx->is_used == 0) {
    return 0;
  }

#ifdef NETSTACK_CONF_WITH_IPV6
  memcpy(&coap_ctx->addr.in6_addr, addr, sizeof(coap_ctx->addr.in6_addr));
  coap_ctx->addr.family = AF_INET6;
#else
  memcpy(&coap_ctx->addr.in_addr, addr, sizeof(coap_ctx->addr.in_addr));
  coap_ctx->addr.family = AF_INET;
#endif
  coap_ctx->port = port;

  coap_ctx->net_ctx = net_context_get(IPPROTO_UDP,
				      (const struct net_addr *)&coap_ctx->addr,
				      coap_ctx->port,
				      (const struct net_addr *)&coap_ctx->my_addr,
				      coap_ctx->my_port);
  if (!coap_ctx->net_ctx) {
    PRINTF("%s: Cannot get network context\n", __FUNCTION__);
    return 0;
  }

  uip_ipaddr_copy(&session.addr.ipaddr, addr);
  session.addr.port = UIP_HTONS(port);
  session.size = sizeof(session.addr);
  session.ifindex = 1;
  coap_ctx->status = STATUS_CONNECTING;
  PRINTF("coap-context: DTLS CONNECT TO [");
  PRINT6ADDR(addr);
  PRINTF("]:%u\n", uip_ntohs(port));
  if(dtls_connect(coap_ctx->dtls_context, &session) >= 0) {
    return 1;
  }

  /* Failed to initiate connection */
  coap_ctx->status = STATUS_ALERT;
  return 0;
}
Пример #20
0
void service_search(ChannelState* state, uint8_t type){

	DataPayload *new_dp = &(state->packet);
	clean_packet(new_dp);
	//dp_complete(new_dp,10,QACK,1);
	set_broadcast(&(home_channel_state.remote_addr));
	new_dp->hdr.src_chan_num = state->chan_num;
	new_dp->hdr.dst_chan_num = 0;
    (new_dp)->hdr.cmd = QUERY; 
    (new_dp)->dhdr.tlen = uip_htons(sizeof(QueryMsg));
    PRINTF("%d\n", uip_ntohs((new_dp)->dhdr.tlen));
    QueryMsg *q = (QueryMsg *) new_dp->data;
   
    q->type = type;
    strcpy(q->name, controller_name);
	knot_broadcast(state,new_dp);
	state->state = STATE_QUERY;
	state->ticks = 100;
}
Пример #21
0
static int
send_to_peer(struct dtls_context_t *ctx, 
	     session_t *session, uint8 *data, size_t len) {

  struct uip_udp_conn *conn = (struct uip_udp_conn *)dtls_get_app_data(ctx);

  uip_ipaddr_copy(&conn->ripaddr, &session->addr);
  conn->rport = session->port;

  PRINTF("send to ");
  PRINT6ADDR(&conn->ripaddr);
  PRINTF(":%u\n", uip_ntohs(conn->rport));

  uip_udp_packet_send(conn, data, len);

  /* Restore server connection to allow data from any node */
  memset(&conn->ripaddr, 0, sizeof(conn->ripaddr));
  memset(&conn->rport, 0, sizeof(conn->rport));

  return len;
}
Пример #22
0
/*---------------------------------------------------------------------------*/
int coap_context_wait_data(coap_context_t *coap_ctx, int32_t ticks)
{
  struct net_buf *buf;

  buf = net_receive(coap_ctx->net_ctx, ticks);
  if (buf) {
    session_t session;
    int ret;

    uip_ipaddr_copy(&session.addr.ipaddr, &UIP_IP_BUF(buf)->srcipaddr);
    session.addr.port = UIP_UDP_BUF(buf)->srcport;
    session.size = sizeof(session.addr);
    session.ifindex = 1;

    PRINTF("coap-context: got dtls message from ");
    PRINT6ADDR(&session.addr.ipaddr);
    PRINTF(":%d %u bytes\n", uip_ntohs(session.addr.port), uip_appdatalen(buf));

    PRINTF("Received appdata %p appdatalen %d\n",
	   ip_buf_appdata(buf), ip_buf_appdatalen(buf));

    coap_ctx->buf = buf;

    ret = dtls_handle_message(coap_ctx->dtls_context, &session,
			      ip_buf_appdata(buf), ip_buf_appdatalen(buf));

    /* We always release the buffer here as this buffer is never sent
     * to network anyway.
     */
    if (coap_ctx->buf) {
      ip_buf_unref(coap_ctx->buf);
      coap_ctx->buf = NULL;
    }

    return ret;
  }

  return 0;
}
Пример #23
0
/*---------------------------------------------------------------------------*/
int coap_context_wait_data(coap_context_t *coap_ctx, int32_t ticks)
{
  struct net_buf *buf;

  buf = net_receive(coap_ctx->net_ctx, ticks);
  if (buf) {
    PRINTF("coap-context: got message from ");
    PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr);
    PRINTF(":%d %u bytes\n", uip_ntohs(UIP_UDP_BUF(buf)->srcport),
	   uip_appdatalen(buf));

    PRINTF("Received data appdata %p appdatalen %d\n",
	   ip_buf_appdata(buf), ip_buf_appdatalen(buf));

    coap_ctx->buf = buf;

    coap_engine_receive(coap_ctx);

    return 1;
  }

  return 0;
}
Пример #24
0
/*---------------------------------------------------------------------------*/
static void
sprint_ip6(uip_ip6addr_t addr)
{
  unsigned char i = 0;
  unsigned char zerocnt = 0;
  unsigned char numprinted = 0;
  unsigned char notskipped = 0;
  char thestring[40];
  char *result = thestring;

  *result++ = '[';
  while(numprinted < 8) {
    if((addr.u16[i] == 0) && (zerocnt == 0)) {
      while(addr.u16[zerocnt + i] == 0) {
    	  zerocnt++;
      }
      if(zerocnt == 1 && notskipped) {
        *result++ = '0';
         numprinted++;
         notskipped = 1;
         continue;
      }
      i += zerocnt;
      numprinted += zerocnt;
    } else {
      result += sprintf(result, "%x", (unsigned int)(uip_ntohs(addr.u16[i])));
      i++;
      numprinted++;
    }
    if(numprinted != 8) {
      *result++ = ':';
    }
  }
  *result++=']';
  *result=0;
  PRINTF("%s", thestring);
}
Пример #25
0
/**
 * \brief							Adds a context to the Context Table
 * 
 * \param length			Length of the prefix
 * 
 * \param context_id	Context Id
 * 
 * \param prefix			Context prefix
 * 
 * \param compression	Is context valid for compression?
 * 
 * \returns						A pointer to the newly created context if the 
 * 										creation was successfull, otherwise NULL.
 *  
 */
uip_ds6_addr_context_t*
uip_ds6_context_add(uip_nd6_opt_6co *context_option,
																						u16_t defrt_lifetime) {
	uip_ds6_addr_context_t* context;	
	
	context = &uip_ds6_addr_context_table[context_option->res1_c_cid & UIP_ND6_RA_CID];
	if(context->state != NOT_IN_USE) {
		/* Context aready exists */
		return NULL;
	}
  context->length = context_option->preflen;
  context->context_id = context_option->res1_c_cid & UIP_ND6_RA_CID;
  uip_ipaddr_copy(&context->prefix, &context_option->prefix);
  if (context_option->res1_c_cid & UIP_ND6_RA_FLAG_COMPRESSION) {
	 	context->state = IN_USE_COMPRESS;
  } else {
  	context->state = IN_USE_UNCOMPRESS_ONLY;
  }
  /* Prevent overflow in case we need to set the lifetime to "twice the
   * Default Router Lifetime" */
  stimer_set(&context->vlifetime, uip_ntohs(context_option->lifetime));
  context->defrt_lifetime = defrt_lifetime < 0x7FFF ? defrt_lifetime : 0x7FFF;
  return context;
}
Пример #26
0
/* Switch the ports and addresses and set route and neighbor cache.
 * Returns 1 if packet was sent properly, in this case it is the caller
 * that needs to release the net_buf. If 0 is returned, then uIP stack
 * has released the net_buf already because there was an some net related
 * error when sending the buffer.
 */
static inline int udp_prepare_and_send(struct net_context *context,
				       struct net_buf *buf)
{
#ifdef CONFIG_NETWORKING_WITH_IPV6
	uip_ds6_route_t *route_old, *route_new = NULL;
	uip_ds6_nbr_t *nbr;
#endif
	uip_ipaddr_t tmp;
	uint16_t port;
	uint8_t ret;

	if (uip_len(buf) == 0) {
		/* This is expected as uIP will typically set the
		 * packet length to 0 after receiving it. So we need
		 * to fix the length here. The protocol specific
		 * part is added also here.
		 */
		uip_len(buf) = uip_slen(buf) = uip_appdatalen(buf);
		buf->data = buf->buf + UIP_IPUDPH_LEN;
	}

	port = UIP_UDP_BUF(buf)->srcport;
	UIP_UDP_BUF(buf)->srcport = UIP_UDP_BUF(buf)->destport;
	UIP_UDP_BUF(buf)->destport = port;

	uip_ipaddr_copy(&tmp, &UIP_IP_BUF(buf)->srcipaddr);
	uip_ipaddr_copy(&UIP_IP_BUF(buf)->srcipaddr,
			&UIP_IP_BUF(buf)->destipaddr);
	uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &tmp);

#ifdef CONFIG_NETWORKING_WITH_IPV6
	/* The peer needs to be in neighbor cache before route can be added.
	 */
	nbr = uip_ds6_nbr_lookup((uip_ipaddr_t *)&UIP_IP_BUF(buf)->destipaddr);
	if (!nbr) {
		const uip_lladdr_t *lladdr = (const uip_lladdr_t *)&buf->src;
		nbr = uip_ds6_nbr_add(
			(uip_ipaddr_t *)&UIP_IP_BUF(buf)->destipaddr,
			lladdr, 0, NBR_REACHABLE);
		if (!nbr) {
			NET_DBG("Cannot add peer ");
			PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr);
			PRINT(" to neighbor cache\n");
		}
	}

	/* Temporarily add route to peer, delete the route after
	 * sending the packet. Check if there was already a
	 * route and do not remove it if there was existing
	 * route to this peer.
	 */
	route_old = uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr);
	if (!route_old) {
		route_new = uip_ds6_route_add(&UIP_IP_BUF(buf)->destipaddr,
					      128,
					      &UIP_IP_BUF(buf)->destipaddr);
		if (!route_new) {
			NET_DBG("Cannot add route to peer ");
			PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr);
			PRINT("\n");
		}
	}
#endif

	ret = simple_udp_sendto_port(buf,
				     net_context_get_udp_connection(context),
				     buf->data, buf->len,
				     &UIP_IP_BUF(buf)->destipaddr,
				     uip_ntohs(UIP_UDP_BUF(buf)->destport));
	if (!ret) {
		NET_DBG("Packet could not be sent properly.\n");
	}

#ifdef CONFIG_NETWORKING_WITH_IPV6
	if (!route_old && route_new) {
		/* This will also remove the neighbor cache entry */
		uip_ds6_route_rm(route_new);
	}
#endif

	return ret;
}
Пример #27
0
/**
 * \brief   Take a packet received over the ethernet link, and send it
 * out over 802.15.4
 */
void mac_ethernetToLowpan(uint8_t * ethHeader)
{
  //Dest address
  uip_lladdr_t destAddr;
  uip_lladdr_t *destAddrPtr = NULL;

  PRINTF("Packet type: 0x%04x\n\r", uip_ntohs(((struct uip_eth_hdr *) ethHeader)->type));

   //RUM doesn't support sending data
   #if UIP_CONF_USE_RUM
   return;
   #endif

  /* In sniffer or sneezr mode we don't ever send anything */
  if ((usbstick_mode.sendToRf == 0) || (usbstick_mode.sneeze != 0)) {
    uip_len = 0;
    return;
  }


  /* If not IPv6 we don't do anything. Disable ipv4 on the interface to prevent possible hangs from discovery packet flooding */
  if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) {
    PRINTF("eth2low: Dropping packet w/type=0x%04x\n",uip_ntohs(((struct uip_eth_hdr *) ethHeader)->type));
  //      printf("!ipv6");

#if !RF230BB && !RF212BB
    usb_eth_stat.txbad++;
#endif
    uip_len = 0;
    return;
  }

  /* IPv6 uses 33-33-xx-xx-xx-xx prefix for multicast ND stuff */
  if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0x33) &&
       (((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0x33) )
  {
    PRINTF("eth2low: Ethernet multicast packet received\n\r");
    ;//Do Nothing
  } else if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0xFF) &&
            (((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0xFF) &&
            (((struct uip_eth_hdr *) ethHeader)->dest.addr[2] == 0xFF) &&
            (((struct uip_eth_hdr *) ethHeader)->dest.addr[3] == 0xFF) &&
            (((struct uip_eth_hdr *) ethHeader)->dest.addr[4] == 0xFF) &&
            (((struct uip_eth_hdr *) ethHeader)->dest.addr[5] == 0xFF) ) {
    /* IPv6 does not use broadcast addresses, hence this should not happen */
    PRINTF("eth2low: Dropping broadcast packet\n\r");

#if !RF230BB && !RF212BB
    usb_eth_stat.txbad++;
#endif
    uip_len = 0;
    return;
  } else {

  /* Simple Address Translation */
  if(memcmp((uint8_t *)&simple_trans_ethernet_addr, &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), 6) == 0) {
#if UIP_CONF_IPV6
        //Addressed to us: make 802.15.4 address from IPv6 Address
        destAddr.addr[0] = UIP_IP_BUF->destipaddr.u8[8] ^ 0x02;
        destAddr.addr[1] = UIP_IP_BUF->destipaddr.u8[9];
        destAddr.addr[2] = UIP_IP_BUF->destipaddr.u8[10];
        destAddr.addr[3] = UIP_IP_BUF->destipaddr.u8[11];
        destAddr.addr[4] = UIP_IP_BUF->destipaddr.u8[12];
        destAddr.addr[5] = UIP_IP_BUF->destipaddr.u8[13];
        destAddr.addr[6] = UIP_IP_BUF->destipaddr.u8[14];
        destAddr.addr[7] = UIP_IP_BUF->destipaddr.u8[15];
#else
		//Not intended to be functional, but allows ip4 build without errors.
        destAddr.addr[0] = UIP_IP_BUF->destipaddr.u8[0] ^ 0x02;
        destAddr.addr[1] = UIP_IP_BUF->destipaddr.u8[1];
        destAddr.addr[2] = UIP_IP_BUF->destipaddr.u8[2];
        destAddr.addr[3] = UIP_IP_BUF->destipaddr.u8[3];
        destAddr.addr[4] = UIP_IP_BUF->destipaddr.u8[0];
        destAddr.addr[5] = UIP_IP_BUF->destipaddr.u8[1];
        destAddr.addr[6] = UIP_IP_BUF->destipaddr.u8[2];
        destAddr.addr[7] = UIP_IP_BUF->destipaddr.u8[3];

#endif

        destAddrPtr = &destAddr;
  }
#if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
  else {
        //Not addressed to us
        uip_len = 0;
        return;
  }
#else

    /* Complex Address Translation */
    PRINTF("eth2low: Addressed packet received... ");
    //Check this returns OK
    if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) {
      PRINTF(" translation failed\n\r");

#if !RF230BB && !RF212BB
      usb_eth_stat.txbad++;
#endif
      uip_len = 0;
      return;
    }
    PRINTF(" translated OK\n\r");
    destAddrPtr = &destAddr;
#endif /* UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS */


  }

  //Remove header from length before passing onward
  uip_len -= UIP_LLH_LEN;

  //Some IP packets have link layer in them, need to change them around!
  if (usbstick_mode.translate) {
#if DEBUG
    uint8_t transReturn = mac_translateIPLinkLayer(ll_802154_type);
    PRINTF("IPTranslation: returns %d\n\r", transReturn);
#else
    mac_translateIPLinkLayer(ll_802154_type);
#endif
  }

#if UIP_CONF_IPV6
/* Send the packet to the uip6 stack if it exists, else send to 6lowpan */
#if UIP_CONF_IPV6_RPL
/* Save the destination address, to trap ponging it back to the interface */
  uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr);
  tcpip_input();
  tcpip_output(destAddrPtr);
#else
//  PRINTF("Input from %x %x %x %x %x %x %x %x\n",UIP_IP_BUF->srcipaddr.u8[0],UIP_IP_BUF->srcipaddr.u8[1],UIP_IP_BUF->srcipaddr.u8[2],UIP_IP_BUF->srcipaddr.u8[3],UIP_IP_BUF->srcipaddr.u8[4],UIP_IP_BUF->srcipaddr.u8[5],UIP_IP_BUF->srcipaddr.u8[6],UIP_IP_BUF->srcipaddr.u8[7]);
//  PRINTF("Output to %x %x %x %x %x %x %x %x\n",destAddr.addr[0],destAddr.addr[1],destAddr.addr[2],destAddr.addr[3],destAddr.addr[4],destAddr.addr[5],destAddr.addr[6],destAddr.addr[7]);
  tcpip_output(destAddrPtr);
#endif
#else  /* UIP_CONF_IPV6 */
  tcpip_output();    //Allow non-ipv6 builds (Hello World) 
#endif /* UIP_CONF_IPV6 */

#if !RF230BB && !RF212BB
  usb_eth_stat.txok++;
#endif
  uip_len = 0;

}
Пример #28
0
void
eth_input(void)
{
#if CETIC_6LBR_TRANSPARENTBRIDGE || CETIC_6LBR_ONE_ITF || CETIC_6LBR_6LR
  uip_lladdr_t srcAddr;
#endif
  uip_lladdr_t destAddr;
  int processFrame = 0;
  int forwardFrame = 0;

  //Packet type filtering
  //---------------------
  //Keep only IPv6 traffic
  if(BUF->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) {
    LOG6LBR_PRINTF(PACKET, PF_IN, "eth_input: Dropping packet type=0x%04x\n", uip_ntohs(BUF->type));
    uip_len = 0;
    return;
  }
  //Packet source Filtering
  //-----------------------
  /* IPv6 uses 33-33-xx-xx-xx-xx prefix for multicast ND stuff */
  if((BUF->dest.addr[0] == 0x33) && (BUF->dest.addr[1] == 0x33)) {
    forwardFrame = 1;
    processFrame = 1;
    rimeaddr_copy((rimeaddr_t *) & destAddr, &rimeaddr_null);
  } else if((BUF->dest.addr[0] == 0xFF)
            && (BUF->dest.addr[1] == 0xFF)
            && (BUF->dest.addr[2] == 0xFF)
            && (BUF->dest.addr[3] == 0xFF)
            && (BUF->dest.addr[4] == 0xFF)
            && (BUF->dest.addr[5] == 0xFF)) {
    /* IPv6 does not use broadcast addresses, hence this should not happen */
    LOG6LBR_PRINTF(PACKET, PF_IN, "eth_input: Dropping broadcast packet\n");
    uip_len = 0;
    return;
  } else {
    /* Complex Address Translation */
    if(mac_createSicslowpanLongAddr(&(BUF->dest.addr[0]), &destAddr) == 0) {
      LOG6LBR_WARN("eth_input: Address translation failed\n");
      uip_len = 0;
      return;
    }
  }

  //Packet content rewriting
  //------------------------
  //Some IP packets have link layer in them, need to change them around!
  uint8_t transReturn = mac_translateIPLinkLayer(ll_802154_type);

  if(transReturn != 0) {
    LOG6LBR_WARN("eth_input: IPTranslation returns %d\n", transReturn);
  }

  //Destination filtering
  //---------------------
  if(memcmp((uint8_t *) & eth_mac_addr, BUF->dest.addr, 6) == 0) {
    processFrame = 1;
  } else {
#if CETIC_6LBR_TRANSPARENTBRIDGE
    //Not for us, forward it directly
    forwardFrame = 1;
#endif
  }

  //Handle packet
  //-------------
#if CETIC_6LBR_TRANSPARENTBRIDGE
  if(forwardFrame) {
    mac_createSicslowpanLongAddr(&(BUF->src.addr[0]), &srcAddr);
#if CETIC_6LBR_LEARN_RPL_MAC
    if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type == ICMP6_RPL) {
      uint8_t *buffer = UIP_ICMP_PAYLOAD;
      uint16_t rank = (uint16_t)buffer[2] << 8 | buffer[2 + 1];
      if ( rank == RPL_MIN_HOPRANKINC ) {
    	platform_set_wsn_mac((rimeaddr_t *) &srcAddr);
        rpl_mac_known=1;
      }
    }
    if (!rpl_mac_known) {
      //Rpl Relay not yet configured, drop packet
      uip_len = 0;
      return;
    }
    if(rimeaddr_cmp((rimeaddr_t *) &srcAddr, &rimeaddr_node_addr) != 0) {
      //Only forward RplRoot packets
      LOG6LBR_LLADDR_PRINTF(PACKET, PF_IN, &destAddr, "eth_input: Forwarding frame to ");
      wireless_output(NULL, &destAddr);
    }
#else
    LOG6LBR_LLADDR_PRINTF(PACKET, PF_IN, &destAddr, "eth_input: Forwarding frame to ");
    wireless_output(&srcAddr, &destAddr);
#endif
  }
#endif
  if(processFrame) {
    LOG6LBR_PRINTF(PACKET, PF_IN, "eth_input: Processing frame\n");
#if CETIC_6LBR_ONE_ITF || CETIC_6LBR_6LR
  //RPL uses source packet address to populate its neighbor table
  //In this two modes RPL packets are incoming from Eth interface
  mac_createSicslowpanLongAddr(&(BUF->src.addr[0]), &srcAddr);
  packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (rimeaddr_t *) &srcAddr);
#endif
    send_to_uip();
  } else {
    //Drop packet
    uip_len = 0;
  }
}
Пример #29
0
/*----------------------------------------------------------------------------*/
static
int
coap_receive(void)
{
    coap_error_code = NO_ERROR;

    PRINTF("handle_incoming_data(): received uip_datalen=%u \n",(uint16_t)uip_datalen());

    /* Static declaration reduces stack peaks and program code size. */
    static coap_packet_t message[1]; /* This way the packet can be treated as pointer as usual. */
    static coap_packet_t response[1];
    static coap_transaction_t *transaction = NULL;

    if (uip_newdata()) {

        PRINTF("receiving UDP datagram from: ");
        PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
        PRINTF(":%u\n  Length: %u\n  Data: ", uip_ntohs(UIP_UDP_BUF->srcport), uip_datalen() );
        PRINTBITS(uip_appdata, uip_datalen());
        PRINTF("\n");

        coap_error_code = coap_parse_message(message, uip_appdata, uip_datalen());

        if (coap_error_code==NO_ERROR)
        {

            /*TODO duplicates suppression, if required by application */

            PRINTF("  Parsed: v %u, t %u, oc %u, c %u, mid %u\n", message->version, message->type, message->option_count, message->code, message->mid);
            PRINTF("  URL: %.*s\n", message->uri_path_len, message->uri_path);
            PRINTF("  Payload: %.*s\n", message->payload_len, message->payload);

            /* Handle requests. */
            if (message->code >= COAP_GET && message->code <= COAP_DELETE)
            {
                /* Use transaction buffer for response to confirmable request. */
                if ( (transaction = coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport)) )
                {
                    uint32_t block_num = 0;
                    uint16_t block_size = REST_MAX_CHUNK_SIZE;
                    uint32_t block_offset = 0;
                    int32_t new_offset = 0;

                    /* prepare response */
                    if (message->type==COAP_TYPE_CON)
                    {
                        /* Reliable CON requests are answered with an ACK. */
                        coap_init_message(response, COAP_TYPE_ACK, CONTENT_2_05, message->mid);
                    }
                    else
                    {
                        /* Unreliable NON requests are answered with a NON as well. */
                        coap_init_message(response, COAP_TYPE_NON, CONTENT_2_05, coap_get_mid());
                    }

                    /* resource handlers must take care of different handling (e.g., TOKEN_OPTION_REQUIRED_240) */
                    if (IS_OPTION(message, COAP_OPTION_TOKEN))
                    {
                        coap_set_header_token(response, message->token, message->token_len);
                        SET_OPTION(response, COAP_OPTION_TOKEN);
                    }

                    /* get offset for blockwise transfers */
                    if (coap_get_header_block2(message, &block_num, NULL, &block_size, &block_offset))
                    {
                        PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n", block_num, block_size, REST_MAX_CHUNK_SIZE, block_offset);
                        block_size = MIN(block_size, REST_MAX_CHUNK_SIZE);
                        new_offset = block_offset;
                    }

                    /* Invoke resource handler. */
                    if (service_cbk)
                    {
                        /* Call REST framework and check if found and allowed. */
                        if (service_cbk(message, response, transaction->packet+COAP_MAX_HEADER_SIZE, block_size, &new_offset))
                        {
                            if (coap_error_code==NO_ERROR)
                            {
                                /* Apply blockwise transfers. */
                                if ( IS_OPTION(message, COAP_OPTION_BLOCK1) && response->code<BAD_REQUEST_4_00 && !IS_OPTION(response, COAP_OPTION_BLOCK1) )
                                {
                                    PRINTF("Block1 NOT IMPLEMENTED\n");

                                    coap_error_code = NOT_IMPLEMENTED_5_01;
                                    coap_error_message = "NoBlock1Support";
                                }
                                else if ( IS_OPTION(message, COAP_OPTION_BLOCK2) )
                                {
                                    /* unchanged new_offset indicates that resource is unaware of blockwise transfer */
                                    if (new_offset==block_offset)
                                    {
                                        PRINTF("Blockwise: unaware resource with payload length %u/%u\n", response->payload_len, block_size);
                                        if (block_offset >= response->payload_len)
                                        {
                                            PRINTF("handle_incoming_data(): block_offset >= response->payload_len\n");

                                            response->code = BAD_OPTION_4_02;
                                            coap_set_payload(response, "BlockOutOfScope", 15); /* a const char str[] and sizeof(str) produces larger code size */
                                        }
                                        else
                                        {
                                            coap_set_header_block2(response, block_num, response->payload_len - block_offset > block_size, block_size);
                                            coap_set_payload(response, response->payload+block_offset, MIN(response->payload_len - block_offset, block_size));
                                        } /* if (valid offset) */
                                    }
                                    else
                                    {
                                        /* resource provides chunk-wise data */
                                        PRINTF("Blockwise: blockwise resource, new offset %ld\n", new_offset);
                                        coap_set_header_block2(response, block_num, new_offset!=-1 || response->payload_len > block_size, block_size);
                                        if (response->payload_len > block_size) coap_set_payload(response, response->payload, block_size);
                                    } /* if (resource aware of blockwise) */
                                }
                                else if (new_offset!=0)
                                {
                                    PRINTF("Blockwise: no block option for blockwise resource, using block size %u\n", REST_MAX_CHUNK_SIZE);

                                    coap_set_header_block2(response, 0, new_offset!=-1, REST_MAX_CHUNK_SIZE);
                                    coap_set_payload(response, response->payload, MIN(response->payload_len, REST_MAX_CHUNK_SIZE));
                                } /* if (blockwise request) */
                            } /* no errors/hooks */
                        } /* successful service callback */

                        /* Serialize response. */
                        if (coap_error_code==NO_ERROR)
                        {
                            if ((transaction->packet_len = coap_serialize_message(response, transaction->packet))==0)
                            {
                                coap_error_code = PACKET_SERIALIZATION_ERROR;
                            }
                        }

                    }
                    else
                    {
                        coap_error_code = NOT_IMPLEMENTED_5_01;
                        coap_error_message = "NoServiceCallbck"; // no a to fit 16 bytes
                    } /* if (service callback) */

                } else {
                    coap_error_code = SERVICE_UNAVAILABLE_5_03;
                    coap_error_message = "NoFreeTraBuffer";
                } /* if (transaction buffer) */
            }
            else
            {
                /* Responses */

                if (message->type==COAP_TYPE_ACK)
                {
                    PRINTF("Received ACK\n");
                }
                else if (message->type==COAP_TYPE_RST)
                {
                    PRINTF("Received RST\n");
                    /* Cancel possible subscriptions. */
                    coap_remove_observer_by_mid(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, message->mid);
                }

                transaction = coap_get_transaction_by_mid(message->mid);
                if (message->type != COAP_TYPE_CON && transaction)
                {
                    /* Free transaction memory before callback, as it may create a new transaction. */
                    restful_response_handler callback = transaction->callback;
                    void *callback_data = transaction->callback_data;
                    coap_clear_transaction(transaction);

                    /* Check if someone registered for the response */
                    if (callback) {
                        callback(callback_data, message);
                    }
                } /* if (ACKed transaction) */
                /* Observe notification */
                if ((message->type == COAP_TYPE_CON || message->type == COAP_TYPE_NON) \
                        && IS_OPTION(message, COAP_OPTION_OBSERVE)) {
                    PRINTF("Observe [%u]\n", message->observe);
                    coap_handle_notification(&UIP_IP_BUF->srcipaddr,                     \
                                             UIP_UDP_BUF->srcport, message);
                }
                transaction = NULL;

            } /* Request or Response */

        } /* if (parsed correctly) */

        if (coap_error_code==NO_ERROR)
        {
            if (transaction) coap_send_transaction(transaction);
        }
        else if (coap_error_code==MANUAL_RESPONSE)
        {
            PRINTF("Clearing transaction for manual response");
            coap_clear_transaction(transaction);
        }
        else
        {
            PRINTF("ERROR %u: %s\n", coap_error_code, coap_error_message);
            coap_clear_transaction(transaction);

            /* Set to sendable error code. */
            if (coap_error_code >= 192)
            {
                coap_error_code = INTERNAL_SERVER_ERROR_5_00;
            }
            /* Reuse input buffer for error message. */
            coap_init_message(message, COAP_TYPE_ACK, coap_error_code, message->mid);
            coap_set_payload(message, coap_error_message, strlen(coap_error_message));
            coap_send_message(&UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport, uip_appdata, coap_serialize_message(message, uip_appdata));
        }
    } /* if (new data) */

    return coap_error_code;
}
Пример #30
0
static void dhcpTask(void* arg)
{
  int wait;

 init:
  xid++;
  s.state = STATE_SENDING;
  wait = 1;

  while (1) {

    send_discover();

    if (readResponse(DHCPOFFER, wait) != -1) {

      s.state = STATE_OFFER_RECEIVED;
      goto selecting;
    }

    if(wait < 60)
      wait = wait * 2;
  }
  
 selecting:
  xid++;
  wait = 1;

  do {

    send_request();

    if (readResponse(DHCPACK, wait) != -1) {

      s.state = STATE_CONFIG_RECEIVED;
      goto bound;
    }

    if(wait < 10) {

      wait++;
    }
    else {

      goto init;
    }

  } while(s.state != STATE_CONFIG_RECEIVED);
  
 bound:
#if 0
  nosPrintf("Got IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.ipaddr));
  nosPrintf("Got netmask %d.%d.%d.%d\n",	 uip_ipaddr_to_quad(&s.netmask));
  nosPrintf("Got DNS server %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.dnsaddr));
  nosPrintf("Got default router %d.%d.%d.%d\n",
	 uip_ipaddr_to_quad(&s.default_router));
  nosPrintf("Lease expires in %ld seconds\n",
	 uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]));
#endif

  dhcpc_configured(&s);

  uint32_t leaseLeft = uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]);
  uint32_t sleepLeft = leaseLeft / 2;

#define MAX_SECS ((INFINITE - 1) / HZ)

  while (sleepLeft > 0) {

    if (sleepLeft > MAX_SECS) {

      wait = MAX_SECS * HZ;
      sleepLeft -= MAX_SECS;
    }
    else {

      wait = sleepLeft * HZ;
      sleepLeft = 0;
    }

    posTaskSleep(wait);
  }

  leaseLeft = leaseLeft / 2;

  /* renewing: */
  xid++;
  do {

    send_request();

    if (leaseLeft / 2 > MAX_SECS)
      wait = MAX_SECS;
    else
      wait = (leaseLeft / 2);

    if (readResponse(DHCPACK, wait) != -1) {

      s.state = STATE_CONFIG_RECEIVED;
      goto bound;
    }

    leaseLeft -= wait;

  } while (leaseLeft > 3);

  /* rebinding: */

  /* lease_expired: */
  dhcpc_unconfigured(&s);
  goto init;
}