ipolite.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.h"
00047 #include "net/rime/ipolite.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
00055
00056 #ifndef MIN
00057 #define MIN(a, b) ((a) < (b)? (a) : (b))
00058 #endif
00059
00060 #define DEBUG 0
00061 #if DEBUG
00062 #include <stdio.h>
00063 #define PRINTF(...) printf(__VA_ARGS__)
00064 #else
00065 #define PRINTF(...)
00066 #endif
00067
00068
00069 static void
00070 recv(struct broadcast_conn *broadcast, const rimeaddr_t *from)
00071 {
00072 struct ipolite_conn *c = (struct ipolite_conn *)broadcast;
00073 if(c->q != NULL &&
00074 packetbuf_datalen() == queuebuf_datalen(c->q) &&
00075 memcmp(packetbuf_dataptr(), queuebuf_dataptr(c->q),
00076 MIN(c->hdrsize, packetbuf_datalen())) == 0) {
00077
00078
00079
00080 c->dups++;
00081 if(c->dups == c->maxdups) {
00082 queuebuf_free(c->q);
00083 c->q = NULL;
00084 ctimer_stop(&c->t);
00085 if(c->cb->dropped) {
00086 c->cb->dropped(c);
00087 }
00088 }
00089 }
00090 if(c->cb->recv) {
00091 c->cb->recv(c, from);
00092 }
00093 }
00094
00095 static void
00096 sent(struct broadcast_conn *bc, int status, int num_tx)
00097 {
00098
00099 }
00100
00101 static void
00102 send(void *ptr)
00103 {
00104 struct ipolite_conn *c = ptr;
00105
00106 PRINTF("%d.%d: ipolite: send queuebuf %p\n",
00107 rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1],
00108 c->q);
00109
00110 if(c->q != NULL) {
00111 queuebuf_to_packetbuf(c->q);
00112 queuebuf_free(c->q);
00113 c->q = NULL;
00114 broadcast_send(&c->c);
00115 if(c->cb->sent) {
00116 c->cb->sent(c);
00117 }
00118 }
00119 }
00120
00121 static const struct broadcast_callbacks broadcast = { recv, sent };
00122
00123 void
00124 ipolite_open(struct ipolite_conn *c, uint16_t channel, uint8_t dups,
00125 const struct ipolite_callbacks *cb)
00126 {
00127 broadcast_open(&c->c, channel, &broadcast);
00128 c->cb = cb;
00129 c->maxdups = dups;
00130 PRINTF("ipolite open channel %d\n", channel);
00131 }
00132
00133 void
00134 ipolite_close(struct ipolite_conn *c)
00135 {
00136 broadcast_close(&c->c);
00137 ctimer_stop(&c->t);
00138 if(c->q != NULL) {
00139 queuebuf_free(c->q);
00140 c->q = NULL;
00141 }
00142 }
00143
00144 int
00145 ipolite_send(struct ipolite_conn *c, clock_time_t interval, uint8_t hdrsize)
00146 {
00147 if(c->q != NULL) {
00148
00149 PRINTF("%d.%d: ipolite_send: cancel old send\n",
00150 rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
00151 queuebuf_free(c->q);
00152 }
00153 c->dups = 0;
00154 c->hdrsize = hdrsize;
00155 if(interval == 0) {
00156 PRINTF("%d.%d: ipolite_send: interval 0\n",
00157 rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
00158 if(broadcast_send(&c->c)) {
00159 if(c->cb->sent) {
00160 c->cb->sent(c);
00161 }
00162 return 1;
00163 }
00164
00165 } else {
00166 c->q = queuebuf_new_from_packetbuf();
00167 if(c->q != NULL) {
00168 ctimer_set(&c->t,
00169 interval / 2 + (random_rand() % (interval / 2)),
00170 send, c);
00171 return 1;
00172 }
00173 PRINTF("%d.%d: ipolite_send: could not allocate queue buffer\n",
00174 rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
00175 }
00176 return 0;
00177 }
00178
00179 void
00180 ipolite_cancel(struct ipolite_conn *c)
00181 {
00182 ctimer_stop(&c->t);
00183 if(c->q != NULL) {
00184 queuebuf_free(c->q);
00185 c->q = NULL;
00186 }
00187 }
00188
00189