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 <stddef.h>
00047
00048 #include "net/rime.h"
00049 #include "net/rime/rudolph0.h"
00050
00051 #define STEADY_TIME CLOCK_SECOND * 2
00052
00053 #define DEFAULT_SEND_INTERVAL CLOCK_SECOND / 2
00054 enum {
00055 TYPE_DATA,
00056 TYPE_NACK,
00057 };
00058
00059 enum {
00060 STATE_RECEIVER,
00061 STATE_SENDER,
00062 };
00063
00064 #define VERSION_LT(a, b) ((signed char)((a) - (b)) < 0)
00065
00066 #define DEBUG 0
00067 #if DEBUG
00068 #include <stdio.h>
00069 #define PRINTF(...) printf(__VA_ARGS__)
00070 #else
00071 #define PRINTF(...)
00072 #endif
00073
00074
00075 static void
00076 read_new_datapacket(struct rudolph0_conn *c)
00077 {
00078 int len = 0;
00079
00080 if(c->cb->read_chunk) {
00081 len = c->cb->read_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE,
00082 c->current.data, RUDOLPH0_DATASIZE);
00083 }
00084 c->current.datalen = len;
00085
00086 PRINTF("read_new_datapacket len %d\n", len);
00087 }
00088
00089 static void
00090 send_nack(struct rudolph0_conn *c)
00091 {
00092 struct rudolph0_hdr *hdr;
00093 packetbuf_clear();
00094 packetbuf_hdralloc(sizeof(struct rudolph0_hdr));
00095 hdr = packetbuf_hdrptr();
00096
00097 hdr->type = TYPE_NACK;
00098 hdr->version = c->current.h.version;
00099 hdr->chunk = c->current.h.chunk;
00100
00101 PRINTF("Sending nack for %d:%d\n", hdr->version, hdr->chunk);
00102 polite_send(&c->nackc, c->send_interval / 2, sizeof(struct rudolph0_hdr));
00103 }
00104
00105 static void
00106 sent(struct stbroadcast_conn *stbroadcast)
00107 {
00108 struct rudolph0_conn *c = (struct rudolph0_conn *)stbroadcast;
00109
00110 if(c->current.datalen == RUDOLPH0_DATASIZE) {
00111 c->current.h.chunk++;
00112 PRINTF("Sending data chunk %d next time\n", c->current.h.chunk);
00113 read_new_datapacket(c);
00114 } else {
00115 stbroadcast_set_timer(&c->c, STEADY_TIME);
00116 PRINTF("Steady: Sending the same data chunk next time datalen %d, %d\n",
00117 c->current.datalen, RUDOLPH0_DATASIZE);
00118 }
00119 }
00120
00121 static void
00122 recv(struct stbroadcast_conn *stbroadcast)
00123 {
00124 struct rudolph0_conn *c = (struct rudolph0_conn *)stbroadcast;
00125 struct rudolph0_datapacket *p = packetbuf_dataptr();
00126
00127 if(p->h.type == TYPE_DATA) {
00128 if(c->current.h.version != p->h.version) {
00129 PRINTF("rudolph0 new version %d\n", p->h.version);
00130 c->current.h.version = p->h.version;
00131 c->current.h.chunk = 0;
00132 c->cb->write_chunk(c, 0, RUDOLPH0_FLAG_NEWFILE, p->data, 0);
00133 if(p->h.chunk != 0) {
00134 send_nack(c);
00135 } else {
00136 c->cb->write_chunk(c, 0, RUDOLPH0_FLAG_NONE, p->data, p->datalen);
00137 c->current.h.chunk++;
00138 }
00139 } else if(p->h.version == c->current.h.version) {
00140 if(p->h.chunk == c->current.h.chunk) {
00141 PRINTF("received chunk %d\n", p->h.chunk);
00142 if(p->datalen < RUDOLPH0_DATASIZE) {
00143 c->cb->write_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE,
00144 RUDOLPH0_FLAG_LASTCHUNK, p->data, p->datalen);
00145 } else {
00146 c->cb->write_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE,
00147 RUDOLPH0_FLAG_NONE, p->data, p->datalen);
00148 }
00149 c->current.h.chunk++;
00150
00151 } else if(p->h.chunk > c->current.h.chunk) {
00152 PRINTF("received chunk %d > %d, sending NACK\n", p->h.chunk, c->current.h.chunk);
00153 send_nack(c);
00154 }
00155 } else {
00156
00157 }
00158 }
00159 }
00160
00161 static void
00162 recv_nack(struct polite_conn *polite)
00163 {
00164 struct rudolph0_conn *c = (struct rudolph0_conn *)
00165 ((char *)polite - offsetof(struct rudolph0_conn,
00166 nackc));
00167 struct rudolph0_datapacket *p = packetbuf_dataptr();
00168
00169 if(p->h.type == TYPE_NACK && c->state == STATE_SENDER) {
00170 if(p->h.version == c->current.h.version) {
00171 PRINTF("Reseting chunk to %d\n", p->h.chunk);
00172 c->current.h.chunk = p->h.chunk;
00173 } else {
00174 PRINTF("Wrong version, reseting chunk to 0\n");
00175 c->current.h.chunk = 0;
00176 }
00177 read_new_datapacket(c);
00178 stbroadcast_set_timer(&c->c, c->send_interval);
00179 }
00180 }
00181
00182 static const struct polite_callbacks polite = { recv_nack, 0, 0 };
00183 static const struct stbroadcast_callbacks stbroadcast = { recv, sent };
00184
00185 void
00186 rudolph0_open(struct rudolph0_conn *c, uint16_t channel,
00187 const struct rudolph0_callbacks *cb)
00188 {
00189 stbroadcast_open(&c->c, channel, &stbroadcast);
00190 polite_open(&c->nackc, channel + 1, &polite);
00191 c->cb = cb;
00192 c->current.h.version = 0;
00193 c->state = STATE_RECEIVER;
00194 c->send_interval = DEFAULT_SEND_INTERVAL;
00195 }
00196
00197 void
00198 rudolph0_close(struct rudolph0_conn *c)
00199 {
00200 stbroadcast_close(&c->c);
00201 polite_close(&c->nackc);
00202 }
00203
00204 void
00205 rudolph0_send(struct rudolph0_conn *c, clock_time_t send_interval)
00206 {
00207 c->state = STATE_SENDER;
00208 c->current.h.version++;
00209 c->current.h.version++;
00210 c->current.h.chunk = 0;
00211 c->current.h.type = TYPE_DATA;
00212 read_new_datapacket(c);
00213 packetbuf_reference(&c->current, sizeof(struct rudolph0_datapacket));
00214 c->send_interval = send_interval;
00215 stbroadcast_send_stubborn(&c->c, c->send_interval);
00216 }
00217
00218 void
00219 rudolph0_force_restart(struct rudolph0_conn *c)
00220 {
00221 c->current.h.chunk = 0;
00222 send_nack(c);
00223 }
00224
00225 void
00226 rudolph0_stop(struct rudolph0_conn *c)
00227 {
00228 stbroadcast_cancel(&c->c);
00229 }
00230
00231 int
00232 rudolph0_version(struct rudolph0_conn *c)
00233 {
00234 return c->current.h.version;
00235 }
00236
00237 void
00238 rudolph0_set_version(struct rudolph0_conn *c, int version)
00239 {
00240 c->current.h.version = version;
00241 }
00242
00243