Esempio n. 1
0
/*---------------------------------------------------------------------------*/
void
mac_sequence_register_seqno(void)
{
  int i, j;

  /* Locate possible previous sequence number for this address. */
  for(i = 0; i < MAX_SEQNOS; ++i) {
    if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
                    &received_seqnos[i].sender)) {
      i++;
      break;
    }
  }

  /* Keep the last sequence number for each address as per 802.15.4e. */
  for(j = i - 1; j > 0; --j) {
    memcpy(&received_seqnos[j], &received_seqnos[j - 1], sizeof(struct seqno));
  }
  received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
  linkaddr_copy(&received_seqnos[0].sender,
                packetbuf_addr(PACKETBUF_ADDR_SENDER));
}
Esempio n. 2
0
/*---------------------------------------------------------------------------*/
static void
recv_from_abc(struct abc_conn *bc)
{
  rimeaddr_t sender;
  struct broadcast_conn *c = (struct broadcast_conn *)bc;

  rimeaddr_copy(&sender, packetbuf_addr(PACKETBUF_ADDR_SENDER));
  
  PRINTF("%d.%d: broadcast: from %d.%d\n",
	 rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1],
	 sender.u8[0], sender.u8[1]);
  c->u->recv(c, &sender);
}
Esempio n. 3
0
//APP Callback function
static void app_recv(void)
{
	PROCESS_CONTEXT_BEGIN(&null_app_process);

	uint8_t *data = packetbuf_dataptr();

	rimeaddr_t *sent_sn_addr = packetbuf_addr(PACKETBUF_ADDR_SENDER);

	uint8_t rx_sn_id = sent_sn_addr->u8[0];
	uint8_t pkt_seq = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
	uint8_t payload_len = packetbuf_datalen();
/*
	uart1_writeb(rx_sn_id);
	uart1_writeb(pkt_seq);
	uart1_writeb(payload_len);
*/
	if(node_id != 0)
	{
		printf("%u,%u,%u\n",rx_sn_id,pkt_seq,payload_len);
	}
	else
	{
		//printf("%u,%u,%u,",rx_sn_id,pkt_seq,payload_len);
		putchar(rx_sn_id);
		putchar(pkt_seq);
		putchar(payload_len);
		
		//printf("%u",rx_sn_id);
		uint8_t i = 0;
	
		for(i = 0; i < (payload_len); i++)
		{
			//printf("%d,",((data[2*i+1]<<8)|data[2*i]));
			putchar(data[i]);
		}

	
	}

/*
	for(i = 0; i < payload_len; i++)
	{
		uart1_writeb(data[i]);
	}
*/
	uart1_writeb('\n');


	PROCESS_CONTEXT_END(&null_app_process);

}
Esempio n. 4
0
/*---------------------------------------------------------------------------*/
static void
input_packet(void)
{
  frame802154_t frame;
  int len;

  len = packetbuf_datalen();

  if(frame802154_parse(packetbuf_dataptr(), len, &frame) &&
     packetbuf_hdrreduce(len - frame.payload_len)) {
    if(frame.fcf.dest_addr_mode) {
      if(frame.dest_pid != mac_src_pan_id &&
         frame.dest_pid != FRAME802154_BROADCASTPANDID) {
        /* Not broadcast or for our PAN */
        PRINTF("6MAC: for another pan %u\n", frame.dest_pid);
        return;
      }
      if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) {
        packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (rimeaddr_t *)&frame.dest_addr);
        if(!rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
                         &rimeaddr_node_addr)) {
          /* Not for this node */
          PRINTF("6MAC: not for us\n");
          return;
        }
      }
    }
    packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (rimeaddr_t *)&frame.src_addr);

    PRINTF("6MAC-IN: %2X", frame.fcf.frame_type);
    PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
    PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
    PRINTF("%u\n", packetbuf_datalen());
    NETSTACK_MAC.input();
  } else {
    PRINTF("6MAC: failed to parse hdr\n");
  }
}
Esempio n. 5
0
/*---------------------------------------------------------------------------*/
static void
fast_c_packet_sent(int mac_status)
{
  /* Check if our parent just ACKed a DAO */
  if(fast_c_parent_knows_us == 0
     && mac_status == MAC_TX_OK
     && packetbuf_attr(PACKETBUF_ATTR_NETWORK_ID) == UIP_PROTO_ICMP6
     && packetbuf_attr(PACKETBUF_ATTR_CHANNEL) == (ICMP6_RPL << 8 | RPL_CODE_DAO)) {
    if(!linkaddr_cmp(&fast_c_parent_linkaddr, &linkaddr_null)
       && linkaddr_cmp(&fast_c_parent_linkaddr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {
      fast_c_parent_knows_us = 1;
    }
  }
}
Esempio n. 6
0
/*---------------------------------------------------------------------------*/
static int
create(void)
{
  struct nullmac_hdr *hdr;

  if(packetbuf_hdralloc(sizeof(struct nullmac_hdr))) {
    hdr = packetbuf_hdrptr();
    linkaddr_copy(&(hdr->sender), &linkaddr_node_addr);
    linkaddr_copy(&(hdr->receiver), packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
    return sizeof(struct nullmac_hdr);
  }
  PRINTF("PNULLMAC-UT: too large header: %u\n", sizeof(struct nullmac_hdr));
  return FRAMER_FAILED;
}
Esempio n. 7
0
/*---------------------------------------------------------------------------*/
static int
read_packet(void)
{
  frame802154_t frame;
  int len;
  packetbuf_clear();
  len = radio->read(packetbuf_dataptr(), PACKETBUF_SIZE);
  if(len > 0) {
    packetbuf_set_datalen(len);
    if(frame802154_parse(packetbuf_dataptr(), len, &frame) &&
       packetbuf_hdrreduce(len - frame.payload_len)) {
      if(frame.fcf.dest_addr_mode) {
        if(frame.dest_pid != mac_src_pan_id &&
           frame.dest_pid != FRAME802154_BROADCASTPANDID) {
          /* Not broadcast or for our PAN */
          PRINTF("6MAC: for another pan %u\n", frame.dest_pid);
          return 0;

        }
        if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr.u8)) {
          packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &frame.dest_addr);
        }
      }
      packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &frame.src_addr);

      PRINTF("6MAC-IN: %2X", frame.fcf.frame_type);
      PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
      PRINTADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
      PRINTF("%u\n", packetbuf_datalen());
      return packetbuf_datalen();
    } else {
      PRINTF("6MAC: failed to parse hdr\n");
    }
  }
  return 0;
}
Esempio n. 8
0
void c_multihop_recv(struct pipe *p, struct stackmodule_i *module) {
	PRINTF("c_multihop_recv \n");
	printaddr(module->stack_id);

	rimeaddr_t *nexthop = NULL;

	rimeaddr_t esender, ereceiver;

	/* Copy the packet attributes to avoid them being overwritten or
	 cleared by an application program that uses the packet buffer for
	 its own needs. */
	//rimeaddr_copy(&esender, packetbuf_addr(PACKETBUF_ADDR_ESENDER));
	rimeaddr_copy(&ereceiver, packetbuf_addr(PACKETBUF_ADDR_ERECEIVER));

	if (rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_ERECEIVER),
			&rimeaddr_node_addr)) {
		stack[module->stack_id].resend_flg = 1;
		PRINTF("for us!\n");
		p->multihop_param.hop_no = packetbuf_attr(PACKETBUF_ATTR_HOPS);
	} else {
		nexthop = c_forward(p, stack[module->stack_id].amodule, stack[module->stack_id].modno);
		PRINTF("nexthop: %d.%d \n", nexthop->u8[0], nexthop->u8[1]);

		packetbuf_set_attr(PACKETBUF_ATTR_HOPS,
				packetbuf_attr(PACKETBUF_ATTR_HOPS) + 1);
		if (nexthop) {
			set_node_addr(module->stack_id, 0, 2, nexthop);
			PRINTF("forwarding to %d.%d\n", nexthop->u8[0], nexthop->u8[1]);
			if (module->stack_id < STACKNO) {
				//stack_send(&stack[module->stack_id], module->module_id);
				stack_send(&stack[module->stack_id], module->module_id);

			}
		}
	}
}
Esempio n. 9
0
/*---------------------------------------------------------------------------*/
void
neighbor_info_packet_received(void)
{
  const rimeaddr_t *src;

  src = packetbuf_addr(PACKETBUF_ADDR_SENDER);
  if(rimeaddr_cmp(src, &rimeaddr_null)) {
    return;
  }

  PRINTF("neighbor-info: packet received from %d.%d\n",
	src->u8[sizeof(*src) - 2], src->u8[sizeof(*src) - 1]);

  add_neighbor(src);
}
Esempio n. 10
0
/*---------------------------------------------------------------------------*/
void
neighbor_info_packet_sent(int status, int numtx)
{
  const rimeaddr_t *dest;
  link_metric_t packet_metric;
#if UIP_DS6_LL_NUD
  uip_ds6_nbr_t *nbr;
#endif /* UIP_DS6_LL_NUD */

  dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
  if(rimeaddr_cmp(dest, &rimeaddr_null)) {
    return;
  }

  packet_metric = numtx;

  PRINTF("neighbor-info: packet sent to %d.%d, status=%d, metric=%u\n",
	dest->u8[sizeof(*dest) - 2], dest->u8[sizeof(*dest) - 1],
	status, (unsigned)packet_metric);

  switch(status) {
  case MAC_TX_OK:
    add_neighbor(dest);
#if UIP_DS6_LL_NUD
    nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
    if(nbr != NULL &&
       (nbr->state == STALE || nbr->state == DELAY || nbr->state == PROBE)) {
      nbr->state = REACHABLE;
//      stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
      PRINTF("neighbor-info : received a link layer ACK : ");
      PRINTLLADDR((uip_lladdr_t *)dest);
      PRINTF(" is reachable.\n");
    }
#endif /* UIP_DS6_LL_NUD */
    break;
  case MAC_TX_NOACK:
    add_neighbor(dest);
    printf("neighbor-info: ETX_NOACK_PENALTY\n");
    packet_metric = ETX_NOACK_PENALTY;
    break;
  default:
    /* Do not penalize the ETX when collisions or transmission
       errors occur. */
    return;
  }

  update_metric(dest, packet_metric);
}
Esempio n. 11
0
//APP Callback function
static void app_recv(void)
{
	PROCESS_CONTEXT_BEGIN(&null_app_process);

#ifdef SF_MOTE_TYPE_AP
	mpu_data_acc_gyro_union data[SAMPLES_PER_FRAME];

	// TX info
	uint8_t i;
	rimeaddr_t *sent_sn_addr = packetbuf_addr(PACKETBUF_ADDR_SENDER);
	uint8_t rx_sn_id = sent_sn_addr->u8[0];

	uint8_t pkt_seq = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
	//DATA_SIZE;
	uint8_t payload_len = packetbuf_datalen();

	if(payload_len != MPU_DATA_ACC_GYRO_SIZE*SAMPLES_PER_FRAME)
	{
		//printf("Ignore packet %u,%u %u\n",rx_sn_id,pkt_seq,payload_len);
		//return;
		memcpy((uint8_t*)data,packetbuf_dataptr(),MPU_DATA_ACC_GYRO_SIZE*SAMPLES_PER_FRAME);
	}
	else
	{
		memcpy((uint8_t*)data,packetbuf_dataptr(),MPU_DATA_ACC_GYRO_SIZE*SAMPLES_PER_FRAME);
	}

	for(i=0;i<SAMPLES_PER_FRAME;i++)
	{
		// MPU data
		mpu_data_acc_gyro_union samples = data[i];


		MPU_PRINT_BYTE(rx_sn_id);
		MPU_PRINT_BYTE(0);
		MPU_PRINT_BYTE(pkt_seq);
		MPU_PRINT_BYTE(0);
		print_mpu_sample_acc_gyro(&samples);
		MPU_PRINT_BYTE('\n');
	}

#endif

	PROCESS_CONTEXT_END(&null_app_process);

}
/*---------------------------------------------------------------------------*/
static int
select_packet(uint16_t *slotframe, uint16_t *timeslot)
{
  /* Select data packets we have a unicast link to */
  const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
  if(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE) == FRAME802154_DATAFRAME
     && !linkaddr_cmp(dest, &linkaddr_null)) {
    if(slotframe != NULL) {
      *slotframe = slotframe_handle;
    }
    if(timeslot != NULL) {
      *timeslot = get_node_timeslot(dest);
    }
    return 1;
  }
  return 0;
}
Esempio n. 13
0
/**
 * Input callback called by the lower layers to indicate incoming data
 */
