50 #define STEADY_TIME CLOCK_SECOND * 2
52 #define DEFAULT_SEND_INTERVAL CLOCK_SECOND / 2
63 #define VERSION_LT(a, b) ((signed char)((a) - (b)) < 0)
68 #define PRINTF(...) printf(__VA_ARGS__)
75 read_new_datapacket(
struct rudolph0_conn *c)
79 if(c->cb->read_chunk) {
80 len = c->cb->read_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE,
81 c->current.data, RUDOLPH0_DATASIZE);
83 c->current.datalen = len;
85 PRINTF(
"read_new_datapacket len %d\n", len);
89 send_nack(
struct rudolph0_conn *c)
91 struct rudolph0_hdr *hdr;
96 hdr->type = TYPE_NACK;
97 hdr->version = c->current.h.version;
98 hdr->chunk = c->current.h.chunk;
100 PRINTF(
"Sending nack for %d:%d\n", hdr->version, hdr->chunk);
101 polite_send(&c->nackc, c->send_interval / 2,
sizeof(
struct rudolph0_hdr));
107 struct rudolph0_conn *c = (
struct rudolph0_conn *)stbroadcast;
109 if(c->current.datalen == RUDOLPH0_DATASIZE) {
110 c->current.h.chunk++;
111 PRINTF(
"Sending data chunk %d next time\n", c->current.h.chunk);
112 read_new_datapacket(c);
115 PRINTF(
"Steady: Sending the same data chunk next time datalen %d, %d\n",
116 c->current.datalen, RUDOLPH0_DATASIZE);
123 struct rudolph0_conn *c = (
struct rudolph0_conn *)stbroadcast;
126 if(p->h.type == TYPE_DATA) {
127 if(c->current.h.version != p->h.version) {
128 PRINTF(
"rudolph0 new version %d\n", p->h.version);
129 c->current.h.version = p->h.version;
130 c->current.h.chunk = 0;
131 c->cb->write_chunk(c, 0, RUDOLPH0_FLAG_NEWFILE, p->data, 0);
132 if(p->h.chunk != 0) {
135 c->cb->write_chunk(c, 0, RUDOLPH0_FLAG_NONE, p->data, p->datalen);
136 c->current.h.chunk++;
138 }
else if(p->h.version == c->current.h.version) {
139 if(p->h.chunk == c->current.h.chunk) {
140 PRINTF(
"received chunk %d\n", p->h.chunk);
141 if(p->datalen < RUDOLPH0_DATASIZE) {
142 c->cb->write_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE,
143 RUDOLPH0_FLAG_LASTCHUNK, p->data, p->datalen);
145 c->cb->write_chunk(c, c->current.h.chunk * RUDOLPH0_DATASIZE,
146 RUDOLPH0_FLAG_NONE, p->data, p->datalen);
148 c->current.h.chunk++;
150 }
else if(p->h.chunk > c->current.h.chunk) {
151 PRINTF(
"received chunk %d > %d, sending NACK\n", p->h.chunk, c->current.h.chunk);
163 struct rudolph0_conn *c = (
struct rudolph0_conn *)
164 ((
char *)polite - offsetof(
struct rudolph0_conn,
168 if(p->h.type == TYPE_NACK && c->state == STATE_SENDER) {
169 if(p->h.version == c->current.h.version) {
170 PRINTF(
"Reseting chunk to %d\n", p->h.chunk);
171 c->current.h.chunk = p->h.chunk;
173 PRINTF(
"Wrong version, reseting chunk to 0\n");
174 c->current.h.chunk = 0;
176 read_new_datapacket(c);
182 static const struct stbroadcast_callbacks stbroadcast = { recv, sent };
185 rudolph0_open(
struct rudolph0_conn *c, uint16_t channel,
186 const struct rudolph0_callbacks *cb)
191 c->current.h.version = 0;
192 c->state = STATE_RECEIVER;
193 c->send_interval = DEFAULT_SEND_INTERVAL;
197 rudolph0_close(
struct rudolph0_conn *c)
199 stbroadcast_close(&c->c);
204 rudolph0_send(
struct rudolph0_conn *c, clock_time_t send_interval)
206 c->state = STATE_SENDER;
207 c->current.h.version++;
208 c->current.h.version++;
209 c->current.h.chunk = 0;
210 c->current.h.type = TYPE_DATA;
211 read_new_datapacket(c);
213 c->send_interval = send_interval;
218 rudolph0_force_restart(
struct rudolph0_conn *c)
220 c->current.h.chunk = 0;
225 rudolph0_stop(
struct rudolph0_conn *c)
231 rudolph0_version(
struct rudolph0_conn *c)
233 return c->current.h.version;
237 rudolph0_set_version(
struct rudolph0_conn *c,
int version)
239 c->current.h.version = version;
int packetbuf_hdralloc(int size)
Extend the header of the packetbuf, for outbound packets.
int polite_send(struct polite_conn *c, clock_time_t interval, uint8_t hdrsize)
Send a packet on a polite connection.
Header file for the single-hop reliable bulk data transfer module
Header file for the Rime stack
void polite_open(struct polite_conn *c, uint16_t channel, const struct polite_callbacks *cb)
Open a polite connection.
void stbroadcast_cancel(struct stbroadcast_conn *c)
Cancel the current stubborn message.
void * packetbuf_hdrptr(void)
Get a pointer to the header in the packetbuf, for outbound packets.
An opaque structure with no user-visible elements that holds the state of a polite connection...
void stbroadcast_open(struct stbroadcast_conn *c, uint16_t channel, const struct stbroadcast_callbacks *u)
Set up a stbroadcast connection.
void stbroadcast_set_timer(struct stbroadcast_conn *c, clock_time_t t)
Set the retransmission time of the current stubborn message.
void packetbuf_clear(void)
Clear and reset the packetbuf.
void polite_close(struct polite_conn *c)
Close a polite connection.
void packetbuf_reference(void *ptr, uint16_t len)
Point the packetbuf to external data.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
A structure with callback functions for a polite connection.
A stbroadcast connection.
int stbroadcast_send_stubborn(struct stbroadcast_conn *c, clock_time_t t)
Send a stubborn message.