Contiki-NG
Loading...
Searching...
No Matches
sixtop.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2016, Yasuyuki Tanaka
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 copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30/**
31 * \addtogroup sixtop
32 * @{
33 */
34/**
35 * \file
36 * 6TiSCH Operation Sublayer (6top)
37 *
38 * \author
39 * Yasuyuki Tanaka <yasuyuki.tanaka@inf.ethz.ch>
40 */
41
42#include "lib/assert.h"
43
44#include "net/netstack.h"
45#include "net/packetbuf.h"
48
49#include "sixtop.h"
50#include "sixtop-conf.h"
51#include "sixp.h"
52
53/* Log configuration */
54#include "sys/log.h"
55#define LOG_MODULE "6top"
56#define LOG_LEVEL LOG_LEVEL_6TOP
57
58const sixtop_sf_t *scheduling_functions[SIXTOP_MAX_SCHEDULING_FUNCTIONS];
59
60const sixtop_sf_t *sixtop_find_sf(uint8_t sfid);
61
62/*---------------------------------------------------------------------------*/
63void
64strip_payload_termination_ie(void)
65{
66 uint8_t *ptr = packetbuf_dataptr();
67 if(ptr[0] == 0x00 && ptr[1] == 0xf8) {
68 /* Payload Termination IE is 2 octets long */
70 }
71}
72/*---------------------------------------------------------------------------*/
73int
75{
76 int i;
77
78 assert(sf != NULL);
79
80 LOG_INFO("6top: sixtop_add_sf() is adding a SF [SFID:%u]\n", sf->sfid);
81
82 if(sixtop_find_sf(sf->sfid) != NULL) {
83 LOG_ERR("6top: sixtop_add_sf() fails because of duplicate SF\n");
84 return -1;
85 }
86
87 for(i = 0; i < SIXTOP_MAX_SCHEDULING_FUNCTIONS; i++) {
88 if(scheduling_functions[i] == NULL) {
89 scheduling_functions[i] = sf;
90 if(sf->init != NULL) {
91 sf->init();
92 }
93 break;
94 }
95 }
96
98 LOG_ERR("6top: sixtop_add_sf() fails because of no memory\n");
99 return -1;
100 }
101
102 if(sf->init != NULL) {
103 sf->init();
104 }
105 LOG_INFO("6top: SF [SFID:%u] has been added and initialized\n", sf->sfid);
106 return 0;
107}
108/*---------------------------------------------------------------------------*/
109const sixtop_sf_t *
110sixtop_find_sf(uint8_t sfid)
111{
112 int i;
113
114 for(i = 0; i < SIXTOP_MAX_SCHEDULING_FUNCTIONS; i++) {
115 if(scheduling_functions[i] != NULL &&
116 scheduling_functions[i]->sfid == sfid) {
117 return (const sixtop_sf_t *)scheduling_functions[i];
118 }
119 }
120
121 return NULL;
122}
123/*---------------------------------------------------------------------------*/
124int
125sixtop_output(const linkaddr_t *dest_addr, mac_callback_t callback, void *arg)
126{
127 uint8_t *p;
128 struct ieee802154_ies ies;
129 int len;
130
131 assert(dest_addr != NULL);
132 if(dest_addr == NULL) {
133 LOG_ERR("6top: sixtop_output() fails because dest_addr is NULL\n");
134 if(callback != NULL) {
135 callback(arg, MAC_TX_ERR_FATAL, 0);
136 }
137 return -1;
138 }
139
140 /* prepend 6top Sub-IE ID */
141 if(packetbuf_hdralloc(1) != 1) {
142 LOG_ERR("6top: sixtop_output() fails because of no room for Sub-IE ID\n");
143 return -1;
144 }
145 p = packetbuf_hdrptr();
146 p[0] = SIXTOP_SUBIE_ID;
147
148 /*
149 * prepend Payload IE header; 2 octets
150 * only sixtop_ie_content_len matters in frame80215e_create_ie_ietf().
151 */
152 memset(&ies, 0, sizeof(ies));
153 ies.sixtop_ie_content_len = packetbuf_totlen();
154 if(packetbuf_hdralloc(2) != 1 ||
155 (len = frame80215e_create_ie_ietf(packetbuf_hdrptr(),
156 2,
157 &ies)) < 0) {
158 LOG_ERR("6top: sixtop_output() fails because of Payload IE Header\n");
159 if(callback != NULL) {
160 callback(arg, MAC_TX_ERR_FATAL, 0);
161 }
162 return -1;
163 }
164
165#if SIXP_WITH_PAYLOAD_TERMINATION_IE
166 /* append Payload Termination IE to the data field; 2 octets */
167 memset(&ies, 0, sizeof(ies));
168 if((len = frame80215e_create_ie_payload_list_termination(
169 (uint8_t *)packetbuf_dataptr() + packetbuf_datalen(),
171 &ies)) < 0) {
172 LOG_ERR("6top: sixtop_output() fails because of Payload Termination IE\n");
173 callback(arg, MAC_TX_ERR_FATAL, 0);
174 return -1;
175 }
177#endif /* SIXP_WITH_PAYLOAD_TERMINATION_IE */
178
179 /* prepend Termination 1 IE to the header field; 2 octets */
180 memset(&ies, 0, sizeof(ies));
181 if(packetbuf_hdralloc(2) &&
182 frame80215e_create_ie_header_list_termination_1(packetbuf_hdrptr(),
183 2,
184 &ies) < 0) {
185 LOG_ERR("6top: sixtop_output() fails because of Header Termination 1 IE\n");
186 callback(arg, MAC_TX_ERR_FATAL, 0);
187 return -1;
188 }
189
190 /* specify with PACKETBUF_ATTR_METADATA that packetbuf has IEs */
191 packetbuf_set_attr(PACKETBUF_ATTR_MAC_METADATA, 1);
192
193 /* 6P packet is data frame */
194 packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
195
196 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, dest_addr);
197 packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);
198
199 NETSTACK_MAC.send(callback, arg);
200 return 0;
201}
202/*---------------------------------------------------------------------------*/
203void
205{
206 uint8_t *hdr_ptr, *payload_ptr;
207 uint16_t hdr_len, payload_len;
208
209 frame802154_t frame;
210 struct ieee802154_ies ies;
211 linkaddr_t src_addr;
212
213 /*
214 * A received *DATA* frame is supposed to be stored in packetbuf by
215 * framer_802154.parse(). packetbuf_dataptr() points at the starting address
216 * of the IE field or Frame Payload field if it's available. FCS should not be
217 * in packetbuf, which is expected to be stripped at a radio.
218 */
219
220 payload_ptr = packetbuf_dataptr();
221 payload_len = packetbuf_datalen();
222 hdr_len = packetbuf_hdrlen();
223 hdr_ptr = payload_ptr - hdr_len;
224
225 memcpy(&src_addr, packetbuf_addr(PACKETBUF_ADDR_SENDER), sizeof(src_addr));
226
227 if(frame802154_parse(hdr_ptr, hdr_len, &frame) == 0) {
228 /* parse error; should not occur, anyway */
229 LOG_ERR("6top: frame802154_parse error\n");
230 return;
231 }
232
233 /*
234 * We don't need to check the frame version nor frame type. The frame version
235 * is turned out to be 0b10 automatically if the frame has a IE list. The
236 * frame type is supposed to be DATA as mentioned above.
237 */
238 assert(frame.fcf.frame_version == FRAME802154_IEEE802154_2015);
239 assert(frame.fcf.frame_type == FRAME802154_DATAFRAME);
240 memset(&ies, 0, sizeof(ies));
241 if(frame.fcf.ie_list_present &&
242 frame802154e_parse_information_elements(payload_ptr,
243 payload_len, &ies) >= 0 &&
244 ies.sixtop_ie_content_ptr != NULL &&
245 ies.sixtop_ie_content_len > 0) {
246
247 sixp_input(ies.sixtop_ie_content_ptr, ies.sixtop_ie_content_len,
248 &src_addr);
249
250 /*
251 * move payloadbuf_dataptr() to the beginning of the next layer for further
252 * processing
253 */
254 packetbuf_hdrreduce(ies.sixtop_ie_content_ptr - payload_ptr +
255 ies.sixtop_ie_content_len);
256 strip_payload_termination_ie();
257 }
258}
259/*---------------------------------------------------------------------------*/
260void
262{
263 int i;
264
265 sixp_init();
266
267 for(i = 0; i < SIXTOP_MAX_SCHEDULING_FUNCTIONS; i++) {
268 scheduling_functions[i] = NULL;
269 }
270
272}
273/*---------------------------------------------------------------------------*/
274void
276{
277 int i;
278
279 for(i = 0; i < SIXTOP_MAX_SCHEDULING_FUNCTIONS; i++) {
280 if(scheduling_functions[i] != NULL &&
281 scheduling_functions[i]->init != NULL) {
282 scheduling_functions[i]->init();
283 }
284 }
285}
286/*---------------------------------------------------------------------------*/
287/** @} */
802.15.4 frame creation and parsing functions
IEEE 802.15.4e Information Element (IE) creation and parsing.
int frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
Parses an input frame.
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition linkaddr.c:48
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition packetbuf.c:136
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition packetbuf.c:143
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
Definition packetbuf.c:167
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Definition packetbuf.c:155
uint8_t packetbuf_hdrlen(void)
Get the length of the header in the packetbuf.
Definition packetbuf.c:161
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
Definition packetbuf.c:149
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Definition packetbuf.h:67
int packetbuf_hdralloc(int size)
Extend the header of the packetbuf, for outbound packets.
Definition packetbuf.c:107
int packetbuf_hdrreduce(int size)
Reduce the header in the packetbuf, for incoming packets.
Definition packetbuf.c:124
const sixtop_sf_t * sixtop_find_sf(uint8_t sfid)
Find a SF which has been added by SFID.
Definition sixtop.c:110
uint8_t sfid
SFID.
Definition sixtop.h:105
int sixtop_add_sf(const sixtop_sf_t *sf)
Add a Scheduling Function (SF) to 6top Sublayer.
Definition sixtop.c:74
#define SIXTOP_MAX_SCHEDULING_FUNCTIONS
The maximum number of Scheduling Functions in the system.
Definition sixtop-conf.h:51
void sixtop_input(void)
Input a packet stored in packetbuf.
Definition sixtop.c:204
void sixtop_init(void)
Initialize 6top module This initialization function removes all the SFs which has been installed into...
Definition sixtop.c:261
void sixp_init(void)
Initialize 6P Module It invokes sixp_nbr_init() and sixp_trans_init().
Definition sixp.c:532
void sixp_input(const uint8_t *buf, uint16_t len, const linkaddr_t *src_addr)
Input a 6P packet.
Definition sixp.c:205
void sixtop_init_sf(void)
Initialize installed SFs which has been added in the system This function is supposed to be invoked e...
Definition sixtop.c:275
int sixtop_output(const linkaddr_t *dest_addr, mac_callback_t callback, void *arg)
Output a 6P packet which is supposestored in packetbuf.
Definition sixtop.c:125
Header file for the logging system.
@ MAC_TX_ERR_FATAL
The MAC layer transmission could not be performed because of insufficient queue space,...
Definition mac.h:112
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet buffer (packetbuf) management.
6top Protocol (6P) APIs
6top Configuration
6TiSCH Operation Sublayer (6top) APIs
uint8_t frame_type
3 bit.
uint8_t frame_version
2 bit.
uint8_t ie_list_present
1 bit.
Parameters used by the frame802154_create() function.
frame802154_fcf_t fcf
Frame control field
void(* send)(mac_callback_t sent_callback, void *ptr)
Send a packet from the packetbuf
Definition mac.h:75
/brief Scheduling Function Driver
Definition sixtop.h:104
void(* init)(void)
Init Function.
Definition sixtop.h:107