static void dtn_network_input(void) 
{
	linkaddr_t source;
	uint8_t * buffer = NULL;
	uint8_t length = 0;
	packetbuf_attr_t rssi = 0;

	leds_on(LEDS_ALL);

	/* Create a copy here, because otherwise packetbuf_clear will evaporate the address */
	linkaddr_copy(&source, packetbuf_addr(PACKETBUF_ADDR_SENDER));
	buffer = packetbuf_dataptr();
	length = packetbuf_datalen();
	rssi = packetbuf_attr(PACKETBUF_ATTR_RSSI);

	convergence_layer_incoming_frame(&source, buffer, length, rssi);

	leds_off(LEDS_ALL);
}
/* Returns the latestForwarded_table_entry pointer to the latestForwardedTable
*  entry representing the neighbor node address passed as a parameter. If
*  no such neighbor exists, returns NULL.
*/
latestForwarded_table_entry* latestForwardedTableFind(rimeaddr_t *neighbor_p) {
	pmesg(200, "%s :: %s :: Line #%d\n", __FILE__, __func__, __LINE__);
	static uint8_t i = 0;
	static bool isBroadcast = 0;
  
  isBroadcast = rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
                                &rimeaddr_null);
	if (isBroadcast)
		return NULL;

	for (i = 0; i < latestForwardedTableActive; i++) {
		if (rimeaddr_cmp(&(latestForwardedTable[i].neighbor), neighbor_p))
		break;
	}

	if(i == latestForwardedTableActive)
		return NULL;

	return &(latestForwardedTable[i]);
}
Esempio n. 15
0
/**
 * Send a probe packet.
 */
