Contiki 2.6

rmh.c

Go to the documentation of this file.
00001 /**
00002  * \addtogroup rimermh
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: rmh.c,v 1.10 2009/11/08 19:40:17 adamdunkels Exp $
00037  */
00038 
00039 /**
00040  * \file
00041  *         Multihop forwarding
00042  * \author
00043  *         Adam Dunkels <adam@sics.se>
00044  */
00045 
00046 #include "contiki.h"
00047 #include "net/rime.h"
00048 #include "net/rime/rmh.h"
00049 
00050 struct data_hdr {
00051   rimeaddr_t dest;
00052   rimeaddr_t originator;
00053   uint8_t hops;
00054   uint8_t max_rexmits;
00055 };
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 /*---------------------------------------------------------------------------*/
00066 static void
00067 received(struct runicast_conn *uc, const rimeaddr_t *from, uint8_t seqno)
00068 {
00069   struct rmh_conn *c = (struct rmh_conn *)uc;
00070   struct data_hdr *msg = packetbuf_dataptr();
00071   rimeaddr_t *nexthop;
00072 
00073   PRINTF("data_packet_received from %d.%d towards %d.%d len %d\n", 
00074          from->u8[0], from->u8[1],
00075          msg->dest.u8[0], msg->dest.u8[1],
00076          packetbuf_datalen());
00077 
00078   if(rimeaddr_cmp(&msg->dest, &rimeaddr_node_addr)) {
00079     PRINTF("for us!\n");
00080     packetbuf_hdrreduce(sizeof(struct data_hdr));
00081     if(c->cb->recv) {
00082       c->cb->recv(c, &msg->originator, msg->hops);
00083     }
00084   } else {
00085     nexthop = NULL;
00086     if(c->cb->forward) {
00087       nexthop = c->cb->forward(c, &msg->originator,
00088                                &msg->dest, from, msg->hops);
00089     }
00090     if(nexthop) {
00091       PRINTF("forwarding to %d.%d\n", nexthop->u8[0], nexthop->u8[1]);
00092       msg->hops++;
00093       runicast_send(&c->c, nexthop, c->num_rexmit);
00094     }
00095   }
00096 }
00097 /*---------------------------------------------------------------------------*/
00098 static void
00099 sent(struct runicast_conn *c, const rimeaddr_t *to, uint8_t retransmissions)
00100 {
00101 
00102 }
00103 /*---------------------------------------------------------------------------*/
00104 static void
00105 timedout(struct runicast_conn *c, const rimeaddr_t *to, uint8_t retransmissions)
00106 {
00107 
00108 }
00109 /*---------------------------------------------------------------------------*/
00110 static const struct runicast_callbacks data_callbacks = { received ,
00111                                                      sent,
00112                                                      timedout};
00113 /*---------------------------------------------------------------------------*/
00114 void
00115 rmh_open(struct rmh_conn *c, uint16_t channel,
00116         const struct rmh_callbacks *callbacks)
00117 {
00118   runicast_open(&c->c, channel, &data_callbacks);
00119   c->cb = callbacks;
00120 }
00121 /*---------------------------------------------------------------------------*/
00122 void
00123 rmh_close(struct rmh_conn *c)
00124 {
00125   runicast_close(&c->c);
00126 }
00127 /*---------------------------------------------------------------------------*/
00128 int
00129 rmh_send(struct rmh_conn *c, rimeaddr_t *to, uint8_t num_rexmit, uint8_t max_hops)
00130 {
00131   rimeaddr_t *nexthop;
00132   struct data_hdr *hdr;
00133   
00134   c->num_rexmit = num_rexmit;
00135   
00136   if(c->cb->forward == NULL) {
00137     return 0;
00138   }
00139   
00140   nexthop = c->cb->forward(c, &rimeaddr_node_addr, to, NULL, 0);
00141   if(nexthop == NULL) {
00142     PRINTF("rmh_send: no route\n");
00143     return 0;
00144   } else {
00145     PRINTF("rmh_send: sending data\n");
00146 
00147     
00148     if(packetbuf_hdralloc(sizeof(struct data_hdr))) {
00149       hdr = packetbuf_hdrptr();
00150       rimeaddr_copy(&hdr->dest, to);
00151       rimeaddr_copy(&hdr->originator, &rimeaddr_node_addr);
00152       hdr->hops = 1;
00153       hdr->max_rexmits = num_rexmit;
00154       runicast_send(&c->c, nexthop, num_rexmit);
00155     }
00156     return 1;
00157   }
00158 }
00159 /*---------------------------------------------------------------------------*/
00160 /** @} */