netflood.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "net/rime/netflood.h"
00047
00048 #include <string.h>
00049
00050 #define HOPS_MAX 16
00051
00052 struct netflood_hdr {
00053 uint16_t originator_seqno;
00054 rimeaddr_t originator;
00055 uint16_t hops;
00056 };
00057
00058 #define DEBUG 0
00059 #if DEBUG
00060 #include <stdio.h>
00061 #define PRINTF(...) printf(__VA_ARGS__)
00062 #else
00063 #define PRINTF(...)
00064 #endif
00065
00066
00067 static int
00068 send(struct netflood_conn *c)
00069 {
00070 PRINTF("%d.%d: netflood send to ipolite\n",
00071 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00072 return ipolite_send(&c->c, c->queue_time, 4);
00073 }
00074
00075 static void
00076 recv_from_ipolite(struct ipolite_conn *ipolite, const rimeaddr_t *from)
00077 {
00078 struct netflood_conn *c = (struct netflood_conn *)ipolite;
00079 struct netflood_hdr hdr;
00080 uint8_t hops;
00081 struct queuebuf *queuebuf;
00082
00083 memcpy(&hdr, packetbuf_dataptr(), sizeof(struct netflood_hdr));
00084 hops = hdr.hops;
00085
00086
00087 queuebuf = queuebuf_new_from_packetbuf();
00088
00089 packetbuf_hdrreduce(sizeof(struct netflood_hdr));
00090 if(c->u->recv != NULL) {
00091 if(!(rimeaddr_cmp(&hdr.originator, &c->last_originator) &&
00092 hdr.originator_seqno <= c->last_originator_seqno)) {
00093
00094 if(c->u->recv(c, from, &hdr.originator, hdr.originator_seqno,
00095 hops)) {
00096
00097 if(queuebuf != NULL) {
00098 queuebuf_to_packetbuf(queuebuf);
00099 queuebuf_free(queuebuf);
00100 queuebuf = NULL;
00101 memcpy(&hdr, packetbuf_dataptr(), sizeof(struct netflood_hdr));
00102
00103
00104 if(hops < HOPS_MAX) {
00105 PRINTF("%d.%d: netflood rebroadcasting %d.%d/%d (%d.%d/%d) hops %d\n",
00106 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00107 hdr.originator.u8[0], hdr.originator.u8[1],
00108 hdr.originator_seqno,
00109 c->last_originator.u8[0], c->last_originator.u8[1],
00110 c->last_originator_seqno,
00111 hops);
00112 hdr.hops++;
00113 memcpy(packetbuf_dataptr(), &hdr, sizeof(struct netflood_hdr));
00114 send(c);
00115 rimeaddr_copy(&c->last_originator, &hdr.originator);
00116 c->last_originator_seqno = hdr.originator_seqno;
00117 }
00118 }
00119 }
00120 }
00121 }
00122 if(queuebuf != NULL) {
00123 queuebuf_free(queuebuf);
00124 }
00125 }
00126
00127 static void
00128 sent(struct ipolite_conn *ipolite)
00129 {
00130 struct netflood_conn *c = (struct netflood_conn *)ipolite;
00131 if(c->u->sent != NULL) {
00132 c->u->sent(c);
00133 }
00134 }
00135
00136 static void
00137 dropped(struct ipolite_conn *ipolite)
00138 {
00139 struct netflood_conn *c = (struct netflood_conn *)ipolite;
00140 if(c->u->dropped != NULL) {
00141 c->u->dropped(c);
00142 }
00143 }
00144
00145 static const struct ipolite_callbacks netflood = {recv_from_ipolite, sent, dropped};
00146
00147 void
00148 netflood_open(struct netflood_conn *c, clock_time_t queue_time,
00149 uint16_t channel, const struct netflood_callbacks *u)
00150 {
00151 ipolite_open(&c->c, channel, 1, &netflood);
00152 c->u = u;
00153 c->queue_time = queue_time;
00154 }
00155
00156 void
00157 netflood_close(struct netflood_conn *c)
00158 {
00159 ipolite_close(&c->c);
00160 }
00161
00162 int
00163 netflood_send(struct netflood_conn *c, uint8_t seqno)
00164 {
00165 if(packetbuf_hdralloc(sizeof(struct netflood_hdr))) {
00166 struct netflood_hdr *hdr = packetbuf_hdrptr();
00167 rimeaddr_copy(&hdr->originator, &rimeaddr_node_addr);
00168 rimeaddr_copy(&c->last_originator, &hdr->originator);
00169 c->last_originator_seqno = hdr->originator_seqno = seqno;
00170 hdr->hops = 0;
00171 PRINTF("%d.%d: netflood sending '%s'\n",
00172 rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
00173 (char *)packetbuf_dataptr());
00174 return ipolite_send(&c->c, 0, 4);
00175 }
00176 return 0;
00177 }
00178
00179 void
00180 netflood_cancel(struct netflood_conn *c)
00181 {
00182 ipolite_cancel(&c->c);
00183 }
00184
00185