static void
send_probe(void)
{
  struct lpp_hdr *hdr;
  struct announcement_msg *adata;
  struct announcement *a;

  /* Set up the probe header. */
  packetbuf_clear();
  packetbuf_set_datalen(sizeof(struct lpp_hdr));
  hdr = packetbuf_dataptr();
  hdr->type = TYPE_PROBE;
  rimeaddr_copy(&hdr->sender, &rimeaddr_node_addr);
  rimeaddr_copy(&hdr->receiver, packetbuf_addr(PACKETBUF_ADDR_RECEIVER));


  /* Construct the announcements */
  adata = (struct announcement_msg *)((char *)hdr + sizeof(struct lpp_hdr));
  
  adata->num = 0;
  for(a = announcement_list(); a != NULL; a = a->next) {
    adata->data[adata->num].id = a->id;
    adata->data[adata->num].value = a->value;
    adata->num++;
  }

  packetbuf_set_datalen(sizeof(struct lpp_hdr) +
		      ANNOUNCEMENT_MSG_HEADERLEN +
		      sizeof(struct announcement_data) * adata->num);

  /*  PRINTF("Sending probe\n");*/

  /*  printf("probe\n");*/
  
  /* XXX should first check access to the medium (CCA - Clear Channel
     Assessment) and add LISTEN_TIME to off_time_adjustment if there
     is a packet in the air. */
  radio->send(packetbuf_hdrptr(), packetbuf_totlen());

  compower_accumulate(&compower_idle_activity);
}
Esempio n. 16
0
/*---------------------------------------------------------------------------*/
int
mac_sequence_is_duplicate(void)
{
    int i;

    /*
     * Check for duplicate packet by comparing the sequence number of the incoming
     * packet with the last few ones we saw.
     */
    for(i = 0; i < MAX_SEQNOS; ++i) {
        if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
                        &received_seqnos[i].sender)) {
            if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO) == received_seqnos[i].seqno) {
                /* Duplicate packet. */
                return 1;
            }
            break;
        }
    }
    return 0;
}
Esempio n. 17
0
/*---------------------------------------------------------------------------*/
static int
send_packet(void)
{
  const rimeaddr_t *addr;

  addr = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
  PRINTF("rime-udp: Sending %d bytes to %d.%d\n", packetbuf_totlen(),
         addr->u8[RIMEADDR_SIZE-2], addr->u8[RIMEADDR_SIZE-1]);

  if(rimeaddr_cmp(&rimeaddr_null, addr)) {
    uip_udp_packet_send(broadcast_conn,
                        packetbuf_hdrptr(), packetbuf_totlen());
  } else {
    uip_ip6addr(&unicast_conn->ripaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
    uip_netif_addr_autoconf_set(&unicast_conn->ripaddr, (uip_lladdr_t *)addr);
    uip_udp_packet_send(unicast_conn,
                        packetbuf_hdrptr(), packetbuf_totlen());
    uip_create_unspecified(&unicast_conn->ripaddr);
  }
  return 1;
}
Esempio n. 18
0
/*---------------------------------------------------------------------------*/
void
uip_ds6_link_neighbor_callback(int status, int numtx)
{
  const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
  if(linkaddr_cmp(dest, &linkaddr_null)) {
    return;
  }

  LINK_NEIGHBOR_CALLBACK(dest, status, numtx);

#if UIP_DS6_LL_NUD
  /* From RFC4861, page 72, last paragraph of section 7.3.3:
   *
   *         "In some cases, link-specific information may indicate that a path to
   *         a neighbor has failed (e.g., the resetting of a virtual circuit). In
   *         such cases, link-specific information may be used to purge Neighbor
   *         Cache entries before the Neighbor Unreachability Detection would do
   *         so. However, link-specific information MUST NOT be used to confirm
   *         the reachability of a neighbor; such information does not provide
   *         end-to-end confirmation between neighboring IP layers."
   *
   * However, we assume that receiving a link layer ack ensures the delivery
   * of the transmitted packed to the IP stack of the neighbour. This is a
   * fair assumption and allows battery powered nodes save some battery by
   * not re-testing the state of a neighbour periodically if it
   * acknowledges link packets. */
  if(status == MAC_TX_OK) {
    uip_ds6_nbr_t *nbr;
    nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
    if(nbr != NULL && nbr->state != NBR_INCOMPLETE) {
      nbr->state = NBR_REACHABLE;
      stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
      PRINTF("uip-ds6-neighbor : received a link layer ACK : ");
      PRINTLLADDR((uip_lladdr_t *)dest);
      PRINTF(" is reachable.\n");
    }
  }
#endif /* UIP_DS6_LL_NUD */

}
Esempio n. 19
0
/*---------------------------------------------------------------------------*/
static void
send_packet(mac_callback_t sent_callback, void *ptr)
{
  const rimeaddr_t *addr;

  addr = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
  PRINTF("rime-udp: Sending %d bytes to %d.%d\n", packetbuf_totlen(),
         addr->u8[0], addr->u8[1]);

  if(rimeaddr_cmp(&rimeaddr_null, addr)) {
    uip_udp_packet_send(broadcast_conn,
                        packetbuf_hdrptr(), packetbuf_totlen());
    mac_call_sent_callback(sent_callback, ptr, MAC_TX_OK, 1);
  } else {
    uip_ip6addr(&unicast_conn->ripaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
    uip_netif_addr_autoconf_set(&unicast_conn->ripaddr, (uip_lladdr_t *)addr);
    uip_udp_packet_send(unicast_conn,
                        packetbuf_hdrptr(), packetbuf_totlen());
    uip_create_unspecified(&unicast_conn->ripaddr);
  }
  return;
}
Esempio n. 20
0
/*---------------------------------------------------------------------------*/
void
serial_lprf_mac_rf_input(void)
{
	uint8_t bufCnt, *bufPtr = packetbuf_dataptr();
#if (DEVICE_MODE == SERIAL_LPRF_MAC)
	uint8_t *addrPtr;
#endif
	
	PUTSTRING("Data Received : ");
	PUTSTRING(bufPtr);
	PUTSTRING("\n");
	leds_toggle(LEDS_RED);
#if (DEVICE_MODE == SERIAL_LPRF_MAC)
	putchar(SERIAL_LPRF_MAC_PACKET_START_BYTE);
	putchar(packetbuf_datalen() + 1 + 8);
	putchar('R');
	addrPtr = (uint8_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER);
	for(bufCnt = 0; bufCnt < 8; bufCnt++)
		putchar( * (addrPtr  + bufCnt));
	for(bufCnt = 0; bufCnt < packetbuf_datalen(); bufCnt++)
		putchar( * (bufPtr + bufCnt));
#endif
}
static int
parse_announcements(void)
{
  /* Parse incoming announcements */
  struct announcement_msg adata;
  const rimeaddr_t *from;
  int i;

  memcpy(&adata, packetbuf_dataptr(),
         MIN(packetbuf_datalen(), sizeof(adata)));
  from = packetbuf_addr(PACKETBUF_ADDR_SENDER);

  /*  printf("%d.%d: probe from %d.%d with %d announcements\n",
     rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
     from->u8[0], from->u8[1], adata.num); */
  /*  for(i = 0; i < packetbuf_datalen(); ++i) {
     printf("%02x ", ((uint8_t *)packetbuf_dataptr())[i]);
     }
     printf("\n"); */

  if(adata.num / sizeof(struct announcement_data) > sizeof(struct announcement_msg)) {
    /* Sanity check. The number of announcements is too large -
       corrupt packet has been received. */
    return 0;
  }

  for(i = 0; i < adata.num; ++i) {
    /*    printf("%d.%d: announcement %d: %d\n",
       rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
       adata.data[i].id,
       adata.data[i].value); */

    announcement_heard(from, adata.data[i].id, adata.data[i].value);
  }
  return i;
}
Esempio n. 22
0
/*---------------------------------------------------------------------------*/
static void recv_from_abc(struct abc_conn *bc)
{

	if (bc == NULL)
	{
		PRINTF("[pbroadcast.c] Error: ABC Connection is NULL\n");
		return;
	}

	linkaddr_t sender;
	struct p_broadcast_conn *c = (struct p_broadcast_conn *)bc;

	linkaddr_copy(&sender, packetbuf_addr(PACKETBUF_ADDR_SENDER));

	uint16_t actual_hash = packet_hash(packetbuf_dataptr(), packetbuf_datalen() - sizeof(uint16_t));
	uint8_t *hash_ptr = packetbuf_dataptr() + (uintptr_t)(packetbuf_datalen() - sizeof(uint16_t));
	uint16_t transmitted_hash = (hash_ptr[1] << 8) + (hash_ptr[0]);

	PRINTF("[pbroadcast.c] Received message of size %d from %d.%d.\n", packetbuf_datalen() - sizeof(uint16_t), sender.u8[0], sender.u8[1]);
	PRINTF("[pbroadcast.c] ^ Data: ");
	DEBUG_DUMP_DATA(packetbuf_dataptr(), packetbuf_datalen());
	PRINTF("\n");

	PRINTF("[pbroadcast.c] ^ Hash: %02X\n", transmitted_hash);

	if (actual_hash != transmitted_hash)
	{
		PRINTF("[pbroadcast.c] ^ Incorrect hash (expected %02X, but is %02X); discarding received packet.\n", transmitted_hash, actual_hash);
		return;
	}

	if (c->received)
	{
		c->received(c, &sender, packetbuf_dataptr(), packetbuf_datalen() - sizeof(uint16_t));
	}
}
Esempio n. 23
0
/*---------------------------------------------------------------------------*/
static void
input_packet(void)
{
  static struct ctimer ct;
  if(!we_are_receiving_burst) {
    off();
  }

  /*  printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/

#ifdef NETSTACK_DECRYPT
  NETSTACK_DECRYPT();
#endif /* NETSTACK_DECRYPT */

  if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) {

#if WITH_CONTIKIMAC_HEADER
    struct hdr *chdr;
    chdr = packetbuf_dataptr();
    if(chdr->id != CONTIKIMAC_ID) {
      PRINTF("contikimac: failed to parse hdr (%u)\n", packetbuf_totlen());
      return;
    }
    packetbuf_hdrreduce(sizeof(struct hdr));
    packetbuf_set_datalen(chdr->len);
#endif /* WITH_CONTIKIMAC_HEADER */

    if(packetbuf_datalen() > 0 &&
       packetbuf_totlen() > 0 &&
       (rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
                     &rimeaddr_node_addr) ||
        rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
                     &rimeaddr_null))) {
      /* This is a regular packet that is destined to us or to the
         broadcast address. */

      /* If FRAME_PENDING is set, we are receiving a packets in a burst */
      we_are_receiving_burst = packetbuf_attr(PACKETBUF_ATTR_PENDING);
      if(we_are_receiving_burst) {
        on();
        /* Set a timer to turn the radio off in case we do not receive
	   a next packet */
        ctimer_set(&ct, INTER_PACKET_DEADLINE, recv_burst_off, NULL);
      } else {
        off();
        ctimer_stop(&ct);
      }

      /* Check for duplicate packet by comparing the sequence number
         of the incoming packet with the last few ones we saw. */
      {
        int i;
        for(i = 0; i < MAX_SEQNOS; ++i) {
          if(packetbuf_attr(PACKETBUF_ATTR_PACKET_ID) == received_seqnos[i].seqno &&
             rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
                          &received_seqnos[i].sender)) {
            /* Drop the packet. */
            /*        printf("Drop duplicate ContikiMAC layer packet\n");*/
            return;
          }
        }
        for(i = MAX_SEQNOS - 1; i > 0; --i) {
          memcpy(&received_seqnos[i], &received_seqnos[i - 1],
                 sizeof(struct seqno));
        }
        received_seqnos[0].seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
        rimeaddr_copy(&received_seqnos[0].sender,
                      packetbuf_addr(PACKETBUF_ADDR_SENDER));
      }

#if CONTIKIMAC_CONF_COMPOWER
      /* Accumulate the power consumption for the packet reception. */
      compower_accumulate(&current_packet);
      /* Convert the accumulated power consumption for the received
         packet to packet attributes so that the higher levels can
         keep track of the amount of energy spent on receiving the
         packet. */
      compower_attrconv(&current_packet);

      /* Clear the accumulated power consumption so that it is ready
         for the next packet. */
      compower_clear(&current_packet);
#endif /* CONTIKIMAC_CONF_COMPOWER */

      PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen());
      NETSTACK_MAC.input();
      return;
    } else {
      PRINTDEBUG("contikimac: data not for us\n");
    }
  } else {
    PRINTF("contikimac: failed to parse (%u)\n", packetbuf_totlen());
  }
}
Esempio n. 24
0
/*---------------------------------------------------------------------------*/
static int
send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
	    struct rdc_buf_list *buf_list,
            int is_receiver_awake)
{
  rtimer_clock_t t0;
  rtimer_clock_t encounter_time = 0;
  int strobes;
  uint8_t got_strobe_ack = 0;
  int hdrlen, len;
  uint8_t is_broadcast = 0;
  uint8_t is_reliable = 0;
  uint8_t is_known_receiver = 0;
  uint8_t collisions;
  int transmit_len;
  int ret;
  uint8_t contikimac_was_on;
  uint8_t seqno;
#if WITH_CONTIKIMAC_HEADER
  struct hdr *chdr;
#endif /* WITH_CONTIKIMAC_HEADER */

  /* Exit if RDC and radio were explicitly turned off */
   if(!contikimac_is_on && !contikimac_keep_radio_on) {
    PRINTF("contikimac: radio is turned off\n");
    return MAC_TX_ERR_FATAL;
  }
 
  if(packetbuf_totlen() == 0) {
    PRINTF("contikimac: send_packet data len 0\n");
    return MAC_TX_ERR_FATAL;
  }

#if !NETSTACK_CONF_BRIDGE_MODE
  /* If NETSTACK_CONF_BRIDGE_MODE is set, assume PACKETBUF_ADDR_SENDER is already set. */
  packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &rimeaddr_node_addr);
