47 #include "net/rpl/rpl-conf.h"
49 #if ORCHESTRA_UNICAST_SENDER_BASED && ORCHESTRA_COLLISION_FREE_HASH
50 #define UNICAST_SLOT_SHARED_FLAG ((ORCHESTRA_UNICAST_PERIOD < (ORCHESTRA_MAX_HASH + 1)) ? LINK_OPTION_SHARED : 0)
52 #define UNICAST_SLOT_SHARED_FLAG LINK_OPTION_SHARED
55 static uint16_t slotframe_handle = 0;
56 static uint16_t channel_offset = 0;
57 static struct tsch_slotframe *sf_unicast;
61 get_node_timeslot(
const linkaddr_t *
addr)
63 if(addr !=
NULL && ORCHESTRA_UNICAST_PERIOD > 0) {
64 return ORCHESTRA_LINKADDR_HASH(addr) % ORCHESTRA_UNICAST_PERIOD;
71 neighbor_has_uc_link(
const linkaddr_t *linkaddr)
74 if((orchestra_parent_knows_us || !ORCHESTRA_UNICAST_SENDER_BASED)
78 if(nbr_table_get_from_lladdr(nbr_routes, (linkaddr_t *)linkaddr) !=
NULL) {
86 add_uc_link(
const linkaddr_t *linkaddr)
88 if(linkaddr !=
NULL) {
89 uint16_t timeslot = get_node_timeslot(linkaddr);
90 uint8_t link_options = ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_RX : LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG;
94 link_options |= ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG: LINK_OPTION_RX;
98 tsch_schedule_add_link(sf_unicast, link_options, LINK_TYPE_NORMAL, &tsch_broadcast_address,
99 timeslot, channel_offset);
104 remove_uc_link(
const linkaddr_t *linkaddr)
109 if(linkaddr ==
NULL) {
113 timeslot = get_node_timeslot(linkaddr);
114 l = tsch_schedule_get_link_by_timeslot(sf_unicast, timeslot);
119 if(timeslot == get_node_timeslot(&orchestra_parent_linkaddr)) {
125 nbr_table_item_t *item = nbr_table_head(nbr_routes);
126 while(item !=
NULL) {
127 linkaddr_t *addr = nbr_table_get_lladdr(nbr_routes, item);
128 if(timeslot == get_node_timeslot(addr)) {
132 item = nbr_table_next(nbr_routes, item);
138 uint8_t link_options = ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG: LINK_OPTION_RX;
139 tsch_schedule_add_link(sf_unicast, link_options, LINK_TYPE_NORMAL, &tsch_broadcast_address,
140 timeslot, channel_offset);
143 tsch_schedule_remove_link(sf_unicast, l);
148 child_added(
const linkaddr_t *linkaddr)
150 add_uc_link(linkaddr);
154 child_removed(
const linkaddr_t *linkaddr)
156 remove_uc_link(linkaddr);
160 select_packet(uint16_t *slotframe, uint16_t *timeslot)
163 const linkaddr_t *dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
164 if(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE) == FRAME802154_DATAFRAME
165 && neighbor_has_uc_link(dest)) {
166 if(slotframe !=
NULL) {
167 *slotframe = slotframe_handle;
169 if(timeslot !=
NULL) {
170 *timeslot = ORCHESTRA_UNICAST_SENDER_BASED ? get_node_timeslot(&
linkaddr_node_addr) : get_node_timeslot(dest);
178 new_time_source(
const struct tsch_neighbor *old,
const struct tsch_neighbor *
new)
181 const linkaddr_t *old_addr = old !=
NULL ? &old->addr :
NULL;
182 const linkaddr_t *new_addr =
new !=
NULL ? &
new->addr :
NULL;
183 if(new_addr !=
NULL) {
188 remove_uc_link(old_addr);
189 add_uc_link(new_addr);
194 init(uint16_t sf_handle)
196 slotframe_handle = sf_handle;
197 channel_offset = sf_handle;
199 sf_unicast = tsch_schedule_add_slotframe(slotframe_handle, ORCHESTRA_UNICAST_PERIOD);
201 tsch_schedule_add_link(sf_unicast,
202 ORCHESTRA_UNICAST_SENDER_BASED ? LINK_OPTION_TX | UNICAST_SLOT_SHARED_FLAG: LINK_OPTION_RX,
203 LINK_TYPE_NORMAL, &tsch_broadcast_address,
204 timeslot, channel_offset);
207 struct orchestra_rule unicast_per_neighbor_rpl_storing = {
static uip_ds6_addr_t * addr
Pointer to a router list entry.
Header file for routing table manipulation.
const linkaddr_t linkaddr_null
The null Rime address.
Header file for the Rime buffer (packetbuf) management
#define NULL
The null pointer.
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two Rime addresses.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a Rime address.
linkaddr_t linkaddr_node_addr
The Rime address of the node.