root / branches / wireless / code / projects / libwireless / wireless_send.c @ 1617
History | View | Annotate | Download (15.6 KB)
1 | 1576 | dsschult | /**
|
---|---|---|---|
2 | * Copyright (c) 2009 Colony Project
|
||
3 | *
|
||
4 | * Permission is hereby granted, free of charge, to any person
|
||
5 | * obtaining a copy of this software and associated documentation
|
||
6 | * files (the "Software"), to deal in the Software without
|
||
7 | * restriction, including without limitation the rights to use,
|
||
8 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
9 | * copies of the Software, and to permit persons to whom the
|
||
10 | * Software is furnished to do so, subject to the following
|
||
11 | * conditions:
|
||
12 | *
|
||
13 | * The above copyright notice and this permission notice shall be
|
||
14 | * included in all copies or substantial portions of the Software.
|
||
15 | *
|
||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||
18 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
19 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||
20 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||
21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||
22 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||
23 | * OTHER DEALINGS IN THE SOFTWARE.
|
||
24 | **/
|
||
25 | |||
26 | /**
|
||
27 | * @file wireless_send.c
|
||
28 | * @brief Wireless library send functions
|
||
29 | *
|
||
30 | * Implementation of high level wireless communication.
|
||
31 | * This is the send functions portion of the library.
|
||
32 | *
|
||
33 | * @author Colony Project, CMU Robotics Club
|
||
34 | **/
|
||
35 | |||
36 | #include "wl_defs.h" |
||
37 | #include "wireless.h" |
||
38 | 1608 | dsschult | #include "xbee.h" |
39 | 1587 | dsschult | #include <string.h> |
40 | 1576 | dsschult | |
41 | |||
42 | 1588 | dsschult | /**
|
43 | 1591 | dsschult | * Definition for wireless library send packet structure
|
44 | 1604 | dsschult | * byte 1: length of packet (from frame number to end of data)
|
45 | 1588 | dsschult | * byte 2: frame number
|
46 | 1604 | dsschult | * bytes 3-n: data (dest, options, frame number, group code, packet)
|
47 | * byte n+1: num retries
|
||
48 | 1587 | dsschult | *
|
49 | * Definition for ack buffer
|
||
50 | * 2 bit system: 0=still sending
|
||
51 | * 1=OK
|
||
52 | * 2=ack failure
|
||
53 | * 3=CCA failure
|
||
54 | 1588 | dsschult | **/
|
55 | 1587 | dsschult | |
56 | |||
57 | /* global variables */
|
||
58 | 1600 | dsschult | uint8_t nextframe = 1; // number of next frame |
59 | uint8_t ack_buf[64]; // ack buffer (holds 255 packet return codes) |
||
60 | uint8_t send_buf[PACKET_BUFFER_SIZE]; // sending buffer for retries
|
||
61 | uint8_t send_buf_first = 0; // first byte of data on buffer |
||
62 | uint8_t send_buf_last = 0; // next free byte on buffer |
||
63 | 1604 | dsschult | uint8_t send_buf_num_packets = 0; // number of packets in sending buffer |
64 | 1587 | dsschult | |
65 | /* private function prototypes */
|
||
66 | void setack(uint8_t num,uint8_t val);
|
||
67 | 1604 | dsschult | void ackhandle(uint8_t num,uint8_t val);
|
68 | 1608 | dsschult | int8_t send_buf_add(uint8_t *ptr, uint8_t byte); |
69 | 1604 | dsschult | uint8_t send_buf_get(uint8_t *ptr); |
70 | 1587 | dsschult | |
71 | 1576 | dsschult | // the send functions
|
72 | 1577 | dsschult | |
73 | /**
|
||
74 | * @addtogroup wireless Wireless
|
||
75 | * @{
|
||
76 | **/
|
||
77 | |||
78 | |||
79 | /**
|
||
80 | * The core send function. This will take all possible arguments and send all types of packets.
|
||
81 | *
|
||
82 | * @param data pointer to the byte array of data to be included in the packet
|
||
83 | * @param length the length of the data array
|
||
84 | * @param group the packet group of the packet
|
||
85 | 1581 | dsschult | * @param scope flag for sending global packet or your current PAN
|
86 | 1577 | dsschult | * @param dest robot ID (for robot to robot packet)
|
87 | 1581 | dsschult | * @param mode flag for using FAST or RELIABLE sending
|
88 | 1577 | dsschult | *
|
89 | 1581 | dsschult | * @return positive packet number for tracking acks, or error code (TBD)
|
90 | 1577 | dsschult | **/
|
91 | 1587 | dsschult | int16_t wl_send(uint8_t *data, uint8_t length, uint8_t group, uint8_t scope, uint16_t dest, uint8_t mode) { |
92 | 1604 | dsschult | uint8_t packet[6];
|
93 | 1587 | dsschult | |
94 | 1604 | dsschult | // build packet header
|
95 | 1587 | dsschult | packet[0] = nextframe;
|
96 | 1604 | dsschult | packet[1] = (dest&0xFF00)>>8; |
97 | packet[2] = dest&0x00FF; |
||
98 | packet[3] = XBEE_OPTIONS_NONE;
|
||
99 | packet[4] = nextframe;
|
||
100 | packet[5] = group;
|
||
101 | 1587 | dsschult | |
102 | 1600 | dsschult | // set scope
|
103 | 1587 | dsschult | if (scope == GLOBAL)
|
104 | 1604 | dsschult | packet[3] &= XBEE_OPTIONS_BROADCAST_ALL_PANS;
|
105 | else if (scope != PAN) { |
||
106 | WL_DEBUG_PRINT("Error - bad scope in core send function\r\n");
|
||
107 | return WL_ERROR_SCOPE;
|
||
108 | } |
||
109 | 1600 | dsschult | |
110 | // set mode
|
||
111 | 1587 | dsschult | if (mode == FAST) {
|
112 | 1604 | dsschult | packet[3] &= XBEE_OPTIONS_DISABLE_RESPONSE;
|
113 | 1600 | dsschult | } else if (mode != RELIABLE) { |
114 | 1587 | dsschult | WL_DEBUG_PRINT("Error - bad mode in core send function\r\n");
|
115 | return WL_ERROR_MODE;
|
||
116 | } |
||
117 | 1604 | dsschult | |
118 | // do checksum
|
||
119 | group = XBEE_FRAME_TX_REQUEST_16; |
||
120 | xbee_checksum_add(packet,6,&group);
|
||
121 | xbee_checksum_add(data,length,&group); |
||
122 | group = 0xFF-group;
|
||
123 | 1576 | dsschult | |
124 | 1587 | dsschult | // send the packet
|
125 | 1604 | dsschult | if (xbee_send_header(XBEE_FRAME_TX_REQUEST_16,length+7) != WL_SUCCESS) { |
126 | WL_DEBUG_PRINT("1Error sending packet from core send function\r\n");
|
||
127 | 1587 | dsschult | return WL_ERROR_SEND;
|
128 | } |
||
129 | 1604 | dsschult | if (xbee_putc(XBEE_FRAME_TX_REQUEST_16) != WL_SUCCESS) {
|
130 | WL_DEBUG_PRINT("2Error sending packet from core send function\r\n");
|
||
131 | return WL_ERROR_SEND;
|
||
132 | } |
||
133 | if (xbee_send(packet,6) != WL_SUCCESS) { |
||
134 | WL_DEBUG_PRINT("3Error sending packet from core send function\r\n");
|
||
135 | return WL_ERROR_SEND;
|
||
136 | } |
||
137 | if (xbee_send(data,length) != WL_SUCCESS) {
|
||
138 | WL_DEBUG_PRINT("4Error sending packet from core send function\r\n");
|
||
139 | return WL_ERROR_SEND;
|
||
140 | } |
||
141 | if (xbee_putc(group) != WL_SUCCESS) {
|
||
142 | WL_DEBUG_PRINT("5Error sending packet from core send function\r\n");
|
||
143 | return WL_ERROR_SEND;
|
||
144 | } |
||
145 | 1587 | dsschult | |
146 | 1600 | dsschult | // save in ack system
|
147 | if (mode == FAST) {
|
||
148 | setack(nextframe,ACK_OK); // assume the send was successful
|
||
149 | 1608 | dsschult | nextframe = (nextframe == 0xFF)?1:nextframe+1; // increment frame number |
150 | return WL_SUCCESS; // no frame number |
||
151 | 1600 | dsschult | } else if (mode == RELIABLE) { |
152 | setack(nextframe,SENDING); // set status to SENDING
|
||
153 | 1604 | dsschult | // save packet on sending buffer
|
154 | scope = send_buf_last; // use as ptr to send buffer
|
||
155 | if (send_buf_add(&scope,length+6) != WL_SUCCESS) { // add length |
||
156 | 1600 | dsschult | WL_DEBUG_PRINT("Error: sending buffer full\r\n");
|
157 | 1604 | dsschult | return WL_ERROR_SENDING_BUFFER_FULL;
|
158 | } |
||
159 | for(mode=0;mode<6;mode++) { // add header |
||
160 | if (send_buf_add(&scope,packet[mode]) != WL_SUCCESS) {
|
||
161 | WL_DEBUG_PRINT("Error: sending buffer full\r\n");
|
||
162 | return WL_ERROR_SENDING_BUFFER_FULL;
|
||
163 | } |
||
164 | } |
||
165 | for(mode=0;mode<length;mode++) { // add data |
||
166 | if (send_buf_add(&scope,data[mode]) != WL_SUCCESS) {
|
||
167 | WL_DEBUG_PRINT("Error: sending buffer full\r\n");
|
||
168 | return WL_ERROR_SENDING_BUFFER_FULL;
|
||
169 | } |
||
170 | } |
||
171 | if (send_buf_add(&scope,0) != WL_SUCCESS) { // add num retries=0 |
||
172 | WL_DEBUG_PRINT("Error: sending buffer full\r\n");
|
||
173 | return WL_ERROR_SENDING_BUFFER_FULL;
|
||
174 | } |
||
175 | send_buf_last = scope; |
||
176 | send_buf_num_packets++; |
||
177 | 1608 | dsschult | |
178 | nextframe = (nextframe == 0xFF)?1:nextframe+1; // increment frame number |
||
179 | return packet[0]; // return frame number for ack tracking |
||
180 | 1600 | dsschult | } |
181 | 1609 | dsschult | return WL_ERROR_SEND;
|
182 | 1576 | dsschult | } |
183 | |||
184 | 1577 | dsschult | /**
|
185 | * Wrapper for core send function that will send a global packet across the current channel.
|
||
186 | *
|
||
187 | * @param data pointer to the byte array of data to be included in the packet
|
||
188 | * @param length the length of the data array
|
||
189 | * @param group the packet group of the packet
|
||
190 | *
|
||
191 | 1581 | dsschult | * @return positive packet number for tracking acks, or error code (TBD)
|
192 | 1577 | dsschult | **/
|
193 | 1609 | dsschult | int16_t wl_send_global(uint8_t *data, uint8_t length, uint8_t group) { |
194 | 1608 | dsschult | return wl_send(data, length, group, GLOBAL, BROADCAST, RELIABLE);
|
195 | 1576 | dsschult | } |
196 | |||
197 | 1577 | dsschult | /**
|
198 | * Wrapper for core send function that will send a packet across the current channel on the current pan.
|
||
199 | *
|
||
200 | * @param data pointer to the byte array of data to be included in the packet
|
||
201 | * @param length the length of the data array
|
||
202 | * @param group the packet group of the packet
|
||
203 | *
|
||
204 | 1581 | dsschult | * @return positive packet number for tracking acks, or error code (TBD)
|
205 | 1577 | dsschult | **/
|
206 | 1609 | dsschult | int16_t wl_send_pan(uint8_t *data, uint8_t length, uint8_t group) { |
207 | 1608 | dsschult | return wl_send(data, length, group, PAN, BROADCAST, RELIABLE);
|
208 | 1576 | dsschult | } |
209 | |||
210 | 1577 | dsschult | /**
|
211 | * Wrapper for core send function that will send a packet across the current channel to a specific robot.
|
||
212 | *
|
||
213 | * @param data pointer to the byte array of data to be included in the packet
|
||
214 | * @param length the length of the data array
|
||
215 | * @param group the packet group of the packet
|
||
216 | * @param dest robot ID (for robot to robot packet)
|
||
217 | 1581 | dsschult | * @param mode flag for using FAST or RELIABLE sending
|
218 | 1577 | dsschult | *
|
219 | 1581 | dsschult | * @return positive packet number for tracking acks, or error code (TBD)
|
220 | 1577 | dsschult | **/
|
221 | 1609 | dsschult | int16_t wl_send_robot(uint8_t *data, uint8_t length, uint8_t group, uint16_t dest, uint8_t mode) { |
222 | 1608 | dsschult | return wl_send(data, length, group, GLOBAL, dest, mode);
|
223 | 1576 | dsschult | } |
224 | |||
225 | 1577 | dsschult | /**
|
226 | * Default (i.e. basic) send wrapper.
|
||
227 | *
|
||
228 | * @param data pointer to the byte array of data to be included in the packet
|
||
229 | * @param length the length of the data array
|
||
230 | *
|
||
231 | 1581 | dsschult | * @return positive packet number for tracking acks, or error code (TBD)
|
232 | 1577 | dsschult | **/
|
233 | 1609 | dsschult | int16_t wl_send_basic(uint8_t *data, uint8_t length) { |
234 | 1607 | bwasserm | /** Check if it needs to adjust according to data type. **/
|
235 | 1609 | dsschult | return wl_send(data, length, BASIC, GLOBAL, BROADCAST, RELIABLE);
|
236 | 1576 | dsschult | } |
237 | |||
238 | |||
239 | 1577 | dsschult | /**
|
240 | * acknowledgment error
|
||
241 | 1581 | dsschult | * check if any of the packets you have sent have been lost.
|
242 | 1577 | dsschult | *
|
243 | 1581 | dsschult | * note that all other error checking will be handled by library,
|
244 | * so your user behavior won't have to worry about it
|
||
245 | 1577 | dsschult | *
|
246 | 1581 | dsschult | * @return the # of packets lost (up to 255)
|
247 | 1577 | dsschult | **/
|
248 | 1587 | dsschult | uint8_t wl_ack_error(void) {
|
249 | 1609 | dsschult | uint8_t val=0,i=1; |
250 | 1587 | dsschult | |
251 | while(1) { |
||
252 | 1609 | dsschult | if (((ack_buf[i/4])&(0x2<<(i%4))) != 0) // if the ack is in an error state |
253 | 1587 | dsschult | val++; |
254 | if (i==255) |
||
255 | break;
|
||
256 | i++; |
||
257 | } |
||
258 | 1576 | dsschult | |
259 | 1587 | dsschult | return val;
|
260 | 1576 | dsschult | } |
261 | |||
262 | 1581 | dsschult | /**
|
263 | * acknowledgement error check
|
||
264 | * check if a specific packet has been lost
|
||
265 | 1587 | dsschult | * note: buffer will overflow every 255 packets
|
266 | 1581 | dsschult | *
|
267 | 1587 | dsschult | * @param packet packet number
|
268 | 1581 | dsschult | *
|
269 | 1587 | dsschult | * @return {SENDING,ACK_OK,ACK_FAILURE,CCA_FAILURE}
|
270 | 1581 | dsschult | **/
|
271 | int8_t wl_ack_check(uint8_t packet) { |
||
272 | 1587 | dsschult | if (packet == 0) { |
273 | // no ack information here
|
||
274 | 1609 | dsschult | WL_DEBUG_PRINT("packet number cannot be 0\r\n");
|
275 | 1587 | dsschult | return WL_ERROR_ARGUMENT;
|
276 | } |
||
277 | |||
278 | // check ack
|
||
279 | return ack_buf[packet/4]&(0x3<<(packet%4)); |
||
280 | 1581 | dsschult | } |
281 | |||
282 | /**
|
||
283 | * acknowledgement reset
|
||
284 | * reset the acknowledgement buffer
|
||
285 | **/
|
||
286 | void wl_ack_reset(void) { |
||
287 | 1587 | dsschult | memset(ack_buf,0,64); |
288 | 1581 | dsschult | } |
289 | |||
290 | |||
291 | 1577 | dsschult | /**@} **/ //end defgroup |
292 | |||
293 | |||
294 | // Define all private functions down here
|
||
295 | |||
296 | 1587 | dsschult | /*
|
297 | * sets 2 bits in the ack_buf
|
||
298 | *
|
||
299 | * @param num the ack number
|
||
300 | * @param val {SENDING,ACK_OK,ACK_FAILURE,CCA_FAILURE}
|
||
301 | */
|
||
302 | void setack(uint8_t num,uint8_t val) {
|
||
303 | switch(num%4) { |
||
304 | case 0: |
||
305 | ack_buf[num/4] &= (0xFC|val); |
||
306 | break;
|
||
307 | case 1: |
||
308 | ack_buf[num/4] &= (0xF3|(val<<2)); |
||
309 | break;
|
||
310 | case 2: |
||
311 | ack_buf[num/4] &= (0xCF|(val<<4)); |
||
312 | break;
|
||
313 | case 3: |
||
314 | ack_buf[num/4] &= (0x3F|(val<<6)); |
||
315 | break;
|
||
316 | } |
||
317 | } |
||
318 | 1577 | dsschult | |
319 | 1591 | dsschult | |
320 | /* ack handler */
|
||
321 | void ackhandle(uint8_t num,uint8_t val) {
|
||
322 | 1604 | dsschult | uint8_t len; |
323 | 1591 | dsschult | switch(val) {
|
324 | case 0: |
||
325 | // success
|
||
326 | 1600 | dsschult | setack(num,ACK_OK); // set status code
|
327 | 1604 | dsschult | // remove from buffer
|
328 | val = send_buf_first; |
||
329 | if (send_buf_num_packets == 0) |
||
330 | return;
|
||
331 | while (1) { |
||
332 | len = send_buf_get(&val); |
||
333 | if (send_buf_get(&val) != num) {
|
||
334 | // not the correct packet, so continue
|
||
335 | val += len; |
||
336 | if (val >= PACKET_BUFFER_SIZE)
|
||
337 | val -= PACKET_BUFFER_SIZE; |
||
338 | if (val == send_buf_last) {
|
||
339 | // reached end of bufer, so assume not present
|
||
340 | return;
|
||
341 | } |
||
342 | } else {
|
||
343 | // remove packet
|
||
344 | num = val+len; |
||
345 | val = (val<2)?PACKET_BUFFER_SIZE+val-2:val-2; |
||
346 | if (num >= PACKET_BUFFER_SIZE)
|
||
347 | num -= PACKET_BUFFER_SIZE; |
||
348 | while(num != send_buf_last) {
|
||
349 | if (send_buf_add(&val,send_buf_get(&num)) != WL_SUCCESS)
|
||
350 | return; // error |
||
351 | } |
||
352 | send_buf_last = val; // set new end of buffer
|
||
353 | return;
|
||
354 | } |
||
355 | } |
||
356 | 1591 | dsschult | break;
|
357 | case 1: |
||
358 | // no ack
|
||
359 | 1604 | dsschult | // check resend attempts
|
360 | val = send_buf_first; |
||
361 | if (send_buf_num_packets == 0) |
||
362 | return;
|
||
363 | while (1) { |
||
364 | len = send_buf_get(&val); |
||
365 | if (send_buf_get(&val) != num) {
|
||
366 | // not the correct packet, so continue
|
||
367 | val += len; |
||
368 | if (val >= PACKET_BUFFER_SIZE)
|
||
369 | val -= PACKET_BUFFER_SIZE; |
||
370 | if (val == send_buf_last) {
|
||
371 | // reached end of bufer, so assume not present
|
||
372 | setack(num,ACK_FAILURE); // mark as failed send
|
||
373 | return;
|
||
374 | } |
||
375 | } else {
|
||
376 | // check attempts on packet
|
||
377 | num = val+len-1; // set to end of packet |
||
378 | if (num >= PACKET_BUFFER_SIZE)
|
||
379 | num -= PACKET_BUFFER_SIZE; |
||
380 | if (send_buf[num] < NUM_RETRIES) {
|
||
381 | val = (val<2)?PACKET_BUFFER_SIZE+val-2:val-2; // set to start of this packet |
||
382 | // retry sending
|
||
383 | send_buf[num]++; // increment retries
|
||
384 | val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // go back one byte |
||
385 | if (xbee_send_header(XBEE_FRAME_TX_REQUEST_16,len+1) != WL_SUCCESS) { |
||
386 | WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n");
|
||
387 | return;
|
||
388 | } |
||
389 | len = XBEE_FRAME_TX_REQUEST_16; |
||
390 | while(val!=num) {
|
||
391 | // compute checksum
|
||
392 | len += send_buf[val]; |
||
393 | if (xbee_putc(send_buf_get(&val)) != WL_SUCCESS) { // send byte |
||
394 | WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n");
|
||
395 | return;
|
||
396 | } |
||
397 | } |
||
398 | len = 0xFF - len;
|
||
399 | if (xbee_putc(len) != WL_SUCCESS) { // send |
||
400 | WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n");
|
||
401 | return;
|
||
402 | } |
||
403 | return;
|
||
404 | } else {
|
||
405 | // done sending, mark as failed send
|
||
406 | val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to frame num |
||
407 | setack(send_buf[val],ACK_FAILURE); |
||
408 | val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to start of this packet |
||
409 | // remove packet
|
||
410 | while(num != send_buf_last) {
|
||
411 | if (send_buf_add(&val,send_buf_get(&num)) != WL_SUCCESS)
|
||
412 | return; // error |
||
413 | } |
||
414 | return;
|
||
415 | } |
||
416 | } |
||
417 | } |
||
418 | break; // shouldn't get here, but just in case |
||
419 | 1591 | dsschult | case 2: |
420 | // CCA failure
|
||
421 | 1604 | dsschult | // check resend attempts
|
422 | val = send_buf_first; |
||
423 | if (send_buf_num_packets == 0) |
||
424 | return;
|
||
425 | while (1) { |
||
426 | len = send_buf_get(&val); |
||
427 | if (send_buf_get(&val) != num) {
|
||
428 | // not the correct packet, so continue
|
||
429 | val += len; |
||
430 | if (val >= PACKET_BUFFER_SIZE)
|
||
431 | val -= PACKET_BUFFER_SIZE; |
||
432 | if (val == send_buf_last) {
|
||
433 | // reached end of bufer, so assume not present
|
||
434 | setack(num,CCA_FAILURE); // mark as failed send
|
||
435 | return;
|
||
436 | } |
||
437 | } else {
|
||
438 | // check attempts on packet
|
||
439 | num = val+len-1; // set to end of packet |
||
440 | if (num >= PACKET_BUFFER_SIZE)
|
||
441 | num -= PACKET_BUFFER_SIZE; |
||
442 | if (send_buf[num] < NUM_RETRIES) {
|
||
443 | val = (val<2)?PACKET_BUFFER_SIZE+val-2:val-2; // set to start of this packet |
||
444 | // retry sending
|
||
445 | send_buf[num]++; // increment retries
|
||
446 | val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // go back one byte |
||
447 | if (xbee_send_header(XBEE_FRAME_TX_REQUEST_16,len+1) != WL_SUCCESS) { |
||
448 | WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n");
|
||
449 | return;
|
||
450 | } |
||
451 | len = XBEE_FRAME_TX_REQUEST_16; |
||
452 | while(val!=num) {
|
||
453 | // compute checksum
|
||
454 | len += send_buf[val]; |
||
455 | if (xbee_putc(send_buf_get(&val)) != WL_SUCCESS) { // send byte |
||
456 | WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n");
|
||
457 | return;
|
||
458 | } |
||
459 | } |
||
460 | len = 0xFF - len;
|
||
461 | if (xbee_putc(len) != WL_SUCCESS) { // send |
||
462 | WL_DEBUG_PRINT("Error sending packet from ackhandle function\r\n");
|
||
463 | return;
|
||
464 | } |
||
465 | return;
|
||
466 | } else {
|
||
467 | // done sending, mark as failed send
|
||
468 | val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to frame num |
||
469 | setack(send_buf[val],CCA_FAILURE); |
||
470 | val = (val==0)?PACKET_BUFFER_SIZE-1:val-1; // set to start of this packet |
||
471 | // remove packet
|
||
472 | while(num != send_buf_last) {
|
||
473 | if (send_buf_add(&val,send_buf_get(&num)) != WL_SUCCESS)
|
||
474 | return; // error |
||
475 | } |
||
476 | return;
|
||
477 | } |
||
478 | } |
||
479 | } |
||
480 | break; // shouldn't get here, but just in case |
||
481 | } |
||
482 | 1591 | dsschult | } |
483 | |||
484 | 1604 | dsschult | /* adds a byte to the send buffer */
|
485 | int8_t send_buf_add(uint8_t *ptr, uint8_t byte) { |
||
486 | if (*ptr == send_buf_first) {
|
||
487 | // buffer full
|
||
488 | WL_DEBUG_PRINT("send buffer full\r\n");
|
||
489 | return WL_ERROR_SENDING_BUFFER_FULL;
|
||
490 | } |
||
491 | 1609 | dsschult | send_buf[(*ptr)++] = byte; |
492 | 1604 | dsschult | if (*ptr == PACKET_BUFFER_SIZE)
|
493 | *ptr = 0;
|
||
494 | return WL_SUCCESS;
|
||
495 | } |
||
496 | /* gets a byte from the send buffer */
|
||
497 | uint8_t send_buf_get(uint8_t *ptr) { |
||
498 | 1609 | dsschult | uint8_t byte = send_buf[(*ptr)++]; |
499 | 1604 | dsschult | if (*ptr == PACKET_BUFFER_SIZE)
|
500 | *ptr = 0;
|
||
501 | return byte;
|
||
502 | } |