#endif
  if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
    is_broadcast = 1;
    PRINTDEBUG("contikimac: send broadcast\n");

    if(broadcast_rate_drop()) {
      return MAC_TX_COLLISION;
    }
  } else {
#if UIP_CONF_IPV6
    PRINTDEBUG("contikimac: send unicast to %02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
               packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
               packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1],
               packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[2],
               packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[3],
               packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[4],
               packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[5],
               packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[6],
               packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[7]);
#else /* UIP_CONF_IPV6 */
    PRINTDEBUG("contikimac: send unicast to %u.%u\n",
               packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
               packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[1]);
#endif /* UIP_CONF_IPV6 */
  }
  is_reliable = packetbuf_attr(PACKETBUF_ATTR_RELIABLE) ||
    packetbuf_attr(PACKETBUF_ATTR_ERELIABLE);

  packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);

#if WITH_CONTIKIMAC_HEADER
  hdrlen = packetbuf_totlen();
  if(packetbuf_hdralloc(sizeof(struct hdr)) == 0) {
    /* Failed to allocate space for contikimac header */
    PRINTF("contikimac: send failed, too large header\n");
    return MAC_TX_ERR_FATAL;
  }
  chdr = packetbuf_hdrptr();
  chdr->id = CONTIKIMAC_ID;
  chdr->len = hdrlen;
  
  /* Create the MAC header for the data packet. */
  hdrlen = NETSTACK_FRAMER.create();
  if(hdrlen < 0) {
    /* Failed to send */
    PRINTF("contikimac: send failed, too large header\n");
    packetbuf_hdr_remove(sizeof(struct hdr));
    return MAC_TX_ERR_FATAL;
  }
  hdrlen += sizeof(struct hdr);
#else
  /* Create the MAC header for the data packet. */
  hdrlen = NETSTACK_FRAMER.create();
  if(hdrlen < 0) {
    /* Failed to send */
    PRINTF("contikimac: send failed, too large header\n");
    return MAC_TX_ERR_FATAL;
  }
#endif

  /* Make sure that the packet is longer or equal to the shortest
     packet length. */
  transmit_len = packetbuf_totlen();
  if(transmit_len < SHORTEST_PACKET_SIZE) {
    /* Pad with zeroes */
    uint8_t *ptr;
    ptr = packetbuf_dataptr();
    memset(ptr + packetbuf_datalen(), 0, SHORTEST_PACKET_SIZE - packetbuf_totlen());

    PRINTF("contikimac: shorter than shortest (%d)\n", packetbuf_totlen());
    transmit_len = SHORTEST_PACKET_SIZE;
  }


  packetbuf_compact();

