Revision 1604
wireless: software retransmit done. serial functions moved to xbee.c
wireless_send.c | ||
---|---|---|
40 | 40 |
|
41 | 41 |
/** |
42 | 42 |
* Definition for wireless library send packet structure |
43 |
* byte 1: length of packet |
|
43 |
* byte 1: length of packet (from frame number to end of data)
|
|
44 | 44 |
* byte 2: frame number |
45 |
* byte 3: group code |
|
46 |
* bytes 4-n: data |
|
47 |
* (byte n+1: num retries - only saved locally in sending buffer) |
|
45 |
* bytes 3-n: data (dest, options, frame number, group code, packet) |
|
46 |
* byte n+1: num retries |
|
48 | 47 |
* |
49 | 48 |
* Definition for ack buffer |
50 | 49 |
* 2 bit system: 0=still sending |
... | ... | |
60 | 59 |
uint8_t send_buf[PACKET_BUFFER_SIZE]; // sending buffer for retries |
61 | 60 |
uint8_t send_buf_first = 0; // first byte of data on buffer |
62 | 61 |
uint8_t send_buf_last = 0; // next free byte on buffer |
62 |
uint8_t send_buf_num_packets = 0; // number of packets in sending buffer |
|
63 | 63 |
|
64 | 64 |
/* private function prototypes */ |
65 | 65 |
void setack(uint8_t num,uint8_t val); |
66 |
void ackhandle(uint8_t num,uint8_t val); |
|
67 |
int8_t send_buf_add(uint8_t *ptr, uint8_t byte) |
|
68 |
uint8_t send_buf_get(uint8_t *ptr); |
|
66 | 69 |
|
67 |
|
|
68 | 70 |
// the send functions |
69 | 71 |
|
70 | 72 |
/** |
... | ... | |
86 | 88 |
* @return positive packet number for tracking acks, or error code (TBD) |
87 | 89 |
**/ |
88 | 90 |
int16_t wl_send(uint8_t *data, uint8_t length, uint8_t group, uint8_t scope, uint16_t dest, uint8_t mode) { |
89 |
uint8_t packet[length+2]; |
|
90 |
uint8_t options = XBEE_OPTIONS_NONE; |
|
91 |
int16_t ret_val = (int16_t)nextframe; |
|
91 |
uint8_t packet[6]; |
|
92 | 92 |
|
93 |
// build packet |
|
93 |
// build packet header
|
|
94 | 94 |
packet[0] = nextframe; |
95 |
packet[1] = group; |
|
96 |
memcpy(packet+2,data,length); |
|
95 |
packet[1] = (dest&0xFF00)>>8; |
|
96 |
packet[2] = dest&0x00FF; |
|
97 |
packet[3] = XBEE_OPTIONS_NONE; |
|
98 |
packet[4] = nextframe; |
|
99 |
packet[5] = group; |
|
97 | 100 |
|
98 | 101 |
// set scope |
99 | 102 |
if (scope == GLOBAL) |
100 |
options &= XBEE_OPTIONS_BROADCAST_ALL_PANS; |
|
103 |
packet[3] &= XBEE_OPTIONS_BROADCAST_ALL_PANS; |
|
104 |
else if (scope != PAN) { |
|
105 |
WL_DEBUG_PRINT("Error - bad scope in core send function\r\n"); |
|
106 |
return WL_ERROR_SCOPE; |
|
107 |
} |
|
101 | 108 |
|
102 | 109 |
// set mode |
103 | 110 |
if (mode == FAST) { |
104 |
options &= XBEE_OPTIONS_DISABLE_RESPONSE; |
|
105 |
ret_val = 0; |
|
111 |
packet[3] &= XBEE_OPTIONS_DISABLE_RESPONSE; |
|
106 | 112 |
} else if (mode != RELIABLE) { |
107 | 113 |
WL_DEBUG_PRINT("Error - bad mode in core send function\r\n"); |
108 | 114 |
return WL_ERROR_MODE; |
109 | 115 |
} |
116 |
|
|
117 |
// do checksum |
|
118 |
group = XBEE_FRAME_TX_REQUEST_16; |
|
119 |
xbee_checksum_add(packet,6,&group); |
|
120 |
xbee_checksum_add(data,length,&group); |
|
121 |
group = 0xFF-group; |
|
110 | 122 |
|
111 | 123 |
// send the packet |
112 |
if (xbee_send_packet(packet,length,dest,options,(uint_8)ret_val) != 0) {
|
|
113 |
WL_DEBUG_PRINT("Error sending packet from core send function\r\n"); |
|
124 |
if (xbee_send_header(XBEE_FRAME_TX_REQUEST_16,length+7) != WL_SUCCESS) {
|
|
125 |
WL_DEBUG_PRINT("1Error sending packet from core send function\r\n");
|
|
114 | 126 |
return WL_ERROR_SEND; |
115 | 127 |
} |
128 |
if (xbee_putc(XBEE_FRAME_TX_REQUEST_16) != WL_SUCCESS) { |
|
129 |
WL_DEBUG_PRINT("2Error sending packet from core send function\r\n"); |
|
130 |
return WL_ERROR_SEND; |
|
131 |
} |
|
132 |
if (xbee_send(packet,6) != WL_SUCCESS) { |
|
133 |
WL_DEBUG_PRINT("3Error sending packet from core send function\r\n"); |
|
134 |
return WL_ERROR_SEND; |
|
135 |
} |
|
136 |
if (xbee_send(data,length) != WL_SUCCESS) { |
|
137 |
WL_DEBUG_PRINT("4Error sending packet from core send function\r\n"); |
|
138 |
return WL_ERROR_SEND; |
|
139 |
} |
|
140 |
if (xbee_putc(group) != WL_SUCCESS) { |
|
141 |
WL_DEBUG_PRINT("5Error sending packet from core send function\r\n"); |
|
142 |
return WL_ERROR_SEND; |
|
143 |
} |
|
116 | 144 |
|
117 | 145 |
// save in ack system |
118 | 146 |
if (mode == FAST) { |
119 | 147 |
setack(nextframe,ACK_OK); // assume the send was successful |
120 | 148 |
} else if (mode == RELIABLE) { |
121 | 149 |
setack(nextframe,SENDING); // set status to SENDING |
122 |
// TODO: save packet on sending buffer |
|
123 |
/* if (buffer full) { |
|
150 |
// save packet on sending buffer |
|
151 |
scope = send_buf_last; // use as ptr to send buffer |
|
152 |
if (send_buf_add(&scope,length+6) != WL_SUCCESS) { // add length |
|
124 | 153 |
WL_DEBUG_PRINT("Error: sending buffer full\r\n"); |
125 |
return WL_ERROR_SENDING_BUFFER_FULL |
|
126 |
} */ |
|
154 |
return WL_ERROR_SENDING_BUFFER_FULL; |
|
155 |
} |
|
156 |
for(mode=0;mode<6;mode++) { // add header |
|
157 |
if (send_buf_add(&scope,packet[mode]) != WL_SUCCESS) { |
|
158 |
WL_DEBUG_PRINT("Error: sending buffer full\r\n"); |
|
159 |
return WL_ERROR_SENDING_BUFFER_FULL; |
|
160 |
} |
|
161 |
} |
|
162 |
for(mode=0;mode<length;mode++) { // add data |
|
163 |
if (send_buf_add(&scope,data[mode]) != WL_SUCCESS) { |
|
164 |
WL_DEBUG_PRINT("Error: sending buffer full\r\n"); |
|
165 |
return WL_ERROR_SENDING_BUFFER_FULL; |
|
166 |
} |
|
167 |
} |
|
168 |
if (send_buf_add(&scope,0) != WL_SUCCESS) { // add num retries=0 |
|
169 |
WL_DEBUG_PRINT("Error: sending buffer full\r\n"); |
|
170 |
return WL_ERROR_SENDING_BUFFER_FULL; |
|
171 |
} |
|
172 |
send_buf_last = scope; |
|
173 |
send_buf_num_packets++; |
|
127 | 174 |
} |
128 | 175 |
|
129 | 176 |
// increment frame number |
... | ... | |
273 | 320 |
|
274 | 321 |
/* ack handler */ |
275 | 322 |
void ackhandle(uint8_t num,uint8_t val) { |
323 |
uint8_t len; |
|
276 | 324 |
switch(val) { |
277 | 325 |
case 0: |
278 | 326 |
// success |
279 | 327 |
setack(num,ACK_OK); // set status code |
280 |
// TODO: remove from sending buffer |
|
328 |
// remove from buffer |
|
329 |
val = send_buf_first; |
|
330 |
if (send_buf_num_packets == 0) |
|
331 |
return; |
|
332 |
while (1) { |
|
333 |
len = send_buf_get(&val); |
|
334 |
if (send_buf_get(&val) != num) { |
|
335 |
// not the correct packet, so continue |
|
336 |
val += len; |
|
337 |
if (val >= PACKET_BUFFER_SIZE) |
|
338 |
val -= PACKET_BUFFER_SIZE; |
|
339 |
if (val == send_buf_last) { |
|
340 |
// reached end of bufer, so assume not present |
|
341 |
return; |
|
342 |
} |
|
343 |
} else { |
|
344 |
// remove packet |
|
345 |
num = val+len; |
|
346 |
val = (val<2)?PACKET_BUFFER_SIZE+val-2:val-2; |
|
347 |
if (num >= PACKET_BUFFER_SIZE) |
|
348 |
num -= PACKET_BUFFER_SIZE; |
|
349 |
while(num != send_buf_last) { |
|
350 |
if (send_buf_add(&val,send_buf_get(&num)) != WL_SUCCESS) |
|
351 |
return; // error |
|
352 |
} |
|
353 |
send_buf_last = val; // set new end of buffer |
|
354 |
return; |
|
355 |
} |
|
356 |
} |
|
281 | 357 |
break; |
282 | 358 |
case 1: |
283 | 359 |
// no ack |
284 |
// TODO: check resend attempts |
|
285 |
setack(num,ACK_FAILURE); |
|
286 |
break; |
|
360 |
// check resend attempts |
|
361 |
val = send_buf_first; |
|
362 |
if (send_buf_num_packets == 0) |
|
363 |
return; |
|
364 |
while (1) { |
|
365 |
len = send_buf_get(&val); |
|
366 |
if (send_buf_get(&val) != num) { |
|
367 |
// not the correct packet, so continue |
|
368 |
val += len; |
|
369 |
if (val >= PACKET_BUFFER_SIZE) |
|
370 |
val -= PACKET_BUFFER_SIZE; |
|
371 |
if (val == send_buf_last) { |
|
372 |
// reached end of bufer, so assume not present |
|
373 |
setack(num,ACK_FAILURE); // mark as failed send |
|
374 |
return; |
|
375 |
} |
|
376 |
} else { |
|
377 |
// check attempts on packet |
|
378 |
num = val+len-1; // set to end of packet |
|
379 |
if (num >= PACKET_BUFFER_SIZE) |
|
380 |
num -= PACKET_BUFFER_SIZE; |
|
381 |
if (send_buf[num] < NUM_RETRIES) { |
|
382 |
val = (val<2)?PACKET_BUFFER_SIZE+val-2:val-2; // set to start of this packet |
|
383 |
// retry sending |
|
384 |
send_buf[num]++; // increment retries |
|
385 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // go back one byte |
|
386 |
if (xbee_send_header(XBEE_FRAME_TX_REQUEST_16,len+1) != WL_SUCCESS) { |
|
387 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
388 |
return; |
|
389 |
} |
|
390 |
len = XBEE_FRAME_TX_REQUEST_16; |
|
391 |
while(val!=num) { |
|
392 |
// compute checksum |
|
393 |
len += send_buf[val]; |
|
394 |
if (xbee_putc(send_buf_get(&val)) != WL_SUCCESS) { // send byte |
|
395 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
396 |
return; |
|
397 |
} |
|
398 |
} |
|
399 |
len = 0xFF - len; |
|
400 |
if (xbee_putc(len) != WL_SUCCESS) { // send |
|
401 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
402 |
return; |
|
403 |
} |
|
404 |
return; |
|
405 |
} else { |
|
406 |
// done sending, mark as failed send |
|
407 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to frame num |
|
408 |
setack(send_buf[val],ACK_FAILURE); |
|
409 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to start of this packet |
|
410 |
// remove packet |
|
411 |
while(num != send_buf_last) { |
|
412 |
if (send_buf_add(&val,send_buf_get(&num)) != WL_SUCCESS) |
|
413 |
return; // error |
|
414 |
} |
|
415 |
return; |
|
416 |
} |
|
417 |
} |
|
418 |
} |
|
419 |
break; // shouldn't get here, but just in case |
|
287 | 420 |
case 2: |
288 | 421 |
// CCA failure |
289 |
// TODO: check resend attempts |
|
290 |
setack(num,CCA_FAILURE); |
|
291 |
break; |
|
422 |
// check resend attempts |
|
423 |
val = send_buf_first; |
|
424 |
if (send_buf_num_packets == 0) |
|
425 |
return; |
|
426 |
while (1) { |
|
427 |
len = send_buf_get(&val); |
|
428 |
if (send_buf_get(&val) != num) { |
|
429 |
// not the correct packet, so continue |
|
430 |
val += len; |
|
431 |
if (val >= PACKET_BUFFER_SIZE) |
|
432 |
val -= PACKET_BUFFER_SIZE; |
|
433 |
if (val == send_buf_last) { |
|
434 |
// reached end of bufer, so assume not present |
|
435 |
setack(num,CCA_FAILURE); // mark as failed send |
|
436 |
return; |
|
437 |
} |
|
438 |
} else { |
|
439 |
// check attempts on packet |
|
440 |
num = val+len-1; // set to end of packet |
|
441 |
if (num >= PACKET_BUFFER_SIZE) |
|
442 |
num -= PACKET_BUFFER_SIZE; |
|
443 |
if (send_buf[num] < NUM_RETRIES) { |
|
444 |
val = (val<2)?PACKET_BUFFER_SIZE+val-2:val-2; // set to start of this packet |
|
445 |
// retry sending |
|
446 |
send_buf[num]++; // increment retries |
|
447 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // go back one byte |
|
448 |
if (xbee_send_header(XBEE_FRAME_TX_REQUEST_16,len+1) != WL_SUCCESS) { |
|
449 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
450 |
return; |
|
451 |
} |
|
452 |
len = XBEE_FRAME_TX_REQUEST_16; |
|
453 |
while(val!=num) { |
|
454 |
// compute checksum |
|
455 |
len += send_buf[val]; |
|
456 |
if (xbee_putc(send_buf_get(&val)) != WL_SUCCESS) { // send byte |
|
457 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
458 |
return; |
|
459 |
} |
|
460 |
} |
|
461 |
len = 0xFF - len; |
|
462 |
if (xbee_putc(len) != WL_SUCCESS) { // send |
|
463 |
WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n"); |
|
464 |
return; |
|
465 |
} |
|
466 |
return; |
|
467 |
} else { |
|
468 |
// done sending, mark as failed send |
|
469 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to frame num |
|
470 |
setack(send_buf[val],CCA_FAILURE); |
|
471 |
val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to start of this packet |
|
472 |
// remove packet |
|
473 |
while(num != send_buf_last) { |
|
474 |
if (send_buf_add(&val,send_buf_get(&num)) != WL_SUCCESS) |
|
475 |
return; // error |
|
476 |
} |
|
477 |
return; |
|
478 |
} |
|
479 |
} |
|
480 |
} |
|
481 |
break; // shouldn't get here, but just in case |
|
482 |
} |
|
292 | 483 |
} |
293 | 484 |
|
485 |
/* adds a byte to the send buffer */ |
|
486 |
int8_t send_buf_add(uint8_t *ptr, uint8_t byte) { |
|
487 |
if (*ptr == send_buf_first) { |
|
488 |
// buffer full |
|
489 |
WL_DEBUG_PRINT("send buffer full\r\n"); |
|
490 |
return WL_ERROR_SENDING_BUFFER_FULL; |
|
491 |
} |
|
492 |
send_buf[(*ptr)++] = byte); |
|
493 |
if (*ptr == PACKET_BUFFER_SIZE) |
|
494 |
*ptr = 0; |
|
495 |
return WL_SUCCESS; |
|
496 |
} |
|
497 |
/* gets a byte from the send buffer */ |
|
498 |
uint8_t send_buf_get(uint8_t *ptr) { |
|
499 |
uint8_t byte = xbee_basic_buf[(*ptr)++]; |
|
500 |
if (*ptr == PACKET_BUFFER_SIZE) |
|
501 |
*ptr = 0; |
|
502 |
return byte; |
|
503 |
} |
Also available in: Unified diff