Contiki-NG
border-router-mac.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, 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  * A null RDC implementation that uses framer for headers and sends
33  * the packets over slip instead of radio.
34  * \author
35  * Adam Dunkels <adam@sics.se>
36  * Joakim Eriksson <joakime@sics.se>
37  * Niclas Finne <nfi@sics.se>
38  */
39 
40 #include "net/packetbuf.h"
41 #include "net/queuebuf.h"
42 #include "net/netstack.h"
43 #include "packetutils.h"
44 #include "border-router.h"
45 #include <string.h>
46 
47 /*---------------------------------------------------------------------------*/
48 /* Log configuration */
49 #include "sys/log.h"
50 #define LOG_MODULE "BR-MAC"
51 #define LOG_LEVEL LOG_LEVEL_NONE
52 
53 #define MAX_CALLBACKS 16
54 static int callback_pos;
55 
56 /* a structure for calling back when packet data is coming back
57  from radio... */
58 struct tx_callback {
59  mac_callback_t cback;
60  void *ptr;
61  struct packetbuf_attr attrs[PACKETBUF_NUM_ATTRS];
62  struct packetbuf_addr addrs[PACKETBUF_NUM_ADDRS];
63 };
64 /*---------------------------------------------------------------------------*/
65 static struct tx_callback callbacks[MAX_CALLBACKS];
66 /*---------------------------------------------------------------------------*/
67 void
68 init_sec(void)
69 {
70  /* use the CSMA LLSEC config parameter */
71 #if LLSEC802154_USES_AUX_HEADER
72  if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) ==
73  PACKETBUF_ATTR_SECURITY_LEVEL_DEFAULT) {
74  packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
75  CSMA_LLSEC_SECURITY_LEVEL);
76  }
77 #endif
78 }
79 /*---------------------------------------------------------------------------*/
80 
81 void
82 packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx)
83 {
84  if(sessionid < MAX_CALLBACKS) {
85  struct tx_callback *callback;
86  callback = &callbacks[sessionid];
88  packetbuf_attr_copyfrom(callback->attrs, callback->addrs);
89  mac_call_sent_callback(callback->cback, callback->ptr, status, tx);
90  } else {
91  LOG_ERR("Session id to high (%d)\n", sessionid);
92  }
93 }
94 /*---------------------------------------------------------------------------*/
95 static int
96 setup_callback(mac_callback_t sent, void *ptr)
97 {
98  struct tx_callback *callback;
99  int tmp = callback_pos;
100  callback = &callbacks[callback_pos];
101  callback->cback = sent;
102  callback->ptr = ptr;
103  packetbuf_attr_copyto(callback->attrs, callback->addrs);
104 
105  callback_pos++;
106  if(callback_pos >= MAX_CALLBACKS) {
107  callback_pos = 0;
108  }
109 
110  return tmp;
111 }
112 /*---------------------------------------------------------------------------*/
113 static void
114 send_packet(mac_callback_t sent, void *ptr)
115 {
116  int size;
117  /* 3 bytes per packet attribute is required for serialization */
118  uint8_t buf[PACKETBUF_NUM_ATTRS * 3 + PACKETBUF_SIZE + 3];
119  uint8_t sid;
120 
121  packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);
122 
123  /* ack or not ? */
124  packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
125 
126  /* Will make it send only DATA packets... for now */
127  packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
128 
129  LOG_INFO("sending packet (%u bytes)\n", packetbuf_datalen());
130 
131  if(NETSTACK_FRAMER.create() < 0) {
132  /* Failed to allocate space for headers */
133  LOG_WARN("send failed, too large header\n");
134  mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
135  } else {
136  /* here we send the data over SLIP to the radio-chip */
137  size = 0;
138 #if SERIALIZE_ATTRIBUTES
139  size = packetutils_serialize_atts(&buf[3], sizeof(buf) - 3);
140 #endif
141  if(size < 0 || size + packetbuf_totlen() + 3 > sizeof(buf)) {
142  LOG_WARN("send failed, too large header\n");
143  mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
144  } else {
145  sid = setup_callback(sent, ptr);
146 
147  buf[0] = '!';
148  buf[1] = 'S';
149  buf[2] = sid; /* sequence or session number for this packet */
150 
151  /* Copy packet data */
152  memcpy(&buf[3 + size], packetbuf_hdrptr(), packetbuf_totlen());
153 
154  write_to_slip(buf, packetbuf_totlen() + size + 3);
155  }
156  }
157 }
158 /*---------------------------------------------------------------------------*/
159 static void
160 packet_input(void)
161 {
162  if(NETSTACK_FRAMER.parse() < 0) {
163  LOG_DBG("failed to parse %u\n", packetbuf_datalen());
164  } else {
165  NETSTACK_NETWORK.input();
166  }
167 }
168 /*---------------------------------------------------------------------------*/
169 static int
170 on(void)
171 {
172  return 1;
173 }
174 /*---------------------------------------------------------------------------*/
175 static int
176 off()
177 {
178  return 1;
179 }
180 /*---------------------------------------------------------------------------*/
181 static int
182 max_payload()
183 {
184  init_sec();
185  return 127 - NETSTACK_FRAMER.length();
186 }
187 /*---------------------------------------------------------------------------*/
188 static void
189 init(void)
190 {
191  callback_pos = 0;
192 }
193 /*---------------------------------------------------------------------------*/
194 const struct mac_driver border_router_mac_driver = {
195  "br-mac",
196  init,
197  send_packet,
198  packet_input,
199  on,
200  off,
201  max_payload,
202 };
203 /*---------------------------------------------------------------------------*/
int(* on)(void)
Turn the MAC layer on.
Definition: mac.h:75
void packetbuf_clear(void)
Clear and reset the packetbuf.
Definition: packetbuf.c:75
Border router header file
The structure of a MAC protocol driver in Contiki.
Definition: mac.h:62
static void send_packet(linkaddr_t *dest)
This function is called by the 6lowpan code to send out a packet.
Definition: sicslowpan.c:1491
static void packet_sent(void *ptr, int status, int transmissions)
Callback function for the MAC packet sent callback.
Definition: sicslowpan.c:1460
int(* off)(void)
Turn the MAC layer off.
Definition: mac.h:78
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Definition: packetbuf.c:155
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition: linkaddr.c:48
Header file for the Packet queue buffer management
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
Definition: packetbuf.c:167
#define PACKETBUF_SIZE
The size of the packetbuf, in bytes.
Definition: packetbuf.h:67
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
Definition: packetbuf.c:149
void(* init)(void)
Initialize the MAC driver.
Definition: mac.h:66
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)
int(* max_payload)(void)
Read out estimated max payload size based on payload in packetbuf.
Definition: mac.h:81
Header file for the logging system