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 packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx)
69 {
70  if(sessionid < MAX_CALLBACKS) {
71  struct tx_callback *callback;
72  callback = &callbacks[sessionid];
74  packetbuf_attr_copyfrom(callback->attrs, callback->addrs);
75  mac_call_sent_callback(callback->cback, callback->ptr, status, tx);
76  } else {
77  LOG_ERR("Session id to high (%d)\n", sessionid);
78  }
79 }
80 /*---------------------------------------------------------------------------*/
81 static int
82 setup_callback(mac_callback_t sent, void *ptr)
83 {
84  struct tx_callback *callback;
85  int tmp = callback_pos;
86  callback = &callbacks[callback_pos];
87  callback->cback = sent;
88  callback->ptr = ptr;
89  packetbuf_attr_copyto(callback->attrs, callback->addrs);
90 
91  callback_pos++;
92  if(callback_pos >= MAX_CALLBACKS) {
93  callback_pos = 0;
94  }
95 
96  return tmp;
97 }
98 /*---------------------------------------------------------------------------*/
99 static void
100 send_packet(mac_callback_t sent, void *ptr)
101 {
102  int size;
103  /* 3 bytes per packet attribute is required for serialization */
104  uint8_t buf[PACKETBUF_NUM_ATTRS * 3 + PACKETBUF_SIZE + 3];
105  uint8_t sid;
106 
107  packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);
108 
109  /* ack or not ? */
110  packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
111 
112  /* Will make it send only DATA packets... for now */
113  packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
114 
115  LOG_INFO("sending packet (%u bytes)\n", packetbuf_datalen());
116 
117  if(NETSTACK_FRAMER.create() < 0) {
118  /* Failed to allocate space for headers */
119  LOG_WARN("send failed, too large header\n");
120  mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
121  } else {
122  /* here we send the data over SLIP to the radio-chip */
123  size = 0;
124 #if SERIALIZE_ATTRIBUTES
125  size = packetutils_serialize_atts(&buf[3], sizeof(buf) - 3);
126 #endif
127  if(size < 0 || size + packetbuf_totlen() + 3 > sizeof(buf)) {
128  LOG_WARN("send failed, too large header\n");
129  mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1);
130  } else {
131  sid = setup_callback(sent, ptr);
132 
133  buf[0] = '!';
134  buf[1] = 'S';
135  buf[2] = sid; /* sequence or session number for this packet */
136 
137  /* Copy packet data */
138  memcpy(&buf[3 + size], packetbuf_hdrptr(), packetbuf_totlen());
139 
140  write_to_slip(buf, packetbuf_totlen() + size + 3);
141  }
142  }
143 }
144 /*---------------------------------------------------------------------------*/
145 static void
146 packet_input(void)
147 {
148  if(NETSTACK_FRAMER.parse() < 0) {
149  LOG_DBG("failed to parse %u\n", packetbuf_datalen());
150  } else {
151  NETSTACK_NETWORK.input();
152  }
153 }
154 /*---------------------------------------------------------------------------*/
155 static int
156 on(void)
157 {
158  return 1;
159 }
160 /*---------------------------------------------------------------------------*/
161 static int
162 off()
163 {
164  return 1;
165 }
166 /*---------------------------------------------------------------------------*/
167 static void
168 init(void)
169 {
170  callback_pos = 0;
171 }
172 /*---------------------------------------------------------------------------*/
173 const struct mac_driver border_router_mac_driver = {
174  "br-mac",
175  init,
176  send_packet,
177  packet_input,
178  on,
179  off
180 };
181 /*---------------------------------------------------------------------------*/
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:1475
static void packet_sent(void *ptr, int status, int transmissions)
Callback function for the MAC packet sent callback.
Definition: sicslowpan.c:1444
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:66
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)
Header file for the logging system