#ifdef NETSTACK_ENCRYPT
  NETSTACK_ENCRYPT();
#endif /* NETSTACK_ENCRYPT */

  transmit_len = packetbuf_totlen();

  NETSTACK_RADIO.prepare(packetbuf_hdrptr(), transmit_len);

  /* Remove the MAC-layer header since it will be recreated next time around. */
  packetbuf_hdr_remove(hdrlen);

  if(!is_broadcast && !is_receiver_awake) {
#if WITH_PHASE_OPTIMIZATION
    ret = phase_wait(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
                     CYCLE_TIME, GUARD_TIME,
                     mac_callback, mac_callback_ptr, buf_list);
    if(ret == PHASE_DEFERRED) {
      return MAC_TX_DEFERRED;
    }
    if(ret != PHASE_UNKNOWN) {
      is_known_receiver = 1;
    }
#endif /* WITH_PHASE_OPTIMIZATION */ 
  }
  


  /* By setting we_are_sending to one, we ensure that the rtimer
     powercycle interrupt do not interfere with us sending the packet. */
  we_are_sending = 1;

  /* If we have a pending packet in the radio, we should not send now,
     because we will trash the received packet. Instead, we signal
     that we have a collision, which lets the packet be received. This
     packet will be retransmitted later by the MAC protocol
     instread. */
  if(NETSTACK_RADIO.receiving_packet() || NETSTACK_RADIO.pending_packet()) {
    we_are_sending = 0;
    PRINTF("contikimac: collision receiving %d, pending %d\n",
           NETSTACK_RADIO.receiving_packet(), NETSTACK_RADIO.pending_packet());
    return MAC_TX_COLLISION;
  }
  
  /* Switch off the radio to ensure that we didn't start sending while
     the radio was doing a channel check. */
  off();


  strobes = 0;

  /* Send a train of strobes until the receiver answers with an ACK. */
  collisions = 0;

  got_strobe_ack = 0;

  /* Set contikimac_is_on to one to allow the on() and off() functions
     to control the radio. We restore the old value of
     contikimac_is_on when we are done. */
  contikimac_was_on = contikimac_is_on;
  contikimac_is_on = 1;

#if !RDC_CONF_HARDWARE_CSMA
    /* Check if there are any transmissions by others. */
    /* TODO: why does this give collisions before sending with the mc1322x? */
  if(is_receiver_awake == 0) {
    int i;
    for(i = 0; i < CCA_COUNT_MAX_TX; ++i) {
      t0 = RTIMER_NOW();
      on();
#if CCA_CHECK_TIME > 0
      while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_CHECK_TIME)) { }
#endif
      if(NETSTACK_RADIO.channel_clear() == 0) {
        collisions++;
        off();
        break;
      }
      off();
      t0 = RTIMER_NOW();
      while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CCA_SLEEP_TIME)) { }
    }
  }

  if(collisions > 0) {
    we_are_sending = 0;
    off();
    PRINTF("contikimac: collisions before sending\n");
    contikimac_is_on = contikimac_was_on;
    return MAC_TX_COLLISION;
  }
#endif /* RDC_CONF_HARDWARE_CSMA */

#if !RDC_CONF_HARDWARE_ACK
  if(!is_broadcast) {
    /* Turn radio on to receive expected unicast ack.  Not necessary
       with hardware ack detection, and may trigger an unnecessary cca
       or rx cycle */
     on();
  }
#endif

  watchdog_periodic();
  t0 = RTIMER_NOW();
  seqno = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);
  for(strobes = 0, collisions = 0;
      got_strobe_ack == 0 && collisions == 0 &&
      RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + STROBE_TIME); strobes++) {

    watchdog_periodic();

    if(!is_broadcast && (is_receiver_awake || is_known_receiver) &&
       !RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + MAX_PHASE_STROBE_TIME)) {
      PRINTF("miss to %d\n", packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0]);
      break;
    }

    len = 0;

    {
      rtimer_clock_t wt;
      rtimer_clock_t txtime;
      int ret;

      txtime = RTIMER_NOW();
      ret = NETSTACK_RADIO.transmit(transmit_len);

#if RDC_CONF_HARDWARE_ACK
     /* For radios that block in the transmit routine and detect the
	ACK in hardware */
      if(ret == RADIO_TX_OK) {
        if(!is_broadcast) {
          got_strobe_ack = 1;
          encounter_time = txtime;
          break;
        }
      } else if (ret == RADIO_TX_NOACK) {
      } else if (ret == RADIO_TX_COLLISION) {
          PRINTF("contikimac: collisions while sending\n");
          collisions++;
      }
      wt = RTIMER_NOW();
      while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { }
#else /* RDC_CONF_HARDWARE_ACK */
     /* Wait for the ACK packet */
      wt = RTIMER_NOW();
      while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + INTER_PACKET_INTERVAL)) { }

      if(!is_broadcast && (NETSTACK_RADIO.receiving_packet() ||
                           NETSTACK_RADIO.pending_packet() ||
                           NETSTACK_RADIO.channel_clear() == 0)) {
        uint8_t ackbuf[ACK_LEN];
        wt = RTIMER_NOW();
        while(RTIMER_CLOCK_LT(RTIMER_NOW(), wt + AFTER_ACK_DETECTECT_WAIT_TIME)) { }

        len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
        if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) {
          got_strobe_ack = 1;
          encounter_time = txtime;
          break;
        } else {
          PRINTF("contikimac: collisions while sending\n");
          collisions++;
        }
      }
#endif /* RDC_CONF_HARDWARE_ACK */
    }
  }

  off();

  PRINTF("contikimac: send (strobes=%u, len=%u, %s, %s), done\n", strobes,
         packetbuf_totlen(),
         got_strobe_ack ? "ack" : "no ack",
         collisions ? "collision" : "no collision");

#if CONTIKIMAC_CONF_COMPOWER
  /* Accumulate the power consumption for the packet transmission. */
  compower_accumulate(&current_packet);

  /* Convert the accumulated power consumption for the transmitted
     packet to packet attributes so that the higher levels can keep
     track of the amount of energy spent on transmitting the
     packet. */
  compower_attrconv(&current_packet);

  /* Clear the accumulated power consumption so that it is ready for
     the next packet. */
  compower_clear(&current_packet);
#endif /* CONTIKIMAC_CONF_COMPOWER */

  contikimac_is_on = contikimac_was_on;
  we_are_sending = 0;

  /* Determine the return value that we will return from the
     function. We must pass this value to the phase module before we
     return from the function.  */
  if(collisions > 0) {
    ret = MAC_TX_COLLISION;
  } else if(!is_broadcast && !got_strobe_ack) {
    ret = MAC_TX_NOACK;
  } else {
    ret = MAC_TX_OK;
  }

#if WITH_PHASE_OPTIMIZATION
  if(is_known_receiver && got_strobe_ack) {
    PRINTF("no miss %d wake-ups %d\n",
	   packetbuf_addr(PACKETBUF_ADDR_RECEIVER)->u8[0],
           strobes);
  }

  if(!is_broadcast) {
    if(collisions == 0 && is_receiver_awake == 0) {
      phase_update(&phase_list, packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
		   encounter_time, ret);
    }
  }
