Contiki-NG
Loading...
Searching...
No Matches
orchestra-rule-eb-per-time-source.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015, Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30/**
31 * \file
32 * Orchestra: a slotframe dedicated to transmission of EBs.
33 * Nodes transmit at a timeslot defined as hash(MAC) % ORCHESTRA_EBSF_PERIOD
34 * Nodes listen at a timeslot defined as hash(time_source.MAC) % ORCHESTRA_EBSF_PERIOD
35 * \author Simon Duquennoy <simonduq@sics.se>
36 * Atis Elsts <atis.elsts@edi.lv>
37 */
38
39#include "contiki.h"
40#include "orchestra.h"
41#include "net/packetbuf.h"
42
43static uint16_t slotframe_handle = 0;
44static uint16_t channel_offset = 0;
45static struct tsch_slotframe *sf_eb;
46static struct tsch_link *timesource_link;
47
48/*---------------------------------------------------------------------------*/
49static uint16_t
50get_node_timeslot(const linkaddr_t *addr)
51{
52#if ORCHESTRA_EBSF_PERIOD > 0
53 return ORCHESTRA_LINKADDR_HASH(addr) % ORCHESTRA_EBSF_PERIOD;
54#else
55 return 0xffff;
56#endif
57}
58/*---------------------------------------------------------------------------*/
59static uint16_t
60get_node_channel_offset(const linkaddr_t *addr)
61{
62#if ORCHESTRA_EBSF_PERIOD > 0
63 if(ORCHESTRA_EB_MAX_CHANNEL_OFFSET >= ORCHESTRA_EB_MIN_CHANNEL_OFFSET) {
64 return ORCHESTRA_LINKADDR_HASH(addr) %
65 (ORCHESTRA_EB_MAX_CHANNEL_OFFSET - ORCHESTRA_EB_MIN_CHANNEL_OFFSET + 1)
66 + ORCHESTRA_EB_MIN_CHANNEL_OFFSET;
67 } else {
68 /* ORCHESTRA_EB_MIN_CHANNEL_OFFSET configure larger than max offset, this is an error */
69 return 0xffff;
70 }
71#else
72 return 0xffff;
73#endif
74}
75/*---------------------------------------------------------------------------*/
76static int
77select_packet(uint16_t *slotframe, uint16_t *timeslot, uint16_t *channel_offset)
78{
79 /* Select EBs only */
80 if(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE) == FRAME802154_BEACONFRAME) {
81 if(slotframe != NULL) {
82 *slotframe = slotframe_handle;
83 }
84 if(timeslot != NULL) {
85 *timeslot = get_node_timeslot(&linkaddr_node_addr);
86 }
87 /* no need to set the channel offset: it's taken automatically from the link */
88 return 1;
89 }
90 return 0;
91}
92/*---------------------------------------------------------------------------*/
93static void
94new_time_source(const struct tsch_neighbor *old, const struct tsch_neighbor *new)
95{
96 uint16_t old_ts = 0xffff;
97 uint16_t new_ts = 0xffff;
98 uint16_t old_channel_offset = 0xffff;
99 uint16_t new_channel_offset = 0xffff;
100
101 if(old != NULL) {
102 const linkaddr_t *addr = tsch_queue_get_nbr_address(old);
103 old_ts = get_node_timeslot(addr);
104 old_channel_offset = get_node_channel_offset(addr);
105 }
106
107 if(new != NULL) {
108 const linkaddr_t *addr = tsch_queue_get_nbr_address(new);
109 new_ts = get_node_timeslot(addr);
110 new_channel_offset = get_node_channel_offset(addr);
111 }
112
113 if(new_ts == old_ts && old_channel_offset == new_channel_offset) {
114 return;
115 }
116
117 if(timesource_link != NULL) {
118 /* Stop listening to the old time source's EBs */
119 tsch_schedule_remove_link(sf_eb, timesource_link);
120 timesource_link = NULL;
121 }
122 if(new_ts != 0xffff) {
123 /* Listen to the time source's EBs */
124 timesource_link = tsch_schedule_add_link(sf_eb, LINK_OPTION_RX, LINK_TYPE_ADVERTISING_ONLY,
125 &tsch_broadcast_address, new_ts, new_channel_offset, 0);
126 }
127}
128/*---------------------------------------------------------------------------*/
129static void
130init(uint16_t sf_handle)
131{
132 const uint16_t local_ts = get_node_timeslot(&linkaddr_node_addr);
133 const uint16_t local_channel_offset = get_node_channel_offset(&linkaddr_node_addr);
134 slotframe_handle = sf_handle;
135 channel_offset = sf_handle;
136 sf_eb = tsch_schedule_add_slotframe(slotframe_handle, ORCHESTRA_EBSF_PERIOD);
137 /* EB link: every neighbor uses its own to avoid contention */
139 LINK_OPTION_TX,
140 LINK_TYPE_ADVERTISING_ONLY, &tsch_broadcast_address,
141 local_ts, local_channel_offset, 0);
142}
143/*---------------------------------------------------------------------------*/
144struct orchestra_rule eb_per_time_source = {
145 init,
146 new_time_source,
147 select_packet,
148 NULL,
149 NULL,
150 NULL,
151 NULL,
152 "EB per time source",
153 ORCHESTRA_EBSF_PERIOD,
154};
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition linkaddr.c:48
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, uint8_t do_remove)
Adds a link to a slotframe.
struct tsch_slotframe * tsch_schedule_add_slotframe(uint16_t handle, uint16_t size)
Creates and adds a new slotframe.
linkaddr_t * tsch_queue_get_nbr_address(const struct tsch_neighbor *n)
Get the address of a neighbor.
Definition tsch-queue.c:135
int tsch_schedule_remove_link(struct tsch_slotframe *slotframe, struct tsch_link *l)
Removes a link.
Orchestra header file.
Header file for the Packet buffer (packetbuf) management.
TSCH neighbor information.
Definition tsch-types.h:109
802.15.4e slotframe (contains links)
Definition tsch-types.h:84
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition uip-nd6.c:107