Exemplo n.º 1
0
static void
trickle_recv(struct trickle_conn *c)
{
  if (!is_gateway) {
    struct gateway_msg *msg;
    msg = rimebuf_dataptr();
    printf("%d.%d: gateway message: %d.%d\n",
	   rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
	   msg->gateway.u8[0], msg->gateway.u8[1]);
    
    uip_over_mesh_set_gateway(&msg->gateway);
  }
}
Exemplo n.º 2
0
/*---------------------------------------------------------------------------*/
static int
format_data(struct rudolph2_conn *c, int chunk)
{
  struct rudolph2_hdr *hdr;
  int len;
  
  rimebuf_clear();
  hdr = rimebuf_dataptr();
  hdr->type = TYPE_DATA;
  hdr->hops_from_base = c->hops_from_base;
  hdr->version = c->version;
  hdr->chunk = chunk;
  len = read_data(c, TC(hdr) + sizeof(struct rudolph2_hdr), chunk);
  rimebuf_set_datalen(sizeof(struct rudolph2_hdr) + len);

  return len;
}
Exemplo n.º 3
0
/*---------------------------------------------------------------------------*/
void
rudolph2_send(struct rudolph2_conn *c, clock_time_t send_interval)
{
  int len;

  c->hops_from_base = 0;
  c->version++;
  c->snd_nxt = 0;
  len = RUDOLPH2_DATASIZE;
  rimebuf_clear();
  for(c->rcv_nxt = 0; len == RUDOLPH2_DATASIZE; c->rcv_nxt++) {
    len = read_data(c, rimebuf_dataptr(), c->rcv_nxt);
  }
  c->flags = FLAG_LAST_RECEIVED;
  printf("Highest chunk %d\n", c->rcv_nxt);
  send_data(c, SEND_INTERVAL);
  ctimer_set(&c->t, SEND_INTERVAL, timed_send,  TC(c));
}
Exemplo n.º 4
0
/*---------------------------------------------------------------------------*/
static int
read_packet(void)
{
  struct xmac_hdr *hdr;
  uint8_t len;

  rimebuf_clear();

  len = radio->read(rimebuf_dataptr(), RIMEBUF_SIZE);

  if(len > 0) {
    rimebuf_set_datalen(len);
    hdr = rimebuf_dataptr();

    rimebuf_hdrreduce(sizeof(struct xmac_hdr));

    if(rimebuf_totlen() == 0) {
      CPRINTF(".");
      /* There is no data in the packet so it has to be a strobe. */
      someone_is_sending = 2;
      
      if(rimeaddr_cmp(&hdr->receiver, &rimeaddr_node_addr)) {
	/* This is a strobe packet for us. */

	if(rimeaddr_cmp(&hdr->sender, &rimeaddr_node_addr)) {
	  /* If the sender address is our node address, the strobe is
	     a stray strobe ACK to us, which we ignore unless we are
	     currently sending a packet.  */
	  CPRINTF("&");
	  someone_is_sending = 0;
	} else {
	  struct xmac_hdr msg;
	  /* If the sender address is someone else, we should
	     acknowledge the strobe and wait for the packet. By using
	     the same address as both sender and receiver, we flag the
	     message is a strobe ack. */
#if WITH_TIMETABLE
	  TIMETABLE_TIMESTAMP(xmac_timetable, "read send ack");
#endif
	  rimeaddr_copy(&msg.receiver, &hdr->sender);
	  rimeaddr_copy(&msg.sender, &hdr->sender);
	  CPRINTF("!");
	  /* We turn on the radio in anticipation of the incoming
	     packet. */
	  someone_is_sending = 1;
	  waiting_for_packet = 1;
	  on();
	  radio->send((const uint8_t *)&msg, sizeof(struct xmac_hdr));
	}
      } else if(rimeaddr_cmp(&hdr->receiver, &rimeaddr_null)) {
	/* If the receiver address is null, the strobe is sent to
	   prepare for an incoming broadcast packet. If this is the
	   case, we turn on the radio and wait for the incoming
	   broadcast packet. */
	waiting_for_packet = 1;
	on();
      }
      /* We are done processing the strobe and we therefore return
	 to the caller. */
      return RIME_OK;
    } else {
      CPRINTF("-");
      someone_is_sending = 0;
      if(rimeaddr_cmp(&hdr->receiver, &rimeaddr_node_addr) ||
	 rimeaddr_cmp(&hdr->receiver, &rimeaddr_null)) {
#if WITH_TIMETABLE
	TIMETABLE_TIMESTAMP(xmac_timetable, "read got packet");
#endif
	/* This is a regular packet that is destined to us or to the
	   broadcast address. */
	
	/* We have received the final packet, so we can go back to being
	   asleep. */
	off();
	waiting_for_packet = 0;
	
	/* XXX should set timer to send queued packet later. */
	if(queued_packet != NULL) {
	  queuebuf_free(queued_packet);
	  queued_packet = NULL;
	}
	
	return rimebuf_totlen();
      }
    }
  }
  return 0;
}
Exemplo n.º 5
0
/*---------------------------------------------------------------------------*/
static void
recv(struct polite_conn *polite)
{
  struct rudolph2_conn * SAFE c =  TC(polite);
  struct rudolph2_hdr *hdr = rimebuf_dataptr();

  /* Only accept NACKs from nodes that are farther away from the base
     than us. */

  if(hdr->type == TYPE_NACK && hdr->hops_from_base > c->hops_from_base) {
    c->nacks++;
    PRINTF("%d.%d: Got NACK for %d:%d (%d:%d)\n",
	   rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
	   hdr->version, hdr->chunk,
	   c->version, c->rcv_nxt);
    if(hdr->version == c->version) {
      if(hdr->chunk < c->rcv_nxt) {
	c->snd_nxt = hdr->chunk;
	send_data(c, SEND_INTERVAL);
      }
    } else if(LT(hdr->version, c->version)) {
      c->snd_nxt = 0;
      send_data(c, SEND_INTERVAL);
    }
  } else if(hdr->type == TYPE_DATA) {
    if(hdr->hops_from_base < c->hops_from_base) {
      /* Only accept data from nodes that are closer to the base than
	 us. */
      c->hops_from_base = hdr->hops_from_base + 1;
      if(LT(c->version, hdr->version)) {
	PRINTF("%d.%d: rudolph2 new version %d, chunk %d\n",
	       rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
	       hdr->version, hdr->chunk);
	c->version = hdr->version;
	c->snd_nxt = c->rcv_nxt = 0;
	c->flags &= ~FLAG_LAST_RECEIVED;
	c->flags &= ~FLAG_LAST_SENT;
	if(hdr->chunk != 0) {
	  send_nack(c);
	} else {
	  rimebuf_hdrreduce(sizeof(struct rudolph2_hdr));
	  write_data(c, 0, rimebuf_dataptr(), rimebuf_totlen());
	}
      } else if(hdr->version == c->version) {
	PRINTF("%d.%d: got chunk %d snd_nxt %d rcv_nxt %d\n",
	       rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
	       hdr->chunk, c->snd_nxt, c->rcv_nxt);
	
	if(hdr->chunk == c->rcv_nxt) {
	  int len;
	  rimebuf_hdrreduce(sizeof(struct rudolph2_hdr));
	  PRINTF("%d.%d: received chunk %d len %d\n",
		 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
		 hdr->chunk, rimebuf_totlen());
	  len = rimebuf_totlen();
	  write_data(c, hdr->chunk, rimebuf_dataptr(), rimebuf_totlen());
	  c->rcv_nxt++;
	  if(len < RUDOLPH2_DATASIZE) {
	    c->flags |= FLAG_LAST_RECEIVED;
	    send_data(c, RESEND_INTERVAL);
	    ctimer_set(&c->t, RESEND_INTERVAL, timed_send,  TC(c));
	  }
	} else if(hdr->chunk > c->rcv_nxt) {
	  PRINTF("%d.%d: received chunk %d > %d, sending NACK\n",
		 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
		 hdr->chunk, c->rcv_nxt);
	  send_nack(c);
	} else if(hdr->chunk < c->rcv_nxt) {
	  /* Ignore packets with a lower chunk number */
	}
      }
    }
  }
}