#endif /* WITH_PHASE_OPTIMIZATION */

  return ret;
}
Esempio n. 25
0
/*---------------------------------------------------------------------------*/
static int
create_frame(int type, int do_create)
{
  frame802154_t params;
  int hdr_len;

  /* init to zeros */
  memset(&params, 0, sizeof(params));

  if(!initialized) {
    initialized = 1;
    mac_dsn = random_rand() & 0xff;
  }

  /* Build the FCF. */
  params.fcf.frame_type = packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE);
  params.fcf.frame_pending = packetbuf_attr(PACKETBUF_ATTR_PENDING);
  if(packetbuf_holds_broadcast()) {
    params.fcf.ack_required = 0;
  } else {
    params.fcf.ack_required = packetbuf_attr(PACKETBUF_ATTR_MAC_ACK);
  }
  params.fcf.panid_compression = 0;

  /* Insert IEEE 802.15.4 (2006) version bits. */
  params.fcf.frame_version = FRAME802154_IEEE802154_2006;
  
#if LLSEC802154_SECURITY
  if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL)) {
    params.fcf.security_enabled = 1;
  }
  /* Setting security-related attributes */
  params.aux_hdr.security_control.security_level = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
  params.aux_hdr.frame_counter.u16[0] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1);
  params.aux_hdr.frame_counter.u16[1] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3);
#if LLSEC802154_USES_EXPLICIT_KEYS
  params.aux_hdr.security_control.key_id_mode = packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE);
  params.aux_hdr.key_index = packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX);
  params.aux_hdr.key_source.u16[0] = packetbuf_attr(PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
#endif /* LLSEC802154_SECURITY */

  /* Increment and set the data sequence number. */
  if(!do_create) {
    /* Only length calculation - no sequence number is needed and
       should not be consumed. */

  } else if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO)) {
    params.seq = packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO);

  } else {
    /* Ensure that the sequence number 0 is not used as it would bypass the above check. */
    if(mac_dsn == 0) {
      mac_dsn++;
    }
    params.seq = mac_dsn++;
    packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, params.seq);
  }

  /* Complete the addressing fields. */
  /**
     \todo For phase 1 the addresses are all long. We'll need a mechanism
     in the rime attributes to tell the mac to use long or short for phase 2.
  */
  if(LINKADDR_SIZE == 2) {
    /* Use short address mode if linkaddr size is short. */
    params.fcf.src_addr_mode = FRAME802154_SHORTADDRMODE;
  } else {
    params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
  }
  params.dest_pid = mac_dst_pan_id;

  if(packetbuf_holds_broadcast()) {
    /* Broadcast requires short address mode. */
    params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    params.dest_addr[0] = 0xFF;
    params.dest_addr[1] = 0xFF;

  } else {
    linkaddr_copy((linkaddr_t *)&params.dest_addr,
                  packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
    /* Use short address mode if linkaddr size is small */
    if(LINKADDR_SIZE == 2) {
      params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
    } else {
      params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
    }
  }

  /* Set the source PAN ID to the global variable. */
  params.src_pid = mac_src_pan_id;

  /*
   * Set up the source address using only the long address mode for
   * phase 1.
   */
  linkaddr_copy((linkaddr_t *)&params.src_addr,
                packetbuf_addr(PACKETBUF_ADDR_SENDER));

  params.payload = packetbuf_dataptr();
  params.payload_len = packetbuf_datalen();
  hdr_len = frame802154_hdrlen(&params);
  if(!do_create) {
    /* Only calculate header length */
    return hdr_len;

  } else if(packetbuf_hdralloc(hdr_len)) {
    frame802154_create(&params, packetbuf_hdrptr());

    PRINTF("15.4-OUT: %2X", params.fcf.frame_type);
    PRINTADDR(params.dest_addr);
    PRINTF("%d %u (%u)\n", hdr_len, packetbuf_datalen(), packetbuf_totlen());

    return hdr_len;
  } else {
    PRINTF("15.4-OUT: too large header: %u\n", hdr_len);
    return FRAMER_FAILED;
  }
}
Esempio n. 26
0
/*---------------------------------------------------------------------------*/
static void
send_packet(mac_callback_t sent, void *ptr)
{
  struct rdc_buf_list *q;
  struct neighbor_queue *n;
  static uint8_t initialized = 0;
  static uint16_t seqno;
  const rimeaddr_t *addr = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);

  if(!initialized) {
    initialized = 1;
    /* Initialize the sequence number to a random value as per 802.15.4. */
    seqno = random_rand();
  }

  if(seqno == 0) {
    /* PACKETBUF_ATTR_MAC_SEQNO cannot be zero, due to a pecuilarity
       in framer-802154.c. */
    seqno++;
  }
  packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, seqno++);

  /* Look for the neighbor entry */
  n = neighbor_queue_from_addr(addr);
  if(n == NULL) {
    /* Allocate a new neighbor entry */
    n = memb_alloc(&neighbor_memb);
    if(n != NULL) {
      /* Init neighbor entry */
      rimeaddr_copy(&n->addr, addr);
      n->transmissions = 0;
      n->collisions = 0;
      n->deferrals = 0;
      /* Init packet list for this neighbor */
      LIST_STRUCT_INIT(n, queued_packet_list);
      /* Add neighbor to the list */
      list_add(neighbor_list, n);
    }
  }

  if(n != NULL) {
    /* Add packet to the neighbor's queue */
    q = memb_alloc(&packet_memb);
    if(q != NULL) {
      q->ptr = memb_alloc(&metadata_memb);
      if(q->ptr != NULL) {
	q->buf = queuebuf_new_from_packetbuf();
	if(q->buf != NULL) {
	  struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr;
	  /* Neighbor and packet successfully allocated */
	  if(packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) {
	    /* Use default configuration for max transmissions */
	    metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS;
	  } else {
	    metadata->max_transmissions =
                  packetbuf_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS);
	  }
	  metadata->sent = sent;
	  metadata->cptr = ptr;

	  if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
	     PACKETBUF_ATTR_PACKET_TYPE_ACK) {
	    list_push(n->queued_packet_list, q);
	  } else {
	    list_add(n->queued_packet_list, q);
	  }

	  /* If q is the first packet in the neighbor's queue, send asap */
	  if(list_head(n->queued_packet_list) == q) {
	    ctimer_set(&n->transmit_timer, 0, transmit_packet_list, n);
	  }
	  return;
	}
	memb_free(&metadata_memb, q->ptr);
	PRINTF("csma: could not allocate queuebuf, dropping packet\n");
      }
      memb_free(&packet_memb, q);
      PRINTF("csma: could not allocate queuebuf, dropping packet\n");
    }
    /* The packet allocation failed. Remove and free neighbor entry if empty. */
    if(list_length(n->queued_packet_list) == 0) {
      list_remove(neighbor_list, n);
      memb_free(&neighbor_memb, n);
    }
    PRINTF("csma: could not allocate packet, dropping packet\n");
  } else {
    PRINTF("csma: could not allocate neighbor, dropping packet\n");
  }
  mac_call_sent_callback(sent, ptr, MAC_TX_ERR, 1);
}
Esempio n. 27
0
/**
 * \brief Take a packet received over the 802.15.4 link, and send it
 * out over ethernet, performing any translations needed.
 */
void mac_LowpanToEthernet(void)
{
#if !RF230BB && !RF212BB
  parsed_frame = sicslowmac_get_frame();
#endif

  //Setup generic ethernet stuff
  ETHBUF(uip_buf)->type = uip_htons(UIP_ETHTYPE_IPV6);

  //Check for broadcast message
  
#if RF230BB || RF212BB
  if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null)) {
//  if(rimeaddr_cmp((const rimeaddr_t *)destAddr, &rimeaddr_null)) {
#else
  if(  ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) &&
       ( parsed_frame->dest_addr->addr16 == 0xffff) ) {
#endif
    ETHBUF(uip_buf)->dest.addr[0] = 0x33;
    ETHBUF(uip_buf)->dest.addr[1] = 0x33;

#if UIP_CONF_IPV6
    ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
    ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
    ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
    ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
#else
	//Not intended to be functional, but allows ip4 build without errors.
    ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[0];
    ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[1];
    ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[2];
    ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[3];
#endif
  } else {
	//Otherwise we have a real address
	mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->dest.addr[0]),
                        (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
  }

