static struct net_buf *copy_buf(struct net_buf *mbuf)
{
  struct net_buf *buf;

  buf = ip_buf_get_reserve_rx(0);
  if(!buf) {
    return NULL;
  }

  /* Copy from the fragment context info buffer first */
  linkaddr_copy(&ip_buf_ll_dest(buf),
		packetbuf_addr(mbuf, PACKETBUF_ADDR_RECEIVER));
  linkaddr_copy(&ip_buf_ll_src(buf),
		packetbuf_addr(mbuf, PACKETBUF_ADDR_SENDER));

  PRINTF("%s: mbuf datalen %d dataptr %p buf %p\n", __FUNCTION__,
	  packetbuf_datalen(mbuf), packetbuf_dataptr(mbuf), uip_buf(buf));
  if(packetbuf_datalen(mbuf) > 0 &&
     packetbuf_datalen(mbuf) <= UIP_BUFSIZE - UIP_LLH_LEN) {
    memcpy(uip_buf(buf), packetbuf_dataptr(mbuf), packetbuf_datalen(mbuf));
    uip_len(buf) = packetbuf_datalen(mbuf);
    net_buf_add(buf, uip_len(buf));
  } else {
    ip_buf_unref(buf);
    buf = NULL;
  }

  return buf;
}
Beispiel #2
0
/*---------------------------------------------------------------------------*/
static void
send_rrep(struct route_discovery_conn *c, const linkaddr_t *dest)
{
  struct rrep_hdr *rrepmsg;
  struct route_entry *rt;
  linkaddr_t saved_dest;
  
  linkaddr_copy(&saved_dest, dest);

  packetbuf_clear();
  dest = &saved_dest;
  rrepmsg = packetbuf_dataptr();
  packetbuf_set_datalen(sizeof(struct rrep_hdr));
  rrepmsg->hops = 0;
  linkaddr_copy(&rrepmsg->dest, dest);
  linkaddr_copy(&rrepmsg->originator, &linkaddr_node_addr);
  rt = route_lookup(dest);
  if(rt != NULL) {
    PRINTF("%d.%d: send_rrep to %d.%d via %d.%d\n",
	   linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
	   dest->u8[0],dest->u8[1],
	   rt->nexthop.u8[0],rt->nexthop.u8[1]);
    unicast_send(&c->rrepconn, &rt->nexthop);
  } else {
    PRINTF("%d.%d: no route for rrep to %d.%d\n",
	   linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
	   dest->u8[0],dest->u8[1]);
  }
}
/* Copy all the fragments that are associated with a specific context into uip */
static struct net_buf *copy_frags2uip(int context)
{
  int i, total_len = 0;
  struct net_buf *buf;

  buf = ip_buf_get_reserve_rx(0);
  if(!buf) {
    return NULL;
  }

  /* Copy from the fragment context info buffer first */
  linkaddr_copy(&ip_buf_ll_dest(buf), &frag_info[context].receiver);
  linkaddr_copy(&ip_buf_ll_src(buf), &frag_info[context].sender);

