Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2007, Swedish Institute of Computer Science. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 */ 00032 00033 /** 00034 * \file 00035 * A Chameleon module that produces non-optimized headers 00036 * \author 00037 * Adam Dunkels <adam@sics.se> 00038 */ 00039 00040 #include <string.h> 00041 00042 #include "net/rime/chameleon.h" 00043 #include "net/rime.h" 00044 00045 /* This option enables an optimization where the link addresses are 00046 left to the MAC RDC and not encoded in the Chameleon header. 00047 Note: this requires that the underlying MAC layer to add link 00048 addresses and will not work together with for example nullrdc. 00049 */ 00050 #ifdef CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES 00051 #define CHAMELEON_WITH_MAC_LINK_ADDRESSES CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES 00052 #else /* !CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES */ 00053 #define CHAMELEON_WITH_MAC_LINK_ADDRESSES 0 00054 #endif /* !CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES */ 00055 00056 #define DEBUG 0 00057 #if DEBUG 00058 #include <stdio.h> 00059 #define PRINTF(...) printf(__VA_ARGS__) 00060 #else 00061 #define PRINTF(...) 00062 #endif 00063 00064 struct raw_hdr { 00065 uint8_t channel[2]; 00066 }; 00067 00068 /*---------------------------------------------------------------------------*/ 00069 static struct channel * 00070 input(void) 00071 { 00072 const struct packetbuf_attrlist *a; 00073 int byteptr, bitptr, len; 00074 uint8_t *hdrptr; 00075 struct raw_hdr *hdr; 00076 struct channel *c; 00077 00078 /* The packet has a header that tells us what channel the packet is 00079 for. */ 00080 hdr = (struct raw_hdr *)packetbuf_dataptr(); 00081 if(packetbuf_hdrreduce(sizeof(struct raw_hdr)) == 0) { 00082 PRINTF("chameleon-raw: too short packet\n"); 00083 return NULL; 00084 } 00085 c = channel_lookup((hdr->channel[1] << 8) + hdr->channel[0]); 00086 if(c == NULL) { 00087 PRINTF("chameleon-raw: input: channel %u not found\n", 00088 (hdr->channel[1] << 8) + hdr->channel[0]); 00089 return NULL; 00090 } 00091 00092 hdrptr = packetbuf_dataptr(); 00093 if(packetbuf_hdrreduce(c->hdrsize) == 0) { 00094 PRINTF("chameleon-raw: too short packet\n"); 00095 return NULL; 00096 } 00097 byteptr = bitptr = 0; 00098 for(a = c->attrlist; a->type != PACKETBUF_ATTR_NONE; ++a) { 00099 #if CHAMELEON_WITH_MAC_LINK_ADDRESSES 00100 if(a->type == PACKETBUF_ADDR_SENDER || 00101 a->type == PACKETBUF_ADDR_RECEIVER) { 00102 /* Let the link layer handle sender and receiver */ 00103 continue; 00104 } 00105 #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */ 00106 PRINTF("%d.%d: unpack_header type %d, len %d\n", 00107 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], 00108 a->type, a->len); 00109 len = (a->len & 0xf8) + ((a->len & 7) ? 8: 0); 00110 if(PACKETBUF_IS_ADDR(a->type)) { 00111 const rimeaddr_t addr; 00112 memcpy((uint8_t *)&addr, &hdrptr[byteptr], len / 8); 00113 PRINTF("%d.%d: unpack_header type %d, addr %d.%d\n", 00114 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], 00115 a->type, addr.u8[0], addr.u8[1]); 00116 packetbuf_set_addr(a->type, &addr); 00117 } else { 00118 packetbuf_attr_t val = 0; 00119 memcpy((uint8_t *)&val, &hdrptr[byteptr], len / 8); 00120 00121 packetbuf_set_attr(a->type, val); 00122 PRINTF("%d.%d: unpack_header type %d, val %d\n", 00123 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], 00124 a->type, val); 00125 } 00126 byteptr += len / 8; 00127 } 00128 return c; 00129 } 00130 /*---------------------------------------------------------------------------*/ 00131 static int 00132 output(struct channel *c) 00133 { 00134 const struct packetbuf_attrlist *a; 00135 int byteptr, len; 00136 uint8_t *hdrptr; 00137 struct raw_hdr *hdr; 00138 00139 /* Compute the total size of the final header by summing the size of 00140 all attributes that are used on this channel. */ 00141 if(packetbuf_hdralloc(c->hdrsize + sizeof(struct raw_hdr)) == 0) { 00142 PRINTF("chameleon-raw: insufficient space for headers\n"); 00143 return 0; 00144 } 00145 hdr = (struct raw_hdr *)packetbuf_hdrptr(); 00146 hdr->channel[0] = c->channelno & 0xff; 00147 hdr->channel[1] = (c->channelno >> 8) & 0xff; 00148 00149 hdrptr = ((uint8_t *)packetbuf_hdrptr()) + sizeof(struct raw_hdr); 00150 byteptr = 0; 00151 for(a = c->attrlist; a->type != PACKETBUF_ATTR_NONE; ++a) { 00152 #if CHAMELEON_WITH_MAC_LINK_ADDRESSES 00153 if(a->type == PACKETBUF_ADDR_SENDER || 00154 a->type == PACKETBUF_ADDR_RECEIVER) { 00155 /* Let the link layer handle sender and receiver */ 00156 PRINTF("%d.%d: pack_header leaving sender/receiver to link layer\n"); 00157 continue; 00158 } 00159 #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */ 00160 PRINTF("%d.%d: pack_header type %d, len %d\n", 00161 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], 00162 a->type, a->len); 00163 len = (a->len & 0xf8) + ((a->len & 7) ? 8: 0); 00164 if(PACKETBUF_IS_ADDR(a->type)) { 00165 const rimeaddr_t *rimeaddr; 00166 /* memcpy(&hdrptr[byteptr], (uint8_t *)packetbuf_attr_aget(a->type), len / 8);*/ 00167 rimeaddr = packetbuf_addr(a->type); 00168 hdrptr[byteptr] = rimeaddr->u8[0]; 00169 hdrptr[byteptr + 1] = rimeaddr->u8[1]; 00170 00171 PRINTF("%d.%d: address %d.%d\n", 00172 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], 00173 ((uint8_t *)packetbuf_addr(a->type))[0], 00174 ((uint8_t *)packetbuf_addr(a->type))[1]); 00175 } else { 00176 packetbuf_attr_t val; 00177 val = packetbuf_attr(a->type); 00178 memcpy(&hdrptr[byteptr], &val, len / 8); 00179 PRINTF("%d.%d: value %d\n", 00180 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1], 00181 val); 00182 } 00183 byteptr += len / 8; 00184 } 00185 00186 return 1; /* Send out packet */ 00187 } 00188 /*---------------------------------------------------------------------------*/ 00189 static int 00190 hdrsize(const struct packetbuf_attrlist *a) 00191 { 00192 int size, len; 00193 00194 /* Compute the total size of the final header by summing the size of 00195 all attributes that are used on this channel. */ 00196 00197 size = 0; 00198 for(; a->type != PACKETBUF_ATTR_NONE; ++a) { 00199 /* PRINTF("chameleon header_size: header type %d len %d\n", 00200 a->type, a->len);*/ 00201 #if CHAMELEON_WITH_MAC_LINK_ADDRESSES 00202 if(a->type == PACKETBUF_ADDR_SENDER || 00203 a->type == PACKETBUF_ADDR_RECEIVER) { 00204 /* Let the mac layer handle the sender and receiver */ 00205 continue; 00206 } 00207 #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */ 00208 len = a->len; 00209 if(len < 8) { 00210 len = 8; 00211 } 00212 size += len; 00213 } 00214 return size / 8; 00215 } 00216 /*---------------------------------------------------------------------------*/ 00217 CC_CONST_FUNCTION struct chameleon_module chameleon_raw = { input, output, 00218 hdrsize };