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