#if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
  //Source ethernet depends on node
  if(!mac_createEthernetAddr(
    (uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]),
    (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)
  ))
#endif

  {
    mac_createDefaultEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]));
  }

  //We only do address translation in network mode!
  if (usbstick_mode.translate) {
    //Some IP packets have link layer in them, need to change them around!
    mac_translateIPLinkLayer(ll_8023_type);
  }
 
#if UIP_CONF_IPV6_RPL
/* We won't play ping-pong with the host! */
    if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) {
        PRINTF("siclow_ethernet: Destination off-link but no route\n");
        uip_len=0;
        return;
    }
#endif

  PRINTF("Low2Eth: Sending packet to ethernet\n\r");

  uip_len += UIP_LLH_LEN;
  if (usbstick_mode.raw == 0)
	  usb_eth_send(uip_buf, uip_len, 1);
#if !RF230BB && !RF212BB
  usb_eth_stat.rxok++;
#endif
  uip_len = 0;
}

/**
 * \brief Translate IP packet's possible link-layer addresses, passing
 *        the message to the appropriate higher level function for this
 *        packet (aka: ICMP)
 * \param target The target we want to end up with - either ll_8023_type
 *        for ethernet, or ll_802154_type for 802.15.4
 * \return    Returns how successful the translation was
 * \retval 0  Addresses, if present, were translated.
 * \retval <0 Negative return values indicate various errors, as defined
 *            by the higher level function.
 */
int8_t mac_translateIPLinkLayer(lltype_t target)
{

#if UIP_LLADDR_LEN == 8
  if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
    PRINTF("eth2low: ICMP Message detected\n\r");
    return mac_translateIcmpLinkLayer(target);
  }
  return 0;
#else
  return 1;
#endif

}

#include "net/uip-icmp6.h"
#include "net/uip-nd6.h"

typedef struct {
  uint8_t type;
  uint8_t length;
  uint8_t data[16];
} icmp_opts_t;

#define UIP_ICMP_BUF     ((struct uip_icmp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
#define UIP_ICMP_OPTS(x) ((icmp_opts_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + x])

void slide(uint8_t * data, uint8_t length, int16_t slide);

/**
 * \brief Translate the link-layer (L2) addresses in an ICMP packet.
 *        This will just be NA/NS/RA/RS packets currently.
 * \param target The target we want to end up with - either ll_8023_type
 *        for ethernet, or ll_802154_type for 802.15.4
 * \return       Returns how successful the translation was
 * \retval 0     Addresses, if present, were translated.
 * \retval -1    ICMP message was unknown type, nothing done.
 * \retval -2    ICMP Length does not make sense?
 * \retval -3    Unknown 'target' type
 */
int8_t mac_translateIcmpLinkLayer(lltype_t target)
{
  uint16_t icmp_opt_offset = 0;
  int16_t len = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0] << 8);

  uint16_t iplen;

  uint8_t i;

  int16_t sizechange;

  uint8_t llbuf[16];

  //Figure out offset to start of options
  switch(UIP_ICMP_BUF->type) {
    case ICMP6_NS:
    case ICMP6_NA:
      icmp_opt_offset = 24;
      break;

    case ICMP6_RS:
      icmp_opt_offset = 8;
      break;

    case ICMP6_RA:
      icmp_opt_offset = 16;
      break;

    case ICMP6_REDIRECT:
      icmp_opt_offset = 40;
      break;

      /** Things without link-layer */
    case ICMP6_DST_UNREACH:
    case ICMP6_PACKET_TOO_BIG:
    case ICMP6_TIME_EXCEEDED:	
    case ICMP6_PARAM_PROB:
    case ICMP6_ECHO_REQUEST:  
    case ICMP6_ECHO_REPLY: 
      return 0;
      break;

    default:
      return -1;
  }

  //Figure out length of options
  len -= icmp_opt_offset;

  //Sanity check
  if (len < 8) return -2; 

  //While we have options to do...
  while (len >= 8){
    
    //If we have one of these, we have something useful!
    if (((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_SLLAO) || 
        ((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_TLLAO) ) {
      
      /* Shrinking the buffer may thrash things, so we store the old
         link-layer address */
      for(i = 0; i < (UIP_ICMP_OPTS(icmp_opt_offset)->length*8 - 2); i++) {
        llbuf[i] = UIP_ICMP_OPTS(icmp_opt_offset)->data[i];
      }

      //Shrink/grow buffer as needed
      if (target == ll_802154_type) {
        //Current is 802.3, Hence current link-layer option is 6 extra bytes
        sizechange = 8;
        slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 6, len - 6, sizechange);
      } else if (target == ll_8023_type) {
        /* Current is 802.15.4, Hence current link-layer option is 14 extra
         * bytes.
         * (Actual LL is 8 bytes, but total option length is in multiples of
         * 8 Bytes, hence 8 + 2 = 10. Closest is 16 bytes, then 16 bytes for
         * total optional length - 2 bytes for type + length leaves 14 )
         */
        sizechange = -8;
        slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 14, len - 14, sizechange);
      } else {
        return -3; //Uh-oh!
      }
      
      //Translate addresses
      if (target == ll_802154_type) {
        mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data);
      } else {
#if !UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS
        if(!mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf))
#endif
            mac_createDefaultEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data);
      }
      
      //Adjust the length
      if (target == ll_802154_type) {
        UIP_ICMP_OPTS(icmp_opt_offset)->length = 2;
      } else {
        UIP_ICMP_OPTS(icmp_opt_offset)->length = 1;
      }

      //Adjust the IP header length, as well as uIP length
      iplen = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0]<<8);
      iplen += sizechange;
      len += sizechange;
      
      UIP_IP_BUF->len[1] = (uint8_t)iplen;
      UIP_IP_BUF->len[0] = (uint8_t)(iplen >> 8);

      uip_len += sizechange;

      //We broke ICMP checksum, be sure to fix that
      UIP_ICMP_BUF->icmpchksum = 0;
#if UIP_CONF_IPV6   //allow non ipv6 builds
      UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
#endif

      //Finally set up next run in while loop
      len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
      icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
    } else {
	  
      //Not an option we care about, ignore it
      len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
	      
      //This shouldn't happen!
      if (UIP_ICMP_OPTS(icmp_opt_offset)->length == 0) {
        PRINTF("Option in ND packet has length zero, error?\n\r");
        len = 0;
      }

      icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
      
    } //If ICMP_OPT is one we care about
   
  } //while(len >= 8)
Esempio n. 28
0
/*
 * BEACON_SD,		BEACON_SD_ACK 보내줌,
 * BEACON_SD_ACK, 	무시
 * BEACON_DS,		BEACON_DS_ACK 보내줌, c_wait set
 * BEACON_DS_ACK, 	무시
 * PREAMBLE,		power cycle data wait 모드
 * PREAMBLE_ACK, 	무시
 * PREAMBLE_ACK_DATA 	무시
 * DATA,			app 으로 올림,
 * DATA_ACK,		끝 아무것도 딱히 안해도됨
 * SYNC_START,		SYNC_REQ 전송, time stamp 찍어서
 * SYNC_REQ,		SYNC_ACK 전송, time stamp 찍어서
 * SYNC_ACK,		SYNC_END 전송, time stamp,  app 으로 올려서 계산
 * SYNC_END			app 으로 올림
 */