  for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
    /* And also copy all matching fragments */
    if(frag_buf[i].len > 0 && frag_buf[i].index == context) {
      memcpy(uip_buf(buf) + (uint16_t)(frag_buf[i].offset << 3),
            (uint8_t *)frag_buf[i].data, frag_buf[i].len);
      total_len += frag_buf[i].len;
    }
  }
  net_buf_add(buf, total_len);
  uip_len(buf) = total_len;

  /* deallocate all the fragments for this context */
  clear_fragments(context);

  return buf;
}
Beispiel #4
0
/* Construct enhanced ACK packet and return ACK length */
int
tsch_packet_create_eack(uint8_t *buf, int buf_size,
                        linkaddr_t *dest_addr, uint8_t seqno, int16_t drift, int nack)
{
    int ret;
    uint8_t curr_len = 0;
    frame802154_t p;
    struct ieee802154_ies ies;

    memset(&p, 0, sizeof(p));
    p.fcf.frame_type = FRAME802154_ACKFRAME;
    p.fcf.frame_version = FRAME802154_IEEE802154E_2012;
    p.fcf.ie_list_present = 1;
    /* Compression unset. According to IEEE802.15.4e-2012:
     * - if no address is present: elide PAN ID
     * - if at least one address is present: include exactly one PAN ID (dest by default) */
    p.fcf.panid_compression = 0;
    p.dest_pid = IEEE802154_PANID;
    p.seq = seqno;
#if TSCH_PACKET_EACK_WITH_DEST_ADDR
    if(dest_addr != NULL) {
        p.fcf.dest_addr_mode = LINKADDR_SIZE > 2 ? FRAME802154_LONGADDRMODE : FRAME802154_SHORTADDRMODE;;
        linkaddr_copy((linkaddr_t *)&p.dest_addr, dest_addr);
    }
#endif
#if TSCH_PACKET_EACK_WITH_SRC_ADDR
    p.fcf.src_addr_mode = LINKADDR_SIZE > 2 ? FRAME802154_LONGADDRMODE : FRAME802154_SHORTADDRMODE;;
    p.src_pid = IEEE802154_PANID;
    linkaddr_copy((linkaddr_t *)&p.src_addr, &linkaddr_node_addr);
#endif
#if LLSEC802154_ENABLED
    if(tsch_is_pan_secured) {
        p.fcf.security_enabled = 1;
        p.aux_hdr.security_control.security_level = TSCH_SECURITY_KEY_SEC_LEVEL_ACK;
        p.aux_hdr.security_control.key_id_mode = FRAME802154_1_BYTE_KEY_ID_MODE;
        p.aux_hdr.security_control.frame_counter_suppression = 1;
        p.aux_hdr.security_control.frame_counter_size = 1;
        p.aux_hdr.key_index = TSCH_SECURITY_KEY_INDEX_ACK;
    }
#endif /* LLSEC802154_ENABLED */

    if((curr_len = frame802154_create(&p, buf)) == 0) {
        return 0;
    }

    /* Append IE timesync */
    memset(&ies, 0, sizeof(ies));
    ies.ie_time_correction = drift;
    ies.ie_is_nack = nack;

    if((ret = frame80215e_create_ie_header_ack_nack_time_correction(buf+curr_len, buf_size-curr_len, &ies)) == -1) {
        return -1;
    }
    curr_len += ret;

    return curr_len;
}
Beispiel #5
0
/*---------------------------------------------------------------------------*/
static void
rrep_packet_received(struct unicast_conn *uc, const linkaddr_t *from)
{
  struct rrep_hdr *msg = packetbuf_dataptr();
  struct route_entry *rt;
  linkaddr_t dest;
  struct route_discovery_conn *c = (struct route_discovery_conn *)
    ((char *)uc - offsetof(struct route_discovery_conn, rrepconn));

  PRINTF("%d.%d: rrep_packet_received from %d.%d towards %d.%d len %d\n",
	 linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
	 from->u8[0],from->u8[1],
	 msg->dest.u8[0],msg->dest.u8[1],
	 packetbuf_datalen());

  PRINTF("from %d.%d hops %d rssi %d lqi %d\n",
	 from->u8[0], from->u8[1],
	 msg->hops,
	 packetbuf_attr(PACKETBUF_ATTR_RSSI),
	 packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));

  insert_route(&msg->originator, from, msg->hops);

  if(linkaddr_cmp(&msg->dest, &linkaddr_node_addr)) {
    PRINTF("rrep for us!\n");
    rrep_pending = 0;
    ctimer_stop(&c->t);
    if(c->cb->new_route) {
      linkaddr_t originator;

      /* If the callback modifies the packet, the originator address
         will be lost. Therefore, we need to copy it into a local
         variable before calling the callback. */
      linkaddr_copy(&originator, &msg->originator);
      c->cb->new_route(c, &originator);
    }

  } else {
    linkaddr_copy(&dest, &msg->dest);

    rt = route_lookup(&msg->dest);
    if(rt != NULL) {
      PRINTF("forwarding to %d.%d\n", rt->nexthop.u8[0], rt->nexthop.u8[1]);
      msg->hops++;
      unicast_send(&c->rrepconn, &rt->nexthop);
    } else {
      PRINTF("%d.%d: no route to %d.%d\n", linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], msg->dest.u8[0], msg->dest.u8[1]);
    }
  }
}
Beispiel #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;
}
Beispiel #7
0
/*---------------------------------------------------------------------------*/
int
stunicast_send_stubborn(struct stunicast_conn *c, const linkaddr_t *receiver,
		  clock_time_t rxmittime)
{
  if(c->buf != NULL) {
    queuebuf_free(c->buf);
  }
  c->buf = queuebuf_new_from_packetbuf();
  if(c->buf == NULL) {
    return 0;
  }
  linkaddr_copy(&c->receiver, receiver);
  ctimer_set(&c->t, rxmittime, send, c);

  PRINTF("%d.%d: stunicast_send_stubborn to %d.%d\n",
	 linkaddr_node_addr.u8[0],linkaddr_node_addr.u8[1],
	 c->receiver.u8[0],c->receiver.u8[1]);
  unicast_send(&c->c, &c->receiver);
  /*  if(c->u->sent != NULL) {
    c->u->sent(c);
    }*/
  
  return 1;
  
}
/*---------------------------------------------------------------------------*/
static void
packet_input(void)
{
#if DISCOVERY_AWARE_RDC_SEND_802154_ACK
	int original_datalen;
	uint8_t *original_dataptr;

	original_datalen = packetbuf_datalen();
	original_dataptr = packetbuf_dataptr();
#endif

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

#if DISCOVERY_AWARE_RDC_802154_AUTOACK
	if(packetbuf_datalen() == ACK_LEN) {
		/* Ignore ack packets */
		PRINTF("RDC: ignored ack\n");
	} else
#endif /* DISCOVERY_AWARE_RDC_802154_AUTOACK */
		if(NETSTACK_FRAMER.parse() < 0) {
			PRINTF("RDC: failed to parse %u\n", packetbuf_datalen());
#if DISCOVERY_AWARE_RDC_ADDRESS_FILTER
		} else if(!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
				&linkaddr_node_addr) &&
				!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
						&linkaddr_null)) {
			PRINTF("RDC: not for us\n");
#endif /* DISCOVERY_AWARE_RDC_ADDRESS_FILTER */
		} else {
#if DISCOVERY_AWARE_RDC_802154_AUTOACK || DISCOVERY_AWARE_RDC_802154_AUTOACK_HW
			/* 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 &&
						linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
								&received_seqnos[i].sender)) {
					/* Drop the packet. */
					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);
			linkaddr_copy(&received_seqnos[0].sender,
					packetbuf_addr(PACKETBUF_ADDR_SENDER));
