chameleon-raw.c

Go to the documentation of this file.
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  * $Id: chameleon-raw.c,v 1.8 2010/05/28 06:18:39 nifi Exp $
00032  */
00033 
00034 /**
00035  * \file
00036  *         A Chameleon module that produces non-optimized headers
00037  * \author
00038  *         Adam Dunkels <adam@sics.se>
00039  */
00040 
00041 #include <string.h>
00042 
00043 #include "net/rime/chameleon.h"
00044 #include "net/rime.h"
00045 
00046 /* This option enables an optimization where the link addresses are
00047    left to the MAC RDC and not encoded in the Chameleon header.
00048    Note: this requires that the underlying MAC layer to add link
00049    addresses and will not work together with for example nullrdc.
00050  */
00051 #ifdef CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES
00052 #define CHAMELEON_WITH_MAC_LINK_ADDRESSES CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES
00053 #else /* !CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES */
00054 #define CHAMELEON_WITH_MAC_LINK_ADDRESSES 0
00055 #endif /* !CHAMELEON_CONF_WITH_MAC_LINK_ADDRESSES */
00056 
00057 #define DEBUG 0
00058 #if DEBUG
00059 #include <stdio.h>
00060 #define PRINTF(...) printf(__VA_ARGS__)
00061 #else
00062 #define PRINTF(...)
00063 #endif
00064 
00065 struct raw_hdr {
00066   uint8_t channel[2];
00067 };
00068 
00069 /*---------------------------------------------------------------------------*/
00070 static struct channel *
00071 input(void)
00072 {
00073   const struct packetbuf_attrlist *a;
00074   int byteptr, bitptr, len;
00075   uint8_t *hdrptr;
00076   struct raw_hdr *hdr;
00077   struct channel *c;
00078 
00079   /* The packet has a header that tells us what channel the packet is
00080      for. */
00081   hdr = (struct raw_hdr *)packetbuf_dataptr();
00082   if(packetbuf_hdrreduce(sizeof(struct raw_hdr)) == 0) {
00083     PRINTF("chameleon-raw: too short packet\n");
00084     return NULL;
00085   }
00086   c = channel_lookup((hdr->channel[1] << 8) + hdr->channel[0]);
00087   if(c == NULL) {
00088     PRINTF("chameleon-raw: input: channel %u not found\n",
00089            (hdr->channel[1] << 8) + hdr->channel[0]);
00090     return NULL;
00091   }
00092 
00093   hdrptr = packetbuf_dataptr();
00094   if(packetbuf_hdrreduce(c->hdrsize) == 0) {
00095     PRINTF("chameleon-raw: too short packet\n");
00096     return NULL;
00097   }
00098   byteptr = bitptr = 0;
00099   for(a = c->attrlist; a->type != PACKETBUF_ATTR_NONE; ++a) {
00100 #if CHAMELEON_WITH_MAC_LINK_ADDRESSES
00101     if(a->type == PACKETBUF_ADDR_SENDER ||
00102        a->type == PACKETBUF_ADDR_RECEIVER) {
00103       /* Let the link layer handle sender and receiver */
00104       continue;
00105     }
00106 #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */
00107     PRINTF("%d.%d: unpack_header type %s, len %d\n",
00108            rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00109            packetbuf_attr_strings[a->type], a->len);
00110     len = (a->len & 0xf8) + ((a->len & 7) ? 8: 0);
00111     if(PACKETBUF_IS_ADDR(a->type)) {
00112       const rimeaddr_t addr;
00113       memcpy((uint8_t *)&addr, &hdrptr[byteptr], len / 8);
00114       PRINTF("%d.%d: unpack_header type %s, addr %d.%d\n",
00115              rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00116              packetbuf_attr_strings[a->type],
00117              addr.u8[0], addr.u8[1]);
00118       packetbuf_set_addr(a->type, &addr);
00119     } else {
00120       packetbuf_attr_t val = 0;
00121       memcpy((uint8_t *)&val, &hdrptr[byteptr], len / 8);
00122 
00123       packetbuf_set_attr(a->type, val);
00124       PRINTF("%d.%d: unpack_header type %s, val %d\n",
00125              rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00126              packetbuf_attr_strings[a->type],
00127              val);
00128     }
00129     byteptr += len / 8;
00130   }
00131   return c;
00132 }
00133 /*---------------------------------------------------------------------------*/
00134 static int
00135 output(struct channel *c)
00136 {
00137   const struct packetbuf_attrlist *a;
00138   int byteptr, len;
00139   uint8_t *hdrptr;
00140   struct raw_hdr *hdr;
00141   
00142   /* Compute the total size of the final header by summing the size of
00143      all attributes that are used on this channel. */
00144   if(packetbuf_hdralloc(c->hdrsize + sizeof(struct raw_hdr)) == 0) {
00145     PRINTF("chameleon-raw: insufficient space for headers\n");
00146     return 0;
00147   }
00148   hdr = (struct raw_hdr *)packetbuf_hdrptr();
00149   hdr->channel[0] = c->channelno & 0xff;
00150   hdr->channel[1] = (c->channelno >> 8) & 0xff;
00151 
00152   hdrptr = ((uint8_t *)packetbuf_hdrptr()) + sizeof(struct raw_hdr);
00153   byteptr = 0;
00154   for(a = c->attrlist; a->type != PACKETBUF_ATTR_NONE; ++a) {
00155 #if CHAMELEON_WITH_MAC_LINK_ADDRESSES
00156     if(a->type == PACKETBUF_ADDR_SENDER ||
00157        a->type == PACKETBUF_ADDR_RECEIVER) {
00158       /* Let the link layer handle sender and receiver */
00159       PRINTF("%d.%d: pack_header leaving sender/receiver to link layer\n");
00160       continue;
00161     }
00162 #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */
00163     PRINTF("%d.%d: pack_header type %s, len %d\n",
00164            rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00165            packetbuf_attr_strings[a->type], a->len);
00166     len = (a->len & 0xf8) + ((a->len & 7) ? 8: 0);
00167     if(PACKETBUF_IS_ADDR(a->type)) {
00168       const rimeaddr_t *rimeaddr;
00169       /*      memcpy(&hdrptr[byteptr], (uint8_t *)packetbuf_attr_aget(a->type), len / 8);*/
00170       rimeaddr = packetbuf_addr(a->type);
00171       hdrptr[byteptr] = rimeaddr->u8[0];
00172       hdrptr[byteptr + 1] = rimeaddr->u8[1];
00173       
00174       PRINTF("%d.%d: address %d.%d\n",
00175             rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00176             ((uint8_t *)packetbuf_addr(a->type))[0],
00177             ((uint8_t *)packetbuf_addr(a->type))[1]);
00178     } else {
00179       packetbuf_attr_t val;
00180       val = packetbuf_attr(a->type);
00181       memcpy(&hdrptr[byteptr], &val, len / 8);
00182       PRINTF("%d.%d: value %d\n",
00183             rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00184             val);
00185     }
00186     byteptr += len / 8;
00187   }
00188 
00189   return 1; /* Send out packet */
00190 }
00191 /*---------------------------------------------------------------------------*/
00192 static int
00193 hdrsize(const struct packetbuf_attrlist *a)
00194 {
00195   int size, len;
00196   
00197   /* Compute the total size of the final header by summing the size of
00198      all attributes that are used on this channel. */
00199   
00200   size = 0;
00201   for(; a->type != PACKETBUF_ATTR_NONE; ++a) {
00202     /*    PRINTF("chameleon header_size: header type %s (%d) len %d\n",
00203            packetbuf_attr_strings[a->type],
00204            a->type,
00205            a->len);*/
00206 #if CHAMELEON_WITH_MAC_LINK_ADDRESSES
00207     if(a->type == PACKETBUF_ADDR_SENDER ||
00208        a->type == PACKETBUF_ADDR_RECEIVER) {
00209       /* Let the mac layer handle the sender and receiver */
00210       continue;
00211     }
00212 #endif /* CHAMELEON_WITH_MAC_LINK_ADDRESSES */
00213     len = a->len;
00214     if(len < 8) {
00215       len = 8;
00216     }
00217     size += len;
00218   }
00219   return size / 8;
00220 }
00221 /*---------------------------------------------------------------------------*/
00222 CC_CONST_FUNCTION struct chameleon_module chameleon_raw = { input, output,
00223                                                             hdrsize };

Generated on Mon Apr 11 14:23:30 2011 for Contiki 2.5 by  doxygen 1.6.1