static void
plb_input(void)
{

if (NETSTACK_FRAMER.parse() >= 0) {
	if (rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
			&rimeaddr_node_addr)) {

#if DEBUG_PACKET
		print_packet(packetbuf_dataptr(),packetbuf_datalen());
#endif

		uint8_t type = ((uint8_t*) packetbuf_dataptr())[0];
		PRINTF("plb_input [src: %d.%d] [type: %x]\n", packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1], type);
		printf("plb_input [src: %d.%d] [type: %x]\n", packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[0],packetbuf_addr(PACKETBUF_ADDR_SENDER)->u8[1], type);

		switch (type) {
		case BEACON_SD:
			//		if( a_wait == 0 ){
			plb_send_ack(BEACON_SD_ACK);
//			a_wait = 1;
			//		}
			break;
		case BEACON_DS:
			//		if( c_wait == 0 ){
			plb_send_ack(BEACON_DS_ACK);
			c_wait = 1;
			//		}0x80
			break;
		case PREAMBLE:
			//		if (preamble_got == 0)	{
			if (has_data == 0) {
				plb_send_ack(PREAMBLE_ACK);
				wait_packet = 1;
			} else if (has_data == 1) {
				plb_send_ack(PREAMBLE_ACK_DATA);
			}
//			preamble_got = 1;
			//		}
			break;
		case DATA:
			NETSTACK_MAC.input();
			plb_send_ack(DATA_ACK);
			break;
		case SYNC_START:
			plb_send_sync(SYNC_REQ);
			break;
		case SYNC_REQ:
			break;
		case SYNC_ACK:
			plb_send_sync(SYNC_END);
			NETSTACK_MAC.input();
			break;
		case SYNC_END:
			NETSTACK_MAC.input();
			break;
		}
	} else{
//		PRINTF("THIS INPUT IS NOT FOR US\n");
	}
}
}
Esempio n. 29
0
/*---------------------------------------------------------------------------*/
static int
plb_send_data(mac_callback_t sent, void *ptr)
{

	PRINTF("plb_send_data\n");

	int ret; //what is it? JJH
	int last_sent_ok = 0;
	int acked;
	int temp=0;

	acked = 0;

	if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE)==0) //if packet_type ==0, DATA JJH_START
	{
		plb_send_strobe(packetbuf_addr(PACKETBUF_ADDR_NEXT),&acked,PREAMBLE);
		if(acked==1)
		{
			PRINTF("plb_send_data DATA_PREAMBLE_ACKED!\n");
			packetbuf_clear();
			packetbuf_copyfrom(dataptr_temp,temp_len);
			if (plb_create_header(packetbuf_addr(PACKETBUF_ADDR_NEXT),DATA) < 0)
			{
				PRINTF("ERROR: plb_create_header ");
				return -1; //ERROR case : -1
			}
//			hold_time(INTER_PACKET_INTERVAL * 5000); //future
			radio_on();
			PRINTF("plb_send_data send DATA packet\n");
			print_packet(packetbuf_hdrptr(), packetbuf_totlen());

			if(NETSTACK_RADIO.send(packetbuf_hdrptr(), packetbuf_totlen())!=RADIO_TX_OK)
			{
				PRINTF("plb_send_data DATA error!\n");
				return -1; //ERROR case
				ret = MAC_TX_ERR;
			}
			acked=plb_wait_data_ack(DATA); //just once?

			if(acked==1) //data ack received
			{
				PRINTF("plb_send_data DATA_ACKED!\n");
				last_sent_ok=1;
				ret=MAC_TX_OK;
			}
			else if(!acked)
			{
				PRINTF("plb_send_data DATA error: no ack!\n");
				ret=MAC_TX_ERR;
			}
			//sent connect
			mac_call_sent_callback(sent, ptr, ret, 1);
			radio_off();
			packetbuf_clear(); // add kdw
			return last_sent_ok;
		}
		else if(acked==2)//if receive preamble ack data
		{
			PRINTF("PREAMBLE ACK DATA RECEIVED!\n");
		}
		else//do not receive any ack, do nothing
		{
			PRINTF("DO NOT RECEIVED PREAMBLE ACK : error!!!\n");
		}

	}//JJH_END

	return 0;
}
Esempio n. 30
0
/*---------------------------------------------------------------------------*/
int
sicslowmac_dataRequest(void)
{

  _delay_ms(SICSLOW_CORRECTION_DELAY);

   /* create structure to store result. */
  frame_create_params_t params;
  frame_result_t result;

  /* Save the msduHandle in a global variable. */
  msduHandle = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);

  /* Build the FCF. */
  params.fcf.frameType = DATAFRAME;
  params.fcf.securityEnabled = false;
  params.fcf.framePending = false;
  params.fcf.ackRequired = packetbuf_attr(PACKETBUF_ATTR_RELIABLE);
  params.fcf.panIdCompression = false;

  /* Insert IEEE 802.15.4 (2003) version bit. */
  params.fcf.frameVersion = IEEE802154_2003;

  /* Increment and set the data sequence number. */
  params.seq = macDSN++;

  /* Complete the addressing fields. */
  /**
     \todo For phase 1 the addresses are all long. We'll need a mechanism
     in the rime attributes to tell the mac to use long or short for phase 2.
  */
  params.fcf.srcAddrMode = LONGADDRMODE;
  params.dest_pid = ieee15_4ManagerAddress.get_dst_panid();

  /*
   *  If the output address is NULL in the Rime buf, then it is broadcast
   *  on the 802.15.4 network.
   */
  if(rimeaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &rimeaddr_null) ) {
    /* Broadcast requires short address mode. */
    params.fcf.destAddrMode = SHORTADDRMODE;
    params.dest_pid = BROADCASTPANDID;
    params.dest_addr.addr16 = BROADCASTADDR;

  } else {

    /* Phase 1.5 - end nodes send to anyone? */
    memcpy(&params.dest_addr, (uint8_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER), LONG_ADDR_LEN);
	
    /* Change from sicslowpan byte arrangement to sicslowmac */
    byte_reverse((uint8_t*)&params.dest_addr.addr64, LONG_ADDR_LEN);

    /* Phase 1 - end nodes only sends to pan coordinator node. */
    /* params.dest_addr.addr64 = ieee15_4ManagerAddress.get_coord_long_addr(); */
    params.fcf.destAddrMode = LONGADDRMODE;
  }

  /* Set the source PAN ID to the global variable. */
  params.src_pid = ieee15_4ManagerAddress.get_src_panid();

  /*
   * Set up the source address using only the long address mode for
   * phase 1.
   */
  params.src_addr.addr64 = ieee15_4ManagerAddress.get_long_addr();

  /* Copy the payload data. */
  params.payload_len = packetbuf_datalen();
  params.payload =  packetbuf_dataptr();

  /* Create transmission frame. */
  frame_tx_create(&params, &result);
  
  /* Log if needed */
  LOG_FRAME(&params, &result);

  /* Retry up to this many times to send the packet if radio is busy */
  uint8_t retry_count = 3;

  while(retry_count) {

	  PRINTF("sicslowmac: sending packet of length %d to radio, result:", result.length);
	  
	    

	  /* Send data to radio. */
	  radio_status_t rv = radio_send_data(result.length, result.frame);

	  if (rv == RADIO_SUCCESS) {
	      PRINTF(" Success\n");

		  return 1; /* True says that the packet could be sent */
      }


	  if (rv != RADIO_WRONG_STATE) {
	      PRINTF(" Failed\n");
	  	  return 0;
      }

	  PRINTF(" Radio busy, retrying\n");

      /** \todo: Fix delay in sicslowmac so they do not block receiving */

       //We have blocking delay here, it is safest this way. BUT doesn't solve the
	   //problem of TX when you are RXing.. as the RX code can't execute!
	  if (retry_count == 3) {
	 	  _delay_ms(10);
	  } else if (retry_count == 2) {
	      _delay_ms(50);
	  } else if (retry_count == 1) {
	      _delay_ms(200);
	  }

	  retry_count--;
  }

  PRINTF("sicslowmac: Unable to send packet, dropped\n");
  return 0;

}