#endif /* DISCOVERY_AWARE_RDC_802154_AUTOACK */

			if (!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER), &linkaddr_null)) {
				to_modifier += 10;
				rec_flag = 1;
			}

			NETSTACK_MAC.input();
		}
}
Beispiel #9
0
/*---------------------------------------------------------------------------*/
static void
recv_runicast(struct runicast_conn *c, const linkaddr_t *from, uint8_t seqno)
{
  /* OPTIONAL: Sender history */
  struct history_entry *e = NULL;
  for(e = list_head(history_table); e != NULL; e = e->next) {
    if(linkaddr_cmp(&e->addr, from)) {
      break;
    }
  }
  if(e == NULL) {
    /* Create new history entry */
    e = memb_alloc(&history_mem);
    if(e == NULL) {
      e = list_chop(history_table); /* Remove oldest at full history */
    }
    linkaddr_copy(&e->addr, from);
    e->seq = seqno;
    list_push(history_table, e);
  } else {
    /* Detect duplicate callback */
    if(e->seq == seqno) {
      printf("runicast message received from %d.%d, seqno %d (DUPLICATE)\n",
	     from->u8[0], from->u8[1], seqno);
      return;
    }
    /* Update existing history entry */
    e->seq = seqno;
  }

  printf("runicast message received from %d.%d, seqno %d\n",
	 from->u8[0], from->u8[1], seqno);
}
Beispiel #10
0
/* Add a TSCH neighbor */
struct tsch_neighbor *
tsch_queue_add_nbr(const linkaddr_t *addr)
{
  struct tsch_neighbor *n = NULL;
  /* If we have an entry for this neighbor already, we simply update it */
  n = tsch_queue_get_nbr(addr);
  if(n == NULL) {
    if(tsch_get_lock()) {
      /* Allocate a neighbor */
      n = memb_alloc(&neighbor_memb);
      if(n != NULL) {
        /* Initialize neighbor entry */
        memset(n, 0, sizeof(struct tsch_neighbor));
        ringbufindex_init(&n->tx_ringbuf, TSCH_QUEUE_NUM_PER_NEIGHBOR);
        linkaddr_copy(&n->addr, addr);
        n->is_broadcast = linkaddr_cmp(addr, &tsch_eb_address)
          || linkaddr_cmp(addr, &tsch_broadcast_address);
        tsch_queue_backoff_reset(n);
        /* Add neighbor to the list */
        list_add(neighbor_list, n);
      }
      tsch_release_lock();
    }
  }
  return n;
}
Beispiel #11
0
/*---------------------------------------------------------------------------*/
int
packetbuf_set_addr(uint8_t type, const linkaddr_t *addr)
{
/*   packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].type = type; */
  linkaddr_copy(&packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr, addr);
  return 1;
}
Beispiel #12
0
/*---------------------------------------------------------------------------*/
static void
setup_sending(linkaddr_t *to, int num)
{
  is_sender = 1;
  left_to_send = num;
  linkaddr_copy(&receiver, to);
  clear_stats();
}
Beispiel #13
0
/*---------------------------------------------------------------------------*/
static void
handle_beacon_send_timer(struct net_buf *buf, void *p)
{
  struct net_buf *mbuf;
  frame802154_t params;
  uint8_t len;

  mbuf = l2_buf_get_reserve(0);
  if(!mbuf) {
    return;
  }

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

  /* use packetbuf for sending ?? */
  packetbuf_clear(mbuf);
  /* Build the FCF. */
  params.fcf.frame_type = FRAME802154_BEACONFRAME;

  /* Insert IEEE 802.15.4 (2006) version bits. */
  params.fcf.frame_version = FRAME802154_IEEE802154_2006;

  /* assume long for now */
  params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
  linkaddr_copy((linkaddr_t *)&params.src_addr, &linkaddr_node_addr);

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

  params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
  params.dest_addr[0] = 0xFF;
  params.dest_addr[1] = 0xFF;

  params.dest_pid = 0xffff;

  params.seq = framer_802154_next_seqno();

  /* Calculate beacon length and copy it to packetbuf */
  beacon_payload_len = handler_802154_calculate_beacon_payload_length(beacon_payload, BEACON_PAYLOAD_BUFFER_SIZE);
  packetbuf_copyfrom(mbuf, beacon_payload, beacon_payload_len);

  /* Set payload and payload length */
  params.payload = packetbuf_dataptr(mbuf);
  params.payload_len = packetbuf_datalen(mbuf);

  len = frame802154_hdrlen(&params);
  if(packetbuf_hdralloc(mbuf, len)) {
    frame802154_create(&params, packetbuf_hdrptr(mbuf), len);
    if(NETSTACK_RADIO.send(mbuf, packetbuf_hdrptr(mbuf),
                  packetbuf_totlen(mbuf)) != RADIO_TX_OK) {
      l2_buf_unref(mbuf);
      return;
    }

    HANDLER_802154_STAT(handler_802154_stats.beacons_sent++);
  }
}
Beispiel #14
0
/**
 * \brief Incoming notification, that service has finished processing bundle
 * \param bundlemem Pointer to the MMEM struct of the bundle
 */
