Contiki 2.6

polite.c

Go to the documentation of this file.
00001 /**
00002  * \addtogroup rimepolite
00003  * @{
00004  */
00005 
00006 /*
00007  * Copyright (c) 2007, 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: polite.c,v 1.10 2010/02/23 18:38:05 adamdunkels Exp $
00037  */
00038 
00039 /**
00040  * \file
00041  *         Polite Anonymous best effort local area BroadCast (polite)
00042  * \author
00043  *         Adam Dunkels <adam@sics.se>
00044  */
00045 
00046 #include "net/rime.h"
00047 #include "net/rime/polite.h"
00048 #include "lib/random.h"
00049 
00050 #include <string.h>
00051 
00052 #ifndef MAX
00053 #define MAX(a,b) ((a) > (b)? (a) : (b))
00054 #endif /* MAX */
00055 
00056 #ifndef MIN
00057 #define MIN(a, b) ((a) < (b)? (a) : (b))
00058 #endif /* MIN */
00059 
00060 
00061 /*---------------------------------------------------------------------------*/
00062 static void
00063 recv(struct abc_conn *abc)
00064 {
00065   struct polite_conn *c = (struct polite_conn *)abc;
00066   if(c->q != NULL &&
00067      packetbuf_datalen() == queuebuf_datalen(c->q) &&
00068      memcmp(packetbuf_dataptr(), queuebuf_dataptr(c->q),
00069             MIN(c->hdrsize, packetbuf_datalen())) == 0) {
00070     /* We received a copy of our own packet, so we do not send out
00071        packet. */
00072     queuebuf_free(c->q);
00073     c->q = NULL;
00074     ctimer_stop(&c->t);
00075     if(c->cb->dropped) {
00076       c->cb->dropped(c);
00077     }
00078   }
00079   if(c->cb->recv) {
00080     c->cb->recv(c);
00081   }
00082 }
00083 /*---------------------------------------------------------------------------*/
00084 static void
00085 sent(struct abc_conn *c, int status, int num_tx)
00086 {
00087 
00088 }
00089 /*---------------------------------------------------------------------------*/
00090 static void
00091 send(void *ptr)
00092 {
00093   struct polite_conn *c = ptr;
00094 
00095   if(c->q != NULL) {
00096     queuebuf_to_packetbuf(c->q);
00097     queuebuf_free(c->q);
00098     c->q = NULL;
00099     abc_send(&c->c);
00100     if(c->cb->sent) {
00101         c->cb->sent(c);
00102     }
00103   }
00104 }
00105 /*---------------------------------------------------------------------------*/
00106 static const struct abc_callbacks abc = { recv, sent };
00107 /*---------------------------------------------------------------------------*/
00108 void
00109 polite_open(struct polite_conn *c, uint16_t channel,
00110           const struct polite_callbacks *cb)
00111 {
00112   abc_open(&c->c, channel, &abc);
00113   c->cb = cb;
00114 }
00115 /*---------------------------------------------------------------------------*/
00116 void
00117 polite_close(struct polite_conn *c)
00118 {
00119   abc_close(&c->c);
00120   ctimer_stop(&c->t);
00121   if(c->q != NULL) {
00122     queuebuf_free(c->q);
00123     c->q = NULL;
00124   }
00125 }
00126 /*---------------------------------------------------------------------------*/
00127 int
00128 polite_send(struct polite_conn *c, clock_time_t interval, uint8_t hdrsize)
00129 {
00130   if(c->q != NULL) {
00131     /* If we are already about to send a packet, we cancel the old one. */
00132     queuebuf_free(c->q);
00133   }
00134   c->hdrsize = hdrsize;
00135   c->q = queuebuf_new_from_packetbuf();
00136   if(c->q != NULL) {
00137     ctimer_set(&c->t, interval / 2 + (random_rand() % (interval / 2)), send, c);
00138     return 1;
00139   }
00140   return 0;
00141 }
00142 /*---------------------------------------------------------------------------*/
00143 void
00144 polite_cancel(struct polite_conn *c)
00145 {
00146   ctimer_stop(&c->t);
00147   if(c->q != NULL) {
00148     queuebuf_free(c->q);
00149     c->q = NULL;
00150   }
00151 }
00152 /*---------------------------------------------------------------------------*/
00153 /** @} */