Contiki-NG
Loading...
Searching...
No Matches
csma.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010, 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 * This file is part of the Contiki operating system.
30 *
31 */
32
33/**
34 * \file
35* The 802.15.4 standard CSMA protocol (nonbeacon-enabled)
36 * \author
37 * Adam Dunkels <adam@sics.se>
38 * Simon Duquennoy <simon.duquennoy@inria.fr>
39 */
40
41#include "net/mac/csma/csma.h"
45#include "net/packetbuf.h"
46#include "net/netstack.h"
47
48/* Log configuration */
49#include "sys/log.h"
50#define LOG_MODULE "CSMA"
51#define LOG_LEVEL LOG_LEVEL_MAC
52
53
54static void
55init_sec(void)
56{
57#if LLSEC802154_USES_AUX_HEADER
58 if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) ==
59 PACKETBUF_ATTR_SECURITY_LEVEL_DEFAULT) {
60 packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
61 CSMA_LLSEC_SECURITY_LEVEL);
62 }
63#endif
64}
65/*---------------------------------------------------------------------------*/
66static void
67send_packet(mac_callback_t sent, void *ptr)
68{
69
70 init_sec();
71
72 csma_output_packet(sent, ptr);
73}
74/*---------------------------------------------------------------------------*/
75static void
76input_packet(void)
77{
78#if CSMA_SEND_SOFT_ACK
79 uint8_t ackdata[CSMA_ACK_LEN];
80#endif
81
82 if(packetbuf_datalen() == CSMA_ACK_LEN) {
83 /* Ignore ack packets */
84 LOG_DBG("ignored ack\n");
85 } else if(CSMA_FRAMER.parse() < 0) {
86 LOG_ERR("failed to parse %u\n", packetbuf_datalen());
87 } else if(!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
90 LOG_WARN("not for us\n");
91 } else if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER), &linkaddr_node_addr)) {
92 LOG_WARN("frame from ourselves\n");
93 } else {
94 int duplicate = 0;
95
96 /* Check for duplicate packet. */
97 duplicate = mac_sequence_is_duplicate();
98 if(duplicate) {
99 /* Drop the packet. */
100 LOG_WARN("drop duplicate link layer packet from ");
101 LOG_WARN_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
102 LOG_WARN_(", seqno %u\n", packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
103 } else {
105 }
106
107#if CSMA_SEND_SOFT_ACK
108 if(packetbuf_attr(PACKETBUF_ATTR_MAC_ACK)) {
109 ackdata[0] = FRAME802154_ACKFRAME;
110 ackdata[1] = 0;
111 ackdata[2] = ((uint8_t *)packetbuf_hdrptr())[2];
112 NETSTACK_RADIO.send(ackdata, CSMA_ACK_LEN);
113 }
114#endif /* CSMA_SEND_SOFT_ACK */
115 if(!duplicate) {
116 LOG_INFO("received packet from ");
117 LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
118 LOG_INFO_(", seqno %u, len %u\n", packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO), packetbuf_datalen());
119 NETSTACK_NETWORK.input();
120 }
121 }
122}
123/*---------------------------------------------------------------------------*/
124static int
125on(void)
126{
127 return NETSTACK_RADIO.on();
128}
129/*---------------------------------------------------------------------------*/
130static int
131off(void)
132{
133 return NETSTACK_RADIO.off();
134}
135/*---------------------------------------------------------------------------*/
136static void
137init(void)
138{
139 radio_value_t radio_max_payload_len;
140
141 /* Check that the radio can correctly report its max supported payload */
142 if(NETSTACK_RADIO.get_value(RADIO_CONST_MAX_PAYLOAD_LEN, &radio_max_payload_len) != RADIO_RESULT_OK) {
143 LOG_ERR("! radio does not support getting RADIO_CONST_MAX_PAYLOAD_LEN. Abort init.\n");
144 return;
145 }
146
147#if CSMA_SEND_SOFT_ACK
148 radio_value_t radio_rx_mode;
149
150 /* Disable radio driver's autoack */
151 if(NETSTACK_RADIO.get_value(RADIO_PARAM_RX_MODE, &radio_rx_mode) != RADIO_RESULT_OK) {
152 LOG_WARN("radio does not support getting RADIO_PARAM_RX_MODE\n");
153 } else {
154 /* Unset autoack */
155 radio_rx_mode &= ~RADIO_RX_MODE_AUTOACK;
156 if(NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, radio_rx_mode) != RADIO_RESULT_OK) {
157 LOG_WARN("radio does not support setting RADIO_PARAM_RX_MODE\n");
158 }
159 }
160#endif
161
163
164#if LLSEC802154_USES_AUX_HEADER
165#ifdef CSMA_LLSEC_DEFAULT_KEY0
166 uint8_t key[16] = CSMA_LLSEC_DEFAULT_KEY0;
167 csma_security_set_key(0, key);
168#endif
169#endif /* LLSEC802154_USES_AUX_HEADER */
170 csma_output_init();
171 on();
172}
173/*---------------------------------------------------------------------------*/
174static int
175max_payload(void)
176{
177 int framer_hdrlen;
178 radio_value_t max_radio_payload_len;
179 radio_result_t res;
180
181 init_sec();
182
183 framer_hdrlen = NETSTACK_FRAMER.length();
184
185 res = NETSTACK_RADIO.get_value(RADIO_CONST_MAX_PAYLOAD_LEN,
186 &max_radio_payload_len);
187
188 if(res == RADIO_RESULT_NOT_SUPPORTED) {
189 LOG_ERR("Failed to retrieve max radio driver payload length\n");
190 return 0;
191 }
192
193 if(framer_hdrlen < 0) {
194 /* Framing failed, we assume the maximum header length */
195 framer_hdrlen = CSMA_MAC_MAX_HEADER;
196 }
197
198 return MIN(max_radio_payload_len, PACKETBUF_SIZE)
199 - framer_hdrlen
200 - LLSEC802154_PACKETBUF_MIC_LEN();
201}
202/*---------------------------------------------------------------------------*/
203const struct mac_driver csma_driver = {
204 "CSMA",
205 init,
208 on,
209 off,
211};
212/*---------------------------------------------------------------------------*/
The 802.15.4 standard CSMA protocol (nonbeacon-enabled).
The 802.15.4 standard CSMA protocol (nonbeacon-enabled)
802.15.4 frame creation and parsing functions
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition linkaddr.c:48
bool linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
Definition linkaddr.c:69
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Definition packetbuf.c:155
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
bool packetbuf_holds_broadcast(void)
Checks whether the current packet is a broadcast.
Definition packetbuf.c:229
enum radio_result_e radio_result_t
Radio return values when setting or getting radio parameters.
int radio_value_t
Each radio has a set of parameters that designate the current configuration and state of the radio.
Definition radio.h:88
@ RADIO_RESULT_NOT_SUPPORTED
The parameter is not supported.
Definition radio.h:481
@ RADIO_RESULT_OK
The parameter was set/read successfully.
Definition radio.h:480
@ RADIO_PARAM_RX_MODE
Radio receiver mode determines if the radio has address filter (RADIO_RX_MODE_ADDRESS_FILTER) and aut...
Definition radio.h:173
static void send_packet(void)
This function is called by the 6lowpan code to send out a packet.
Header file for the logging system.
int mac_sequence_is_duplicate(void)
Tell whether the packetbuf is a duplicate packet.
void mac_sequence_register_seqno(void)
Register the sequence number of the packetbuf.
void mac_sequence_init(void)
brief Initializes the destination sequence number to a random value.
Header file for MAC sequence numbers management.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet buffer (packetbuf) management.
Stores data about an incoming packet.
Definition tsch-types.h:148
The structure of a MAC protocol driver in Contiki.
Definition mac.h:68
int(* on)(void)
Turn the MAC layer on.
Definition mac.h:81
int(* max_payload)(void)
Read out estimated max payload size based on payload in packetbuf.
Definition mac.h:87
int(* off)(void)
Turn the MAC layer off.
Definition mac.h:84
void(* init)(void)
Initialize the MAC driver.
Definition mac.h:72