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; }
/*---------------------------------------------------------------------------*/ 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; }
/* 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; }
/*---------------------------------------------------------------------------*/ 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]); } } }
/*---------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------*/ 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(); } }
/*---------------------------------------------------------------------------*/ 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); }
/* 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; }
/*---------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------*/ static void setup_sending(linkaddr_t *to, int num) { is_sender = 1; left_to_send = num; linkaddr_copy(&receiver, to); clear_stats(); }
/*---------------------------------------------------------------------------*/ 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(¶ms, 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 *)¶ms.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(¶ms); if(packetbuf_hdralloc(mbuf, len)) { frame802154_create(¶ms, 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++); } }
/** * \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); }
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; }
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; }
/*---------------------------------------------------------------------------*/ 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); } }
/*---------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------*/ 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); }
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(¤t_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 = ¤t_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(¤t_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, ¤t_object); } } }
/*---------------------------------------------------------------------------*/ 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); } }
/*---------------------------------------------------------------------------*/ 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++; }
/*---------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------*/ 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, ð_mac_addr, "Eth MAC address : "); eth_mac_addr_ready = 1; enc28j60_init(eth_mac_addr); process_start(ð_drv_process, NULL); ethernet_ready = 1; }
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) }
/*---------------------------------------------------------------------------*/ 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"); }
/*---------------------------------------------------------------------------*/ 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; } }
/*---------------------------------------------------------------------------*/ 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(); } } }