Contiki 3.x
contikimac-framer.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Fraunhofer Heinrich-Hertz-Institut.
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 /**
32  * \file
33  * Creates and parses the ContikiMAC header.
34  * \author
35  * Konrad Krentz <konrad.krentz@gmail.com>
36  */
37 
39 #include "net/packetbuf.h"
40 #include "net/netstack.h"
41 #include <string.h>
42 
43 #define CONTIKIMAC_ID 0x00
44 
45 /* SHORTEST_PACKET_SIZE is the shortest packet that ContikiMAC
46  allows. Packets have to be a certain size to be able to be detected
47  by two consecutive CCA checks, and here is where we define this
48  shortest size.
49  Padded packets will have the wrong ipv6 checksum unless CONTIKIMAC_HEADER
50  is used (on both sides) and the receiver will ignore them.
51  With no header, reduce to transmit a proper multicast RPL DIS. */
52 #ifdef CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE
53 #define SHORTEST_PACKET_SIZE CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE
54 #else /* CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE */
55 #define SHORTEST_PACKET_SIZE 43
56 #endif /* CONTIKIMAC_FRAMER_CONF_SHORTEST_PACKET_SIZE */
57 
58 #ifdef CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER
59 #define DECORATED_FRAMER CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER
60 #else /* CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER */
61 #define DECORATED_FRAMER framer_802154
62 #endif /* CONTIKIMAC_FRAMER_CONF_DECORATED_FRAMER */
63 
64 extern const struct framer DECORATED_FRAMER;
65 
66 #define DEBUG 0
67 #if DEBUG
68 #include <stdio.h>
69 #define PRINTF(...) printf(__VA_ARGS__)
70 #else
71 #define PRINTF(...)
72 #endif
73 
74 /* 2-byte header for recovering padded packets.
75  Wireshark will not understand such packets at present. */
76 struct hdr {
77  uint8_t id;
78  uint8_t len;
79 };
80 
81 /*---------------------------------------------------------------------------*/
82 static int
83 create(void)
84 {
85  struct hdr *chdr;
86  int hdr_len;
87 
88  if(packetbuf_hdralloc(sizeof(struct hdr)) == 0) {
89  PRINTF("contikimac-framer: too large header\n");
90  return FRAMER_FAILED;
91  }
92  chdr = packetbuf_hdrptr();
93  chdr->id = CONTIKIMAC_ID;
94  chdr->len = 0;
95 
96  hdr_len = DECORATED_FRAMER.create();
97  if(hdr_len < 0) {
98  PRINTF("contikimac-framer: decorated framer failed\n");
99  return FRAMER_FAILED;
100  }
101 
102  return hdr_len + sizeof(struct hdr);
103 }
104 /*---------------------------------------------------------------------------*/
105 static void
106 pad(void)
107 {
108  int transmit_len;
109  uint8_t *ptr;
110  uint8_t zeroes_count;
111 
112  transmit_len = packetbuf_totlen();
113  if(transmit_len < SHORTEST_PACKET_SIZE) {
114  /* Padding required */
115  zeroes_count = SHORTEST_PACKET_SIZE - transmit_len;
116  ptr = packetbuf_dataptr();
117  memset(ptr + packetbuf_datalen(), 0, zeroes_count);
118  packetbuf_set_datalen(packetbuf_datalen() + zeroes_count);
119  }
120 }
121 /*---------------------------------------------------------------------------*/
122 static int
123 create_and_secure(void)
124 {
125  struct hdr *chdr;
126  int hdr_len;
127 
128  hdr_len = create();
129  if(hdr_len < 0) {
130  return FRAMER_FAILED;
131  }
132 
134  if(!NETSTACK_LLSEC.on_frame_created()) {
135  PRINTF("contikimac-framer: securing failed\n");
136  return FRAMER_FAILED;
137  }
138 
139  chdr = (struct hdr *)(((uint8_t *) packetbuf_dataptr()) - sizeof(struct hdr));
140  chdr->len = packetbuf_datalen();
141  pad();
142 
143  return hdr_len;
144 }
145 /*---------------------------------------------------------------------------*/
146 static int
147 parse(void)
148 {
149  int hdr_len;
150  struct hdr *chdr;
151 
152  hdr_len = DECORATED_FRAMER.parse();
153  if(hdr_len < 0) {
154  return FRAMER_FAILED;
155  }
156 
157  chdr = packetbuf_dataptr();
158  if(chdr->id != CONTIKIMAC_ID) {
159  PRINTF("contikimac-framer: CONTIKIMAC_ID is missing\n");
160  return FRAMER_FAILED;
161  }
162 
163  if(!packetbuf_hdrreduce(sizeof(struct hdr))) {
164  PRINTF("contikimac-framer: packetbuf_hdrreduce failed\n");
165  return FRAMER_FAILED;
166  }
167 
168  packetbuf_set_datalen(chdr->len);
169  chdr->len = 0;
170 
171  return hdr_len + sizeof(struct hdr);
172 }
173 /*---------------------------------------------------------------------------*/
174 const struct framer contikimac_framer = {
175  create,
176  create_and_secure,
177  parse
178 };
179 /*---------------------------------------------------------------------------*/
int packetbuf_hdralloc(int size)
Extend the header of the packetbuf, for outbound packets.
Definition: packetbuf.c:172
Header file for the Rime buffer (packetbuf) management
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition: packetbuf.c:200
uint16_t packetbuf_totlen(void)
Get the total length of the header and data in the packetbuf.
Definition: packetbuf.c:260
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Definition: packetbuf.c:239
Creates and parses the ContikiMAC header.
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
Definition: packetbuf.c:213
void packetbuf_compact(void)
Compact the packetbuf.
Definition: packetbuf.c:105
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:207
int packetbuf_hdrreduce(int size)
Reduce the header in the packetbuf, for incoming packets.
Definition: packetbuf.c:188
Include file for the Contiki low-layer network stack (NETSTACK)