Contiki 3.x
chameleon-raw.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007, 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  * A Chameleon module that produces non-optimized headers
36  * \author
37  * Adam Dunkels <adam@sics.se>
38  */
39 
40 #include <string.h>
41 
42 #include "net/rime/chameleon.h"
43 #include "net/rime/rime.h"
44 
45 /* This option enables an optimization where the link addresses are
46  left to the MAC RDC and not encoded in the Chameleon header.
47  Note: this requires that the underlying MAC layer to add link
48  addresses and will not work together with for example nullrdc.
49  */
50 #ifdef CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES
51 #define CHAMELEON_WITH_MAC_LINK_ADDRESSES CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES
52 #else /* !CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES */
53 #define CHAMELEON_WITH_MAC_LINK_ADDRESSES 0
54 #endif /* !CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES */
55 
56 #define DEBUG 0
57 #if DEBUG
58 #include <stdio.h>
59 #define PRINTF(...) printf(__VA_ARGS__)
60 #else
61 #define PRINTF(...)
62 #endif
63 
64 struct raw_hdr {
65  uint8_t channel[2];
66 };
67 
68 /*---------------------------------------------------------------------------*/
69 static struct channel *
70 input(void)
71 {
72  const struct packetbuf_attrlist *a;
73  int byteptr, bitptr, len;
74  uint8_t *hdrptr;
75  struct raw_hdr *hdr;
76  struct channel *c;
77 
78  /* The packet has a header that tells us what channel the packet is
79  for. */
80  hdr = (struct raw_hdr *)packetbuf_dataptr();
81  if(packetbuf_hdrreduce(sizeof(struct raw_hdr)) == 0) {
82  PRINTF("chameleon-raw: too short packet\n");
83  return NULL;
84  }
85  c = channel_lookup((hdr->channel[1] << 8) + hdr->channel[0]);
86  if(c == NULL) {
87  PRINTF("chameleon-raw: input: channel %u not found\n",
88  (hdr->channel[1] << 8) + hdr->channel[0]);
89  return NULL;
90  }
91 
92  hdrptr = packetbuf_dataptr();
93  if(packetbuf_hdrreduce(c->hdrsize) == 0) {
94  PRINTF("chameleon-raw: too short packet\n");
95  return NULL;
96  }
97  byteptr = bitptr = 0;
98  for(a = c->attrlist; a->type != PACKETBUF_ATTR_NONE; ++a) {
99 #if CHAMELEON_WITH_MAC_LINK_ADDRESSES
100  if(a->type == PACKETBUF_ADDR_SENDER ||
101  a->type == PACKETBUF_ADDR_RECEIVER) {
102  /* Let the link layer handle sender and receiver */
103  continue;
104  }
105 #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */
106  PRINTF("%d.%d: unpack_header type %d, len %d\n",
108  a->type, a->len);
109  len = (a->len & 0xf8) + ((a->len & 7) ? 8: 0);
110  if(PACKETBUF_IS_ADDR(a->type)) {
111  const linkaddr_t addr;
112  memcpy((uint8_t *)&addr, &hdrptr[byteptr], len / 8);
113  PRINTF("%d.%d: unpack_header type %d, addr %d.%d\n",
115  a->type, addr.u8[0], addr.u8[1]);
116  packetbuf_set_addr(a->type, &addr);
117  } else {
118  packetbuf_attr_t val = 0;
119  memcpy((uint8_t *)&val, &hdrptr[byteptr], len / 8);
120 
121  packetbuf_set_attr(a->type, val);
122  PRINTF("%d.%d: unpack_header type %d, val %d\n",
124  a->type, val);
125  }
126  byteptr += len / 8;
127  }
128  return c;
129 }
130 /*---------------------------------------------------------------------------*/
131 static int
132 output(struct channel *c)
133 {
134  const struct packetbuf_attrlist *a;
135  int byteptr, len;
136  uint8_t *hdrptr;
137  struct raw_hdr *hdr;
138 
139  /* Compute the total size of the final header by summing the size of
140  all attributes that are used on this channel. */
141  if(packetbuf_hdralloc(c->hdrsize + sizeof(struct raw_hdr)) == 0) {
142  PRINTF("chameleon-raw: insufficient space for headers\n");
143  return 0;
144  }
145  hdr = (struct raw_hdr *)packetbuf_hdrptr();
146  hdr->channel[0] = c->channelno & 0xff;
147  hdr->channel[1] = (c->channelno >> 8) & 0xff;
148 
149  hdrptr = ((uint8_t *)packetbuf_hdrptr()) + sizeof(struct raw_hdr);
150  byteptr = 0;
151  for(a = c->attrlist; a->type != PACKETBUF_ATTR_NONE; ++a) {
152 #if CHAMELEON_WITH_MAC_LINK_ADDRESSES
153  if(a->type == PACKETBUF_ADDR_SENDER ||
154  a->type == PACKETBUF_ADDR_RECEIVER) {
155  /* Let the link layer handle sender and receiver */
156  PRINTF("%d.%d: pack_header leaving sender/receiver to link layer\n");
157  continue;
158  }
159 #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */
160  PRINTF("%d.%d: pack_header type %d, len %d\n",
162  a->type, a->len);
163  len = (a->len & 0xf8) + ((a->len & 7) ? 8: 0);
164  if(PACKETBUF_IS_ADDR(a->type)) {
165  const linkaddr_t *linkaddr;
166  /* memcpy(&hdrptr[byteptr], (uint8_t *)packetbuf_attr_aget(a->type), len / 8);*/
167  linkaddr = packetbuf_addr(a->type);
168  hdrptr[byteptr] = linkaddr->u8[0];
169  hdrptr[byteptr + 1] = linkaddr->u8[1];
170 
171  PRINTF("%d.%d: address %d.%d\n",
173  ((uint8_t *)packetbuf_addr(a->type))[0],
174  ((uint8_t *)packetbuf_addr(a->type))[1]);
175  } else {
176  packetbuf_attr_t val;
177  val = packetbuf_attr(a->type);
178  memcpy(&hdrptr[byteptr], &val, len / 8);
179  PRINTF("%d.%d: value %d\n",
181  val);
182  }
183  byteptr += len / 8;
184  }
185 
186  return 1; /* Send out packet */
187 }
188 /*---------------------------------------------------------------------------*/
189 static int
190 hdrsize(const struct packetbuf_attrlist *a)
191 {
192  int size, len;
193 
194  /* Compute the total size of the final header by summing the size of
195  all attributes that are used on this channel. */
196 
197  size = 0;
198  for(; a->type != PACKETBUF_ATTR_NONE; ++a) {
199  /* PRINTF("chameleon header_size: header type %d len %d\n",
200  a->type, a->len);*/
201 #if CHAMELEON_WITH_MAC_LINK_ADDRESSES
202  if(a->type == PACKETBUF_ADDR_SENDER ||
203  a->type == PACKETBUF_ADDR_RECEIVER) {
204  /* Let the mac layer handle the sender and receiver */
205  continue;
206  }
207 #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */
208  len = a->len;
209  if(len < 8) {
210  len = 8;
211  }
212  size += len;
213  }
214  return size / 8;
215 }
216 /*---------------------------------------------------------------------------*/
217 CC_CONST_FUNCTION struct chameleon_module chameleon_raw = { input, output,
218  hdrsize };
int packetbuf_hdralloc(int size)
Extend the header of the packetbuf, for outbound packets.
Definition: packetbuf.c:172
linkaddr_t linkaddr_node_addr
The Rime address of the node.
Definition: linkaddr.c:48
Header file for Chameleon, Rime&#39;s header processing module
#define CC_CONST_FUNCTION
Configure if the C compiler have problems with const function pointers.
Definition: cc.h:86
#define NULL
The null pointer.
Header file for the Rime stack
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
Definition: packetbuf.c:213
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