void routing_chain_bundle_delivered_locally(struct mmem * bundlemem) {
	struct routing_list_entry_t * n = NULL;
	struct routing_entry_t * entry = NULL;
	struct bundle_t * bundle = (struct bundle_t *) MMEM_PTR(bundlemem);

	// Tell the agent to call us again to resubmit bundles
	routing_chain_schedule_resubmission();

	if( bundle == NULL ) {
		LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "flood_locally_delivered called with invalid pointer");
		return;
	}

	// Find the bundle in our internal storage
	for( n = (struct routing_list_entry_t *) list_head(routing_list);
		 n != NULL;
		 n = list_item_next(n) ) {

		entry = (struct routing_entry_t *) MMEM_PTR(&n->entry);

		if( entry->bundle_number == bundle->bundle_num ) {
			break;
		}
	}

	if( n == NULL ) {
		LOG(LOGD_DTN, LOG_ROUTE, LOGL_ERR, "Bundle not in storage yet");
		return;
	}

	// Unset the IN_DELIVERY flag
	entry->flags &= ~ROUTING_FLAG_IN_DELIVERY;

	// Unset the LOCAL flag
	entry->flags &= ~ROUTING_FLAG_LOCAL;

	// Unblock the receiving service
	delivery_unblock_service(bundlemem);

	// Free the bundle memory
	bundle_decrement(bundlemem);

	/* We count ourselves as node as well, so list us as receiver of a bundle copy */
	if (entry->send_to < ROUTING_NEI_MEM) {
		linkaddr_copy(&entry->neighbours[entry->send_to], &linkaddr_node_addr);
		entry->send_to++;
		LOG(LOGD_DTN, LOG_ROUTE, LOGL_DBG, "bundle %lu sent to %u nodes", entry->bundle_number, entry->send_to);
	} else if (entry->send_to >= ROUTING_NEI_MEM) {
		// Here we can delete the bundle from storage, because it will not be routed anyway
		LOG(LOGD_DTN, LOG_ROUTE, LOGL_DBG, "bundle %lu sent to max number of nodes, deleting", entry->bundle_number);

		/* Unsetting the forward flag will make routing_flooding_check_keep_bundle delete the bundle */
		entry->flags &= ~ROUTING_FLAG_FORWARD;
	}

	// Check remaining live of bundle
	routing_chain_check_keep_bundle(entry->bundle_number);
}
Beispiel #15
0
static uint8_t net_tcpip_output(struct net_buf *buf, const uip_lladdr_t *lladdr)
{
	if (!netdev.drv) {
		return 0;
	}

	if(lladdr == NULL) {
		linkaddr_copy(&buf->dest, &linkaddr_null);
	} else {
		linkaddr_copy(&buf->dest, (const linkaddr_t *)lladdr);
	}

	if (netdev.drv->send(buf) < 0) {
		return 0;
	}

	return 1;
}
Beispiel #16
0
void
slip_got_mac(const uint8_t * data)
{
    memcpy(uip_lladdr.addr, data, sizeof(uip_lladdr.addr));
    linkaddr_set_node_addr((linkaddr_t *) uip_lladdr.addr);
    linkaddr_copy((linkaddr_t *) & wsn_mac_addr, &linkaddr_node_addr);
    LOG6LBR_LLADDR(INFO, &uip_lladdr, "Got MAC: ");
    radio_mac_addr_ready = 1;
}
Beispiel #17
0
/*---------------------------------------------------------------------------*/
void
packetbuf_attr_clear(void)
{
  int i;
  memset(packetbuf_attrs, 0, sizeof(packetbuf_attrs));
  for(i = 0; i < PACKETBUF_NUM_ADDRS; ++i) {
    linkaddr_copy(&packetbuf_addrs[i].addr, &linkaddr_null);
  }
}
Beispiel #18
0
/*---------------------------------------------------------------------------*/
static int
rreq_packet_received(struct netflood_conn *nf, const linkaddr_t *from,
		     const linkaddr_t *originator, uint8_t seqno, uint8_t hops)
{
  struct route_msg *msg = packetbuf_dataptr();
  struct route_discovery_conn *c = (struct route_discovery_conn *)
    ((char *)nf - offsetof(struct route_discovery_conn, rreqconn));

  PRINTF("%d.%d: rreq_packet_received from %d.%d hops %d rreq_id %d last %d.%d/%d\n",
	 linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
	 from->u8[0], from->u8[1],
	 hops, msg->rreq_id,
     c->last_rreq_originator.u8[0],
     c->last_rreq_originator.u8[1],
	 c->last_rreq_id);

  if(!(linkaddr_cmp(&c->last_rreq_originator, originator) &&
       c->last_rreq_id == msg->rreq_id)) {

    PRINTF("%d.%d: rreq_packet_received: request for %d.%d originator %d.%d / %d\n",
	   linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
	   msg->dest.u8[0], msg->dest.u8[1],
	   originator->u8[0], originator->u8[1],
	   msg->rreq_id);

    linkaddr_copy(&c->last_rreq_originator, originator);
    c->last_rreq_id = msg->rreq_id;

    if(linkaddr_cmp(&msg->dest, &linkaddr_node_addr)) {
      PRINTF("%d.%d: route_packet_received: route request for our address\n",
	     linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
      PRINTF("from %d.%d hops %d rssi %d lqi %d\n",
	     from->u8[0], from->u8[1],
	     hops,
	     packetbuf_attr(PACKETBUF_ATTR_RSSI),
	     packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));

      insert_route(originator, from, hops);
      
      /* Send route reply back to source. */
      send_rrep(c, originator);
      return 0; /* Don't continue to flood the rreq packet. */
    } else {
      /*      PRINTF("route request for %d\n", msg->dest_id);*/
      PRINTF("from %d.%d hops %d rssi %d lqi %d\n",
	     from->u8[0], from->u8[1],
	     hops,
	     packetbuf_attr(PACKETBUF_ATTR_RSSI),
	     packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));
      insert_route(originator, from, hops);
    }
    
    return 1;
  }
  return 0; /* Don't forward packet. */
}
/* Adds a link to a slotframe, return a pointer to it (NULL if failure) */
struct tsch_link *
tsch_schedule_add_link(struct tsch_slotframe *slotframe,
                       uint8_t link_options, enum link_type link_type, const linkaddr_t *address,
                       uint16_t timeslot, uint16_t channel_offset)
{
  struct tsch_link *l = NULL;
  if(slotframe != NULL) {
    /* We currently support only one link per timeslot in a given slotframe. */
    /* Start with removing the link currently installed at this timeslot (needed
     * to keep neighbor state in sync with link options etc.) */
    tsch_schedule_remove_link_by_timeslot(slotframe, timeslot);
    if(!tsch_get_lock()) {
      PRINTF("TSCH-schedule:! add_link memb_alloc couldn't take lock\n");
    } else {
      l = memb_alloc(&link_memb);
      if(l == NULL) {
        PRINTF("TSCH-schedule:! add_link memb_alloc failed\n");
      } else {
        static int current_link_handle = 0;
        struct tsch_neighbor *n;
        /* Add the link to the slotframe */
        list_add(slotframe->links_list, l);
        /* Initialize link */
        l->handle = current_link_handle++;
        l->link_options = link_options;
        l->link_type = link_type;
        l->slotframe_handle = slotframe->handle;
        l->timeslot = timeslot;
        l->channel_offset = channel_offset;
        l->data = NULL;
        if(address == NULL) {
          address = &linkaddr_null;
        }
        linkaddr_copy(&l->addr, address);

        PRINTF("TSCH-schedule: add_link %u %u %u %u %u %u\n",
               slotframe->handle, link_options, link_type, timeslot, channel_offset, TSCH_LOG_ID_FROM_LINKADDR(address));

        /* Release the lock before we update the neighbor (will take the lock) */
        tsch_release_lock();

        if(l->link_options & LINK_OPTION_TX) {
          n = tsch_queue_add_nbr(&l->addr);
          /* We have a tx link to this neighbor, update counters */
          if(n != NULL) {
            n->tx_links_count++;
            if(!(l->link_options & LINK_OPTION_SHARED)) {
              n->dedicated_tx_links_count++;
            }
          }
        }
      }
    }
  }
  return l;
}
Beispiel #20
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(example_collect_process, ev, data)
{
  static struct etimer periodic;
  static struct etimer et;
  
  PROCESS_BEGIN();

  collect_open(&tc, 130, COLLECT_ROUTER, &callbacks);

  if(linkaddr_node_addr.u8[0] == 1 &&
     linkaddr_node_addr.u8[1] == 0) {
	printf("I am sink\n");
	collect_set_sink(&tc, 1);
  }

  /* Allow some time for the network to settle. */
  etimer_set(&et, 120 * CLOCK_SECOND);
  PROCESS_WAIT_UNTIL(etimer_expired(&et));

  while(1) {

    /* Send a packet every 30 seconds. */
    if(etimer_expired(&periodic)) {
      etimer_set(&periodic, CLOCK_SECOND * 30);
      etimer_set(&et, random_rand() % (CLOCK_SECOND * 30));
    }

    PROCESS_WAIT_EVENT();


    if(etimer_expired(&et)) {
      static linkaddr_t oldparent;
      const linkaddr_t *parent;

      printf("Sending\n");
      packetbuf_clear();
      packetbuf_set_datalen(sprintf(packetbuf_dataptr(),
				  "%s", "Hello") + 1);
      collect_send(&tc, 15);

      parent = collect_parent(&tc);
      if(!linkaddr_cmp(parent, &oldparent)) {
        if(!linkaddr_cmp(&oldparent, &linkaddr_null)) {
          printf("#L %d 0\n", oldparent.u8[0]);
        }
        if(!linkaddr_cmp(parent, &linkaddr_null)) {
          printf("#L %d 1\n", parent->u8[0]);
        }
        linkaddr_copy(&oldparent, parent);
      }
    }

  }

  PROCESS_END();
}
/*---------------------------------------------------------------------------*/
static char
cpowercycle(void *ptr)
{
  if(is_streaming) {
    if(!RTIMER_CLOCK_LT(RTIMER_NOW(), stream_until)) {
      is_streaming = 0;
      linkaddr_copy(&is_streaming_to, &linkaddr_null);
      linkaddr_copy(&is_streaming_to_too, &linkaddr_null);
    }
  }

  PT_BEGIN(&pt);

  while(1) {
    /* Only wait for some cycles to pass for someone to start sending */
    if(someone_is_sending > 0) {
      someone_is_sending--;
    }

    /* If there were a strobe in the air, turn radio on */
    powercycle_turn_radio_on();
    CSCHEDULE_POWERCYCLE(DEFAULT_ON_TIME);
    PT_YIELD(&pt);

    if(cxmac_config.off_time > 0) {
      powercycle_turn_radio_off();
      if(waiting_for_packet != 0) {
	waiting_for_packet++;
	if(waiting_for_packet > 2) {
	  /* We should not be awake for more than two consecutive
	     power cycles without having heard a packet, so we turn off
	     the radio. */
	  waiting_for_packet = 0;
	  powercycle_turn_radio_off();
	}
      }
      CSCHEDULE_POWERCYCLE(DEFAULT_OFF_TIME);
      PT_YIELD(&pt);
    }
  }

  PT_END(&pt);
}
Beispiel #22
0
static void
handle_summary(struct deluge_msg_summary *msg, const linkaddr_t *sender)
{
  int highest_available, i;
  clock_time_t oldest_request, oldest_data, now;
  struct deluge_page *page;

  highest_available = highest_available_page(&current_object);

  if(msg->version != current_object.version ||
      msg->highest_available != highest_available) {
    neighbor_inconsistency = 1;
  } else {
    recv_adv++;
  }

  if(msg->version < current_object.version) {
    old_summary = 1;
    broadcast_profile = 1;
  }

  /* Deluge M.5 */
  if(msg->version == current_object.update_version &&
     msg->highest_available > highest_available) {
    if(msg->highest_available > OBJECT_PAGE_COUNT(current_object)) {
      PRINTF("Error: highest available is above object page count!\n");
      return;
    }

    oldest_request = oldest_data = now = clock_time();
    for(i = 0; i < msg->highest_available; i++) {
      page = &current_object.pages[i];
      if(page->last_request < oldest_request) {
	oldest_request = page->last_request;
      }
      if(page->last_request < oldest_data) {
	oldest_data = page->last_data;
      }
    }

    if(((now - oldest_request) / CLOCK_SECOND) <= 2 * r_interval ||
	((now - oldest_data) / CLOCK_SECOND) <= r_interval) {
      return;
    }

    linkaddr_copy(&current_object.summary_from, sender);
    transition(DELUGE_STATE_RX);

    if(ctimer_expired(&rx_timer)) {
      ctimer_set(&rx_timer,
	CONST_OMEGA * ESTIMATED_TX_TIME + ((unsigned)random_rand() % T_R),
	send_request, &current_object);
    }
  }
}
Beispiel #23
0
/*---------------------------------------------------------------------------*/
void
packetbuf_attr_clear(void)
{
  int i;
  for(i = 0; i < PACKETBUF_NUM_ATTRS; ++i) {
    packetbuf_attrs[i].val = 0;
  }
  for(i = 0; i < PACKETBUF_NUM_ADDRS; ++i) {
    linkaddr_copy(&packetbuf_addrs[i].addr, &linkaddr_null);
  }
}
Beispiel #24
0
/*---------------------------------------------------------------------------*/
static void
send_rreq(struct route_discovery_conn *c, const linkaddr_t *dest)
{
  linkaddr_t dest_copy;
  struct route_msg *msg;

  linkaddr_copy(&dest_copy, dest);
  dest = &dest_copy;

  packetbuf_clear();
  msg = packetbuf_dataptr();
  packetbuf_set_datalen(sizeof(struct route_msg));

  msg->pad = 0;
  msg->rreq_id = c->rreq_id;
  linkaddr_copy(&msg->dest, dest);

  netflood_send(&c->rreqconn, c->rreq_id);
  c->rreq_id++;
}
Beispiel #25
0
/*---------------------------------------------------------------------------*/
int
route_add(const linkaddr_t *dest, const linkaddr_t *nexthop,
	  uint8_t cost, uint8_t seqno)
{
  struct route_entry *e;

  /* Avoid inserting duplicate entries. */
  e = route_lookup(dest);
  if(e != NULL && linkaddr_cmp(&e->nexthop, nexthop)) {
    list_remove(route_table, e);
  } else {
    /* Allocate a new entry or reuse the oldest entry with highest cost. */
    e = memb_alloc(&route_mem);
    if(e == NULL) {
      /* Remove oldest entry.  XXX */
      e = list_chop(route_table);
      PRINTF("route_add: removing entry to %d.%d with nexthop %d.%d and cost %d\n",
	     e->dest.u8[0], e->dest.u8[1],
	     e->nexthop.u8[0], e->nexthop.u8[1],
	     e->cost);
    }
  }

  linkaddr_copy(&e->dest, dest);
  linkaddr_copy(&e->nexthop, nexthop);
  e->cost = cost;
  e->seqno = seqno;
  e->time = 0;
  e->decay = 0;

  /* New entry goes first. */
  list_push(route_table, e);

  PRINTF("route_add: new entry to %d.%d with nexthop %d.%d and cost %d\n",
	 e->dest.u8[0], e->dest.u8[1],
	 e->nexthop.u8[0], e->nexthop.u8[1],
	 e->cost);
  
  return 0;
}
Beispiel #26
0
/*---------------------------------------------------------------------------*/
void
eth_drv_init()
{
  LOG6LBR_INFO("ENC28J60 init\n");

  linkaddr_copy((linkaddr_t *) & wsn_mac_addr, &linkaddr_node_addr);
  mac_createEthernetAddr((uint8_t *) eth_mac_addr, &wsn_mac_addr);
  LOG6LBR_ETHADDR(INFO, &eth_mac_addr, "Eth MAC address : ");
  eth_mac_addr_ready = 1;

  enc28j60_init(eth_mac_addr);
  process_start(&eth_drv_process, NULL);
  ethernet_ready = 1;
}
Beispiel #27
0
static void
recv_runicast(struct runicast_conn *c, const linkaddr_t *from, uint8_t seqno)
{
	struct history_entry *e = NULL;
	int16_t data, id;

	for(e = list_head(history_table); e != NULL; e = e->next)
	{
		if(linkaddr_cmp(&e->addr, from))
		{
			break;
		}
	}

	if(e == NULL)
	{
		/* Create new history entry */
		e = memb_alloc(&history_mem);
		if(e == NULL)
		{
			e = list_chop(history_table); /* Remove oldest at full history */
		}
		linkaddr_copy(&e->addr, from);
		e->seq = seqno;
		list_push(history_table, e);
	}
	else
	{
		/* Detect duplicate callback */
		if(e->seq == seqno)
		{
			printf("runicast message received from %d.%d, seqno %d (DUPLICATE)\n",
					from->u8[0], from->u8[1], seqno);
		}
		/* Update existing history entry */
		e->seq = seqno;
	}

	printf("Basestation: runicast message received from %d.%d, seqno %d\n",
			from->u8[0], from->u8[1], seqno);

	struct runicast_message *received_msg = packetbuf_dataptr();

	if (received_msg->type == RUNICAST_TYPE_TEMP)
	{
		time_delay = received_msg->data;

		printf("Temperature from actuator %d has value %d",id,data)
	}
Beispiel #28
0
/*---------------------------------------------------------------------------*/
void fast_c_init(void)
{
	int i;

	rime_sniffer_add(&fast_c_sniffer);
	linkaddr_copy(&fast_c_parent_linkaddr, &linkaddr_null);

	for(i = 0; i < NUM_RULES; i++) {
		if(init_rules[i]->init != NULL) {
			PRINTF("FAST-C: initializing rule %u\n", i);
			init_rules[i]->init(i);
		}
	}
	PRINTF("FAST-C: initialization done\n");
}
Beispiel #29
0
/*---------------------------------------------------------------------------*/
void
uip_over_mesh_make_announced_gateway(void)
{
  struct gateway_msg msg;
  /* Make this node the gateway node, unless it already is the
     gateway. */
  if(!is_gateway) {
    PRINTF("%d.%d: making myself the gateway\n",
	   linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
    uip_over_mesh_set_gateway(&linkaddr_node_addr);
    linkaddr_copy(&(msg.gateway), &linkaddr_node_addr);
    packetbuf_copyfrom(&msg, sizeof(struct gateway_msg));
    trickle_send(&gateway_announce_conn);
    is_gateway = 1;
  }
}
Beispiel #30
0
/*---------------------------------------------------------------------------*/
static void
packet_input(void)
{
  int frame_parsed = 1;

  frame_parsed = NETSTACK_FRAMER.parse();

  if(frame_parsed < 0) {
    PRINTF("TSCH:! failed to parse %u\n", packetbuf_datalen());
  } else {
    int duplicate = 0;

    /* Seqno of 0xffff means no seqno */
    if(packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO) != 0xffff) {
      /* 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_MAC_SEQNO) == received_seqnos[i].seqno &&
           linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER),
                        &received_seqnos[i].sender)) {
          /* Drop the packet. */
          PRINTF("TSCH:! drop dup ll from %u seqno %u\n",
                 TSCH_LOG_ID_FROM_LINKADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)),
                 packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
          duplicate = 1;
        }
      }
      if(!duplicate) {
        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_MAC_SEQNO);
        linkaddr_copy(&received_seqnos[0].sender,
                      packetbuf_addr(PACKETBUF_ADDR_SENDER));
      }
    }

    if(!duplicate) {
      PRINTF("TSCH: received from %u with seqno %u\n",
             TSCH_LOG_ID_FROM_LINKADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER)),
             packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
      NETSTACK_LLSEC.input();
    }
  }
}