Contiki 2.6

rime.c

Go to the documentation of this file.
00001 /**
00002  * \addtogroup rime
00003  * @{
00004  */
00005 
00006 /*
00007  * Copyright (c) 2006, Swedish Institute of Computer Science.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions
00012  * are met:
00013  * 1. Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  * 3. Neither the name of the Institute nor the names of its contributors
00019  *    may be used to endorse or promote products derived from this software
00020  *    without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00032  * SUCH DAMAGE.
00033  *
00034  * This file is part of the Contiki operating system.
00035  *
00036  * $Id: rime.c,v 1.31 2010/10/03 20:10:22 adamdunkels Exp $
00037  */
00038 
00039 /**
00040  * \file
00041  *         Rime initialization and common code
00042  * \author
00043  *         Adam Dunkels <adam@sics.se>
00044  */
00045 
00046 #define DEBUG 0
00047 #if DEBUG
00048 #include <stdio.h>
00049 #define PRINTF(...) printf(__VA_ARGS__)
00050 #else
00051 #define PRINTF(...)
00052 #endif
00053 
00054 #include "net/netstack.h"
00055 #include "net/rime.h"
00056 #include "net/rime/chameleon.h"
00057 #include "net/rime/route.h"
00058 #include "net/rime/announcement.h"
00059 #include "net/rime/broadcast-announcement.h"
00060 #include "net/mac/mac.h"
00061 
00062 #include "lib/list.h"
00063 
00064 #ifdef RIME_CONF_BROADCAST_ANNOUNCEMENT_CHANNEL
00065 #define BROADCAST_ANNOUNCEMENT_CHANNEL RIME_CONF_BROADCAST_ANNOUNCEMENT_CHANNEL
00066 #else /* RIME_CONF_BROADCAST_ANNOUNCEMENT_CHANNEL */
00067 #define BROADCAST_ANNOUNCEMENT_CHANNEL 2
00068 #endif /* RIME_CONF_BROADCAST_ANNOUNCEMENT_CHANNEL */
00069 
00070 #ifdef RIME_CONF_BROADCAST_ANNOUNCEMENT_BUMP_TIME
00071 #define BROADCAST_ANNOUNCEMENT_BUMP_TIME RIME_CONF_BROADCAST_ANNOUNCEMENT_BUMP_TIME
00072 #else /* RIME_CONF_BROADCAST_ANNOUNCEMENT_BUMP_TIME */
00073 #define BROADCAST_ANNOUNCEMENT_BUMP_TIME CLOCK_SECOND * 32 / NETSTACK_RDC_CHANNEL_CHECK_RATE
00074 #endif /* RIME_CONF_BROADCAST_ANNOUNCEMENT_BUMP_TIME */
00075 
00076 #ifdef RIME_CONF_BROADCAST_ANNOUNCEMENT_MIN_TIME
00077 #define BROADCAST_ANNOUNCEMENT_MIN_TIME RIME_CONF_BROADCAST_ANNOUNCEMENT_MIN_TIME
00078 #else /* RIME_CONF_BROADCAST_ANNOUNCEMENT_MIN_TIME */
00079 #define BROADCAST_ANNOUNCEMENT_MIN_TIME CLOCK_SECOND * 60
00080 #endif /* RIME_CONF_BROADCAST_ANNOUNCEMENT_MIN_TIME */
00081 
00082 #ifdef RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME
00083 #define BROADCAST_ANNOUNCEMENT_MAX_TIME RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME
00084 #else /* RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME */
00085 #define BROADCAST_ANNOUNCEMENT_MAX_TIME CLOCK_SECOND * 3600UL
00086 #endif /* RIME_CONF_BROADCAST_ANNOUNCEMENT_MAX_TIME */
00087 
00088 
00089 LIST(sniffers);
00090 
00091 /*---------------------------------------------------------------------------*/
00092 void
00093 rime_sniffer_add(struct rime_sniffer *s)
00094 {
00095   list_add(sniffers, s);
00096 }
00097 /*---------------------------------------------------------------------------*/
00098 void
00099 rime_sniffer_remove(struct rime_sniffer *s)
00100 {
00101   list_remove(sniffers, s);
00102 }
00103 /*---------------------------------------------------------------------------*/
00104 static void
00105 input(void)
00106 {
00107   struct rime_sniffer *s;
00108   struct channel *c;
00109 
00110   RIMESTATS_ADD(rx);
00111   c = chameleon_parse();
00112   
00113   for(s = list_head(sniffers); s != NULL; s = list_item_next(s)) {
00114     if(s->input_callback != NULL) {
00115       s->input_callback();
00116     }
00117   }
00118   
00119   if(c != NULL) {
00120     abc_input(c);
00121   }
00122 }
00123 /*---------------------------------------------------------------------------*/
00124 static void
00125 init(void)
00126 {
00127   queuebuf_init();
00128   packetbuf_clear();
00129   announcement_init();
00130 
00131   chameleon_init();
00132   
00133   /* XXX This is initializes the transmission of announcements but it
00134    * is not currently certain where this initialization is supposed to
00135    * be. Also, the times are arbitrarily set for now. They should
00136    * either be configurable, or derived from some MAC layer property
00137    * (duty cycle, sleep time, or something similar). But this is OK
00138    * for now, and should at least get us started with experimenting
00139    * with announcements.
00140    */
00141   broadcast_announcement_init(BROADCAST_ANNOUNCEMENT_CHANNEL,
00142                               BROADCAST_ANNOUNCEMENT_BUMP_TIME,
00143                               BROADCAST_ANNOUNCEMENT_MIN_TIME,
00144                               BROADCAST_ANNOUNCEMENT_MAX_TIME);
00145 }
00146 /*---------------------------------------------------------------------------*/
00147 static void
00148 packet_sent(void *ptr, int status, int num_tx)
00149 {
00150   struct channel *c = ptr;
00151   struct rime_sniffer *s;
00152   
00153   switch(status) {
00154   case MAC_TX_COLLISION:
00155     PRINTF("rime: collision after %d tx\n", num_tx);
00156     break; 
00157   case MAC_TX_NOACK:
00158     PRINTF("rime: noack after %d tx\n", num_tx);
00159     break;
00160   case MAC_TX_OK:
00161     PRINTF("rime: sent after %d tx\n", num_tx);
00162     break;
00163   default:
00164     PRINTF("rime: error %d after %d tx\n", status, num_tx);
00165   }
00166 
00167   /* Call sniffers, pass along the MAC status code. */
00168   for(s = list_head(sniffers); s != NULL; s = list_item_next(s)) {
00169     if(s->output_callback != NULL) {
00170       s->output_callback(status);
00171     }
00172   }
00173 
00174   abc_sent(c, status, num_tx);
00175 }
00176 /*---------------------------------------------------------------------------*/
00177 int
00178 rime_output(struct channel *c)
00179 {
00180   RIMESTATS_ADD(tx);
00181   if(chameleon_create(c)) {
00182     packetbuf_compact();
00183 
00184     NETSTACK_MAC.send(packet_sent, c);
00185     return 1;
00186   }
00187   return 0;
00188 }
00189 /*---------------------------------------------------------------------------*/
00190 const struct network_driver rime_driver = {
00191   "Rime",
00192   init,
00193   input
00194 };
00195 /** @} */