1 /*
2 *
3 * BlueZ - Bluetooth protocol stack for Linux
4 *
5 * Copyright (C) 2000-2005 CSR Ltd.
6 *
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 /*****************************************************************************/
34 /*****************************************************************************/
35 /*****************************************************************************/
36 /** **/
37 /** ubcsp,c **/
38 /** **/
39 /** MicroBCSP - a very low cost implementation of the BCSP protocol **/
40 /** **/
41 /*****************************************************************************/
42
43 #include "ubcsp.h"
44
45 #if SHOW_PACKET_ERRORS || SHOW_LE_STATES
46 #include <stdio.h>
47 #include <windows.h>
48 #endif
49
50 static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc);
51 static uint16 ubcsp_crc_reverse (uint16);
52
53 /*****************************************************************************/
54 /** **/
55 /** Constant Data - ROM **/
56 /** **/
57 /*****************************************************************************/
58
59 /* This is the storage for the link establishment messages */
60
61 static const uint8 ubcsp_le_buffer[4][4] =
62 {
63 { 0xDA, 0xDC, 0xED, 0xED },
64 { 0xAC, 0xAF, 0xEF, 0xEE },
65 { 0xAD, 0xEF, 0xAC, 0xED },
66 { 0xDE, 0xAD, 0xD0, 0xD0 },
67 };
68
69 /* These are the link establishment headers */
70 /* The two version are for the CRC and non-CRC varients */
71
72 #if UBCSP_CRC
73 static const uint8 ubcsp_send_le_header[4] =
74 {
75 0x40, 0x41, 0x00, 0x7E
76 };
77 #else
78 static const uint8 ubcsp_send_le_header[4] =
79 {
80 0x00, 0x41, 0x00, 0xBE
81 };
82 #endif
83
84 /*****************************************************************************/
85 /** **/
86 /** Static Data - RAM **/
87 /** **/
88 /*****************************************************************************/
89
90 /* This is the storage for all state data for ubcsp */
91
92 static struct ubcsp_configuration ubcsp_config;
93
94 /* This is the ACK packet header - this will be overwritten when
95 we create an ack packet */
96
97 static uint8 ubcsp_send_ack_header[4] =
98 {
99 0x00, 0x00, 0x00, 0x00
100 };
101
102 /* This is the deslip lookup table */
103
104 static const uint8 ubcsp_deslip[2] =
105 {
106 SLIP_FRAME, SLIP_ESCAPE,
107 };
108
109 /* This is a state machine table for link establishment */
110
111 static uint8 next_le_packet[16] =
112 {
113 ubcsp_le_sync, // uninit
114 ubcsp_le_conf, // init
115 ubcsp_le_none, // active
116 ubcsp_le_none,
117 ubcsp_le_sync_resp, // sync_resp
118 ubcsp_le_sync_resp,
119 ubcsp_le_none,
120 ubcsp_le_none,
121 ubcsp_le_none, // conf_resp
122 ubcsp_le_conf_resp,
123 ubcsp_le_conf_resp,
124 ubcsp_le_none,
125 };
126
127 /* This is the storage required for building send and crc data */
128
129 static uint8 ubcsp_send_header[4];
130 static uint8 ubcsp_send_crc[2];
131
132 /* This is where the receive header is stored before the payload arrives */
133
134 static uint8 ubcsp_receive_header[4];
135
136 /*****************************************************************************/
137 /** **/
138 /** Code - ROM or RAM **/
139 /** **/
140 /*****************************************************************************/
141
142 /*****************************************************************************/
143 /** **/
144 /** ubcsp_initialize **/
145 /** **/
146 /** This initializes the state of the ubcsp engine to a known values **/
147 /** **/
148 /*****************************************************************************/
149
ubcsp_initialize(void)150 void ubcsp_initialize (void)
151 {
152 ubcsp_config.ack_number = 0;
153 ubcsp_config.sequence_number = 0;
154 ubcsp_config.send_ptr = 0;
155 ubcsp_config.send_size = 0;
156 ubcsp_config.receive_index = -4;
157
158 ubcsp_config.delay = 0;
159
160 #if SHOW_LE_STATES
161 printf ("Hello Link Uninitialized\n");
162 #endif
163
164 ubcsp_config.link_establishment_state = ubcsp_le_uninitialized;
165 ubcsp_config.link_establishment_packet = ubcsp_le_sync;
166 }
167
168 /*****************************************************************************/
169 /** **/
170 /** ubcsp_send_packet **/
171 /** **/
172 /** This sends a packet structure for sending to the ubcsp engine **/
173 /** This can only be called when the activity indication from ubcsp_poll **/
174 /** indicates that a packet can be sent with UBCSP_PACKET_SENT **/
175 /** **/
176 /*****************************************************************************/
177
ubcsp_send_packet(struct ubcsp_packet * send_packet)178 void ubcsp_send_packet (struct ubcsp_packet *send_packet)
179 {
180 /* Initialize the send data to the packet we want to send */
181
182 ubcsp_config.send_packet = send_packet;
183
184 /* we cannot send the packet at the moment
185 when we can at the moment, just set things to 0 */
186
187 ubcsp_config.send_size = 0;
188 ubcsp_config.send_ptr = 0;
189 }
190
191 /*****************************************************************************/
192 /** **/
193 /** ubcsp_receive_packet **/
194 /** **/
195 /** This sends a packet structure for receiving to the ubcsp engine **/
196 /** This can only be called when the activity indication from ubcsp_poll **/
197 /** indicates that a packet can be sent with UBCSP_PACKET_RECEIVED **/
198 /** **/
199 /*****************************************************************************/
200
ubcsp_receive_packet(struct ubcsp_packet * receive_packet)201 void ubcsp_receive_packet (struct ubcsp_packet *receive_packet)
202 {
203 /* Initialize the receive data to the packet we want to receive */
204
205 ubcsp_config.receive_packet = receive_packet;
206
207 /* setup to receive the header first */
208
209 ubcsp_config.receive_index = -4;
210 }
211
212 /*****************************************************************************/
213 /** **/
214 /** ubcsp_calc_crc **/
215 /** **/
216 /** Takes the next 8 bit value ch, and updates the crc with this value **/
217 /** **/
218 /*****************************************************************************/
219
220
221 #ifdef UBCSP_CRC
222
ubcsp_calc_crc(uint8 ch,uint16 crc)223 static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc)
224 {
225 /* Calculate the CRC using the above 16 entry lookup table */
226
227 static const uint16 crc_table[] =
228 {
229 0x0000, 0x1081, 0x2102, 0x3183,
230 0x4204, 0x5285, 0x6306, 0x7387,
231 0x8408, 0x9489, 0xa50a, 0xb58b,
232 0xc60c, 0xd68d, 0xe70e, 0xf78f
233 };
234
235 /* Do this four bits at a time - more code, less space */
236
237 crc = (crc >> 4) ^ crc_table[(crc ^ ch) & 0x000f];
238 crc = (crc >> 4) ^ crc_table[(crc ^ (ch >> 4)) & 0x000f];
239
240 return crc;
241 }
242
243 /*****************************************************************************/
244 /** **/
245 /** ubcsp_crc_reverse **/
246 /** **/
247 /** Reserves the bits in crc and returns the new value **/
248 /** **/
249 /*****************************************************************************/
250
ubcsp_crc_reverse(uint16 crc)251 static uint16 ubcsp_crc_reverse (uint16 crc)
252 {
253 int32
254 b,
255 rev;
256
257 /* Reserse the bits to compute the actual CRC value */
258
259 for (b = 0, rev=0; b < 16; b++)
260 {
261 rev = rev << 1;
262 rev |= (crc & 1);
263 crc = crc >> 1;
264 }
265
266 return rev;
267 }
268
269 #endif
270
271 /*****************************************************************************/
272 /** **/
273 /** ubcsp_put_slip_uart **/
274 /** **/
275 /** Outputs a single octet to the uart **/
276 /** If the octet needs to be escaped, then output the escape value **/
277 /** and then store the second octet to be output later **/
278 /** **/
279 /*****************************************************************************/
280
ubcsp_put_slip_uart(uint8 ch)281 static void ubcsp_put_slip_uart (uint8 ch)
282 {
283 /* output a single UART octet */
284
285 /* If it needs to be escaped, then output the escape octet
286 and set the send_slip_escape so that the next time we
287 output the second octet for the escape correctly.
288 This is done right at the top of ubcsp_poll */
289
290 if (ch == SLIP_FRAME)
291 {
292 put_uart (SLIP_ESCAPE);
293 ubcsp_config.send_slip_escape = SLIP_ESCAPE_FRAME;
294 }
295 else if (ch == SLIP_ESCAPE)
296 {
297 put_uart (SLIP_ESCAPE);
298 ubcsp_config.send_slip_escape = SLIP_ESCAPE_ESCAPE;
299 }
300 else
301 {
302 /* Not escaped, so just output octet */
303
304 put_uart (ch);
305 }
306 }
307
308 /*****************************************************************************/
309 /** **/
310 /** ubcsp_which_le_payload **/
311 /** **/
312 /** Check the payload of this packet, and determine which of the four **/
313 /** link establishment packets this was. **/
314 /** Can return 5 if it is not a valid link establishment packet **/
315 /** **/
316 /*****************************************************************************/
317
ubcsp_which_le_payload(const uint8 * payload)318 static uint32 ubcsp_which_le_payload (const uint8 *payload)
319 {
320 static int32
321 octet,
322 loop;
323
324 /* Search through the various link establishment payloads to find
325 which one we have received */
326
327 for (loop = 0; loop < 4; loop ++)
328 {
329 for (octet = 0; octet < 4; octet ++)
330 {
331 if (payload[octet] != ubcsp_le_buffer[loop][octet])
332 {
333 /* Bad match, just to loop again */
334 goto bad_match_loop;
335 }
336 }
337
338 /* All the octets matched, return the value */
339
340 return loop;
341
342 /* Jumps out of octet loop if we got a bad match */
343 bad_match_loop:
344 {}
345 }
346
347 /* Non of the link establishment payloads matched - return invalid value */
348
349 return 5;
350 }
351
352 /*****************************************************************************/
353 /** **/
354 /** ubcsp_recevied_packet **/
355 /** **/
356 /** This function is called when we have a SLIP END octet and a full **/
357 /** packet header and possibly data in the receive packet **/
358 /** **/
359 /*****************************************************************************/
360
ubcsp_recevied_packet(void)361 static uint8 ubcsp_recevied_packet (void)
362 {
363 static uint8
364 receive_crc,
365 receive_seq,
366 receive_ack,
367 activity;
368
369 #if UBCSP_CRC
370 static int32
371 loop;
372
373 static uint16
374 crc;
375 #endif
376
377 static uint16
378 length;
379
380 /* Keep track of what activity this received packet will cause */
381
382 activity = 0;
383
384 /*** Do all error checks that we can ***/
385
386 /* First check the header checksum */
387
388 if (((ubcsp_receive_header[0] + ubcsp_receive_header[1] + ubcsp_receive_header[2] + ubcsp_receive_header[3]) & 0xff) != 0xff)
389 {
390 /* Header Checksum Error */
391
392 #if SHOW_PACKET_ERRORS
393 printf ("\n######################## Header Checksum Error %02X %02X %02X %02X\n",
394 ubcsp_receive_header[0],
395 ubcsp_receive_header[1],
396 ubcsp_receive_header[2],
397 ubcsp_receive_header[3]);
398 #endif
399
400 /* If we have a header checksum error, send an ack in return
401 this gets a packet to be resent as quickly as possible */
402
403 ubcsp_config.send_ack = 1;
404
405 return activity;
406 }
407
408 /* Decode the received packets header */
409
410 ubcsp_config.receive_packet->reliable = (ubcsp_receive_header[0] & 0x80) >> 7;
411
412 receive_crc = (ubcsp_receive_header[0] & 0x40) >> 6;
413 receive_ack = (ubcsp_receive_header[0] & 0x38) >> 3;
414 receive_seq = (ubcsp_receive_header[0] & 0x07);
415
416 ubcsp_config.receive_packet->channel = (ubcsp_receive_header[1] & 0x0f);
417
418 length =
419 ((ubcsp_receive_header[1] & 0xf0) >> 4) |
420 (ubcsp_receive_header[2] << 4);
421
422 #if SHOW_PACKET_ERRORS
423 if (ubcsp_config.receive_packet->reliable)
424 {
425 printf (" : %10d Recv SEQ: %d ACK %d\n",
426 GetTickCount () % 100000,
427 receive_seq,
428 receive_ack);
429 }
430 else if (ubcsp_config.receive_packet->channel != 1)
431 {
432 printf (" : %10d Recv ACK %d\n",
433 GetTickCount () % 100000,
434 receive_ack);
435 }
436 #endif
437
438 /* Check for length errors */
439
440 #if UBCSP_CRC
441 if (receive_crc)
442 {
443 /* If this packet had a CRC, then the length of the payload
444 should be 2 less than the received size of the payload */
445
446 if (length + 2 != ubcsp_config.receive_index)
447 {
448 /* Slip Length Error */
449
450 #if SHOW_PACKET_ERRORS
451 printf ("\n######################## Slip Length Error (With CRC) %d,%d\n", length, ubcsp_config.receive_index - 2);
452 #endif
453
454 /* If we have a payload length error, send an ack in return
455 this gets a packet to be resent as quickly as possible */
456
457 ubcsp_config.send_ack = 1;
458 return activity;
459 }
460
461 /* We have a CRC at the end of this packet */
462
463 ubcsp_config.receive_index -= 2;
464
465 /* Calculate the packet CRC */
466
467 crc = 0xffff;
468
469 /* CRC the packet header */
470
471 for (loop = 0; loop < 4; loop ++)
472 {
473 crc = ubcsp_calc_crc (ubcsp_receive_header[loop], crc);
474 }
475
476 /* CRC the packet payload - without the CRC bytes */
477
478 for (loop = 0; loop < ubcsp_config.receive_index; loop ++)
479 {
480 crc = ubcsp_calc_crc (ubcsp_config.receive_packet->payload[loop], crc);
481 }
482
483 /* Reverse the CRC */
484
485 crc = ubcsp_crc_reverse (crc);
486
487 /* Check the CRC is correct */
488
489 if
490 (
491 (((crc & 0xff00) >> 8) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index]) ||
492 ((crc & 0xff) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index + 1])
493 )
494 {
495 #if SHOW_PACKET_ERRORS
496 printf ("\n######################## CRC Error\n");
497 #endif
498
499 /* If we have a packet crc error, send an ack in return
500 this gets a packet to be resent as quickly as possible */
501
502 ubcsp_config.send_ack = 1;
503 return activity;
504 }
505 }
506 else
507 {
508 #endif
509 /* No CRC present, so just check the length of payload with that received */
510
511 if (length != ubcsp_config.receive_index)
512 {
513 /* Slip Length Error */
514
515 #if SHOW_PACKET_ERRORS
516 printf ("\n######################## Slip Length Error (No CRC) %d,%d\n", length, ubcsp_config.receive_index);
517 #endif
518
519 /* If we have a payload length error, send an ack in return
520 this gets a packet to be resent as quickly as possible */
521
522 ubcsp_config.send_ack = 1;
523 return activity;
524 }
525 #if UBCSP_CRC
526 }
527 #endif
528
529 /*** We have a fully formed packet having passed all data integrity checks ***/
530
531 /* Check if we have an ACK for the last packet we sent */
532
533 if (receive_ack != ubcsp_config.sequence_number)
534 {
535 /* Since we only have a window size of 1, if the ACK is not equal to SEQ
536 then the packet was sent */
537
538 if
539 (
540 (ubcsp_config.send_packet) &&
541 (ubcsp_config.send_packet->reliable)
542 )
543 {
544 /* We had sent a reliable packet, so clear this packet
545 Then increament the sequence number for the next packet */
546
547 ubcsp_config.send_packet = 0;
548 ubcsp_config.sequence_number ++;
549 ubcsp_config.delay = 0;
550
551 /* Notify the caller that we have SENT a packet */
552
553 activity |= UBCSP_PACKET_SENT;
554 }
555 }
556
557 /*** Now we can concentrate of the packet we have received ***/
558
559 /* Check for Link Establishment packets */
560
561 if (ubcsp_config.receive_packet->channel == 1)
562 {
563 /* Link Establishment */
564
565 ubcsp_config.delay = 0;
566
567 /* Find which link establishment packet this payload means
568 This could return 5, meaning none */
569
570 switch (ubcsp_which_le_payload (ubcsp_config.receive_packet->payload))
571 {
572 case 0:
573 {
574 /* SYNC Recv'd */
575
576 #if SHOW_LE_STATES
577 printf ("Recv SYNC\n");
578 #endif
579
580 /* If we receive a SYNC, then we respond to it with a SYNC RESP
581 but only if we are not active.
582 If we are active, then we have a PEER RESET */
583
584 if (ubcsp_config.link_establishment_state < ubcsp_le_active)
585 {
586 ubcsp_config.link_establishment_resp = 1;
587 }
588 else
589 {
590 /* Peer reset !!!! */
591
592 #if SHOW_LE_STATES
593 printf ("\n\n\n\n\nPEER RESET\n\n");
594 #endif
595
596 /* Reinitialize the link */
597
598 ubcsp_initialize ();
599
600 /* Tell the host what has happened */
601
602 return UBCSP_PEER_RESET;
603 }
604 break;
605 }
606
607 case 1:
608 {
609 /* SYNC RESP Recv'd */
610
611 #if SHOW_LE_STATES
612 printf ("Recv SYNC RESP\n");
613 #endif
614
615 /* If we receive a SYNC RESP, push us into the initialized state */
616
617 if (ubcsp_config.link_establishment_state < ubcsp_le_initialized)
618 {
619 #if SHOW_LE_STATES
620 printf ("Link Initialized\n");
621 #endif
622 ubcsp_config.link_establishment_state = ubcsp_le_initialized;
623 }
624
625 break;
626 }
627
628 case 2:
629 {
630 /* CONF Recv'd */
631
632 #if SHOW_LE_STATES
633 printf ("Recv CONF\n");
634 #endif
635
636 /* If we receive a CONF, and we are initialized or active
637 then respond with a CONF RESP */
638
639 if (ubcsp_config.link_establishment_state >= ubcsp_le_initialized)
640 {
641 ubcsp_config.link_establishment_resp = 2;
642 }
643
644 break;
645 }
646
647 case 3:
648 {
649 /* CONF RESP Recv'd */
650
651 #if SHOW_LE_STATES
652 printf ("Recv CONF RESP\n");
653 #endif
654
655 /* If we received a CONF RESP, then push us into the active state */
656
657 if (ubcsp_config.link_establishment_state < ubcsp_le_active)
658 {
659 #if SHOW_LE_STATES
660 printf ("Link Active\n");
661 #endif
662
663 ubcsp_config.link_establishment_state = ubcsp_le_active;
664 ubcsp_config.send_size = 0;
665
666 return activity | UBCSP_PACKET_SENT;
667 }
668
669 break;
670 }
671 }
672
673 /* We have finished processing Link Establishment packets */
674 }
675 else if (ubcsp_config.receive_index)
676 {
677 /* We have some payload data we need to process
678 but only if we are active - otherwise, we just ignore it */
679
680 if (ubcsp_config.link_establishment_state == ubcsp_le_active)
681 {
682 if (ubcsp_config.receive_packet->reliable)
683 {
684 /* If the packet we've just received was reliable
685 then send an ACK */
686
687 ubcsp_config.send_ack = 1;
688
689 /* We the sequence number we received is the same as
690 the last ACK we sent, then we have received a packet in sequence */
691
692 if (receive_seq == ubcsp_config.ack_number)
693 {
694 /* Increase the ACK number - which will be sent in the next ACK
695 or normal packet we send */
696
697 ubcsp_config.ack_number ++;
698
699 /* Set the values in the receive_packet structure, so the caller
700 knows how much data we have */
701
702 ubcsp_config.receive_packet->length = length;
703 ubcsp_config.receive_packet = 0;
704
705 /* Tell the caller that we have received a packet, and that it
706 will be ACK'ed */
707
708 activity |= UBCSP_PACKET_RECEIVED | UBCSP_PACKET_ACK;
709 }
710 }
711 else
712 {
713 /* Set the values in the receive_packet structure, so the caller
714 knows how much data we have */
715
716 ubcsp_config.receive_packet->length = length;
717 ubcsp_config.receive_packet = 0;
718
719 /* Tell the caller that we have received a packet */
720
721 activity |= UBCSP_PACKET_RECEIVED;
722 }
723 }
724 }
725
726 /* Just return any activity that occured */
727
728 return activity;
729 }
730
731 /*****************************************************************************/
732 /** **/
733 /** ubcsp_setup_packet **/
734 /** **/
735 /** This function is called to setup a packet to be sent **/
736 /** This allows just a header, or a header and payload to be sent **/
737 /** It also allows the header checksum to be precalcuated **/
738 /** or calculated here **/
739 /** part1 is always 4 bytes **/
740 /** **/
741 /*****************************************************************************/
742
ubcsp_setup_packet(uint8 * part1,uint8 calc,uint8 * part2,uint16 len2)743 static void ubcsp_setup_packet (uint8 *part1, uint8 calc, uint8 *part2, uint16 len2)
744 {
745 /* If we need to calculate the checksum, do that now */
746
747 if (calc)
748 {
749 part1[3] =
750 ~(part1[0] + part1[1] + part1[2]);
751 }
752
753 /* Setup the header send pointer and size so we can clock this out */
754
755 ubcsp_config.send_ptr = part1;
756 ubcsp_config.send_size = 4;
757
758 /* Setup the payload send pointer and size */
759
760 ubcsp_config.next_send_ptr = part2;
761 ubcsp_config.next_send_size = len2;
762
763 #if UBCSP_CRC
764 /* Initialize the crc as required */
765
766 ubcsp_config.send_crc = -1;
767
768 ubcsp_config.need_send_crc = 1;
769 #endif
770 }
771
772 /*****************************************************************************/
773 /** **/
774 /** ubcsp_sent_packet **/
775 /** **/
776 /** Called when we have finished sending a packet **/
777 /** If this packet was unreliable, then notify caller, and clear the data **/
778 /** **/
779 /*****************************************************************************/
780
ubcsp_sent_packet(void)781 static uint8 ubcsp_sent_packet (void)
782 {
783 if (ubcsp_config.send_packet)
784 {
785 if (!ubcsp_config.send_packet->reliable)
786 {
787 /* We had a packet sent that was unreliable */
788
789 /* Forget about this packet */
790
791 ubcsp_config.send_packet = 0;
792
793 /* Notify caller that they can send another one */
794
795 return UBCSP_PACKET_SENT;
796 }
797 }
798
799 /* We didn't have a packet, or it was reliable
800 Must wait for ACK before allowing another packet to be sent */
801
802 return 0;
803 }
804
805 /*****************************************************************************/
806 /** **/
807 /** ubcsp_poll **/
808 /** **/
809 /** This is the main function for ubcsp **/
810 /** It performs a number of tasks **/
811 /** **/
812 /** 1) Send another octet to the UART - escaping as required **/
813 /** 2) Setup the payload to be sent after the header has been sent **/
814 /** 3) Send the CRC for the packet if required **/
815 /** **/
816 /** 4) Calculate the next Link Establishment State **/
817 /** 5) Send a Link Establishment packet **/
818 /** 6) Send a normal packet if available **/
819 /** 7) Send an ACK packet if required **/
820 /** **/
821 /** 8) Receive octets from UART and deslip them as required **/
822 /** 9) Place received octets into receive header or receive payload buffer **/
823 /** 10) Process received packet when SLIP_END is received **/
824 /** **/
825 /** 11) Keep track of ability of caller to delay recalling **/
826 /** **/
827 /*****************************************************************************/
828
ubcsp_poll(uint8 * activity)829 uint8 ubcsp_poll (uint8 *activity)
830 {
831 uint8
832 delay = UBCSP_POLL_TIME_IMMEDIATE;
833
834 uint8
835 value;
836
837 /* Assume no activity to start with */
838
839 *activity = 0;
840
841 /* If we don't have to delay, then send something if we can */
842
843 if (!ubcsp_config.delay)
844 {
845 /* Do we have something we are sending to send */
846
847 if (ubcsp_config.send_size)
848 {
849 /* We have something to send so send it */
850
851 if (ubcsp_config.send_slip_escape)
852 {
853 /* Last time we send a SLIP_ESCAPE octet
854 this time send the second escape code */
855
856 put_uart (ubcsp_config.send_slip_escape);
857
858 ubcsp_config.send_slip_escape = 0;
859 }
860 else
861 {
862 #if UBCSP_CRC
863 /* get the value to send, and calculate CRC as we go */
864
865 value = *ubcsp_config.send_ptr ++;
866
867 ubcsp_config.send_crc = ubcsp_calc_crc (value, ubcsp_config.send_crc);
868
869 /* Output the octet */
870
871 ubcsp_put_slip_uart (value);
872 #else
873 /* Just output the octet*/
874
875 ubcsp_put_slip_uart (*ubcsp_config.send_ptr ++);
876 #endif
877 }
878
879 /* If we did output a SLIP_ESCAPE, then don't process the end of a block */
880
881 if ((!ubcsp_config.send_slip_escape) && ((ubcsp_config.send_size = ubcsp_config.send_size - 1) == 0))
882 {
883 /*** We are at the end of a block - either header or payload ***/
884
885 /* setup the next block */
886
887 ubcsp_config.send_ptr = ubcsp_config.next_send_ptr;
888 ubcsp_config.send_size = ubcsp_config.next_send_size;
889 ubcsp_config.next_send_ptr = 0;
890 ubcsp_config.next_send_size = 0;
891
892 #if UBCSP_CRC
893 /* If we have no successor block
894 then we might need to send the CRC */
895
896 if (!ubcsp_config.send_ptr)
897 {
898 if (ubcsp_config.need_send_crc)
899 {
900 /* reverse the CRC from what we computed along the way */
901
902 ubcsp_config.need_send_crc = 0;
903
904 ubcsp_config.send_crc = ubcsp_crc_reverse (ubcsp_config.send_crc);
905
906 /* Save in the send_crc buffer */
907
908 ubcsp_send_crc[0] = (uint8) (ubcsp_config.send_crc >> 8);
909 ubcsp_send_crc[1] = (uint8) ubcsp_config.send_crc;
910
911 /* Setup to send this buffer */
912
913 ubcsp_config.send_ptr = ubcsp_send_crc;
914 ubcsp_config.send_size = 2;
915 }
916 else
917 {
918 /* We don't need to send the crc
919 either we just have, or this packet doesn't include it */
920
921 /* Output the end of FRAME marker */
922
923 put_uart (SLIP_FRAME);
924
925 /* Check if this is an unreliable packet */
926
927 *activity |= ubcsp_sent_packet ();
928
929 /* We've sent the packet, so don't need to have be called quickly soon */
930
931 delay = UBCSP_POLL_TIME_DELAY;
932 }
933 }
934 #else
935 /* If we have no successor block
936 then we might need to send the CRC */
937
938 if (!ubcsp_config.send_ptr)
939 {
940 /* Output the end of FRAME marker */
941
942 put_uart (SLIP_FRAME);
943
944 /* Check if this is an unreliable packet */
945
946 *activity |= ubcsp_sent_packet ();
947
948 /* We've sent the packet, so don't need to have be called quickly soon */
949
950 delay = UBCSP_POLL_TIME_DELAY;
951 }
952 #endif
953 }
954 }
955 else if (ubcsp_config.link_establishment_packet == ubcsp_le_none)
956 {
957 /* We didn't have something to send
958 AND we have no Link Establishment packet to send */
959
960 if (ubcsp_config.link_establishment_resp & 2)
961 {
962 /* Send the start of FRAME packet */
963
964 put_uart (SLIP_FRAME);
965
966 /* We did require a RESP packet - so setup the send */
967
968 ubcsp_setup_packet ((uint8*) ubcsp_send_le_header, 0, (uint8*) ubcsp_le_buffer[ubcsp_le_conf_resp], 4);
969
970 /* We have now "sent" this packet */
971
972 ubcsp_config.link_establishment_resp = 0;
973 }
974 else if (ubcsp_config.send_packet)
975 {
976 /* There is a packet ready to be sent */
977
978 /* Send the start of FRAME packet */
979
980 put_uart (SLIP_FRAME);
981
982 /* Encode up the packet header using ACK and SEQ numbers */
983
984 ubcsp_send_header[0] =
985 (ubcsp_config.send_packet->reliable << 7) |
986 #if UBCSP_CRC
987 0x40 | /* Always use CRC's */
988 #endif
989 (ubcsp_config.ack_number << 3) |
990 (ubcsp_config.sequence_number);
991
992 /* Encode up the packet header's channel and length */
993 ubcsp_send_header[1] =
994 (ubcsp_config.send_packet->channel & 0x0f) |
995 ((ubcsp_config.send_packet->length << 4) & 0xf0);
996
997 ubcsp_send_header[2] =
998 (ubcsp_config.send_packet->length >> 4) & 0xff;
999
1000 /* Let the ubcsp_setup_packet function calculate the header checksum */
1001
1002 ubcsp_setup_packet ((uint8*) ubcsp_send_header, 1, ubcsp_config.send_packet->payload, ubcsp_config.send_packet->length);
1003
1004 /* Don't need to send an ACK - we just place on in this packet */
1005
1006 ubcsp_config.send_ack = 0;
1007
1008 #if SHOW_PACKET_ERRORS
1009 printf (" : %10d Send %d Ack %d\n",
1010 GetTickCount () % 100000,
1011 ubcsp_config.sequence_number,
1012 ubcsp_config.ack_number);
1013 #endif
1014 }
1015 else if (ubcsp_config.send_ack)
1016 {
1017 /* Send the start of FRAME packet */
1018
1019 put_uart (SLIP_FRAME);
1020
1021 #if SHOW_PACKET_ERRORS
1022 printf (" : %10d Send ACK %d\n",
1023 GetTickCount () % 100000,
1024 ubcsp_config.ack_number);
1025 #endif
1026
1027 /* The ack packet is already computed apart from the first octet */
1028
1029 ubcsp_send_ack_header[0] =
1030 #if UBCSP_CRC
1031 0x40 |
1032 #endif
1033 (ubcsp_config.ack_number << 3);
1034
1035 /* Let the ubcsp_setup_packet function calculate the header checksum */
1036
1037 ubcsp_setup_packet (ubcsp_send_ack_header, 1, 0, 0);
1038
1039 /* We've now sent the ack */
1040
1041 ubcsp_config.send_ack = 0;
1042 }
1043 else
1044 {
1045 /* We didn't have a Link Establishment response packet,
1046 a normal packet or an ACK packet to send */
1047
1048 delay = UBCSP_POLL_TIME_DELAY;
1049 }
1050 }
1051 else
1052 {
1053 #if SHOW_PACKET_ERRORS
1054 // printf (" : %10d Send LE %d\n",
1055 // GetTickCount () % 100000,
1056 // ubcsp_config.link_establishment_packet);
1057 #endif
1058
1059 /* Send A Link Establishment Message */
1060
1061 put_uart (SLIP_FRAME);
1062
1063 /* Send the Link Establishment header followed by the
1064 Link Establishment packet */
1065
1066 ubcsp_setup_packet ((uint8*) ubcsp_send_le_header, 0, (uint8*) ubcsp_le_buffer[ubcsp_config.link_establishment_packet], 4);
1067
1068 /* start sending immediately */
1069
1070 ubcsp_config.delay = 0;
1071
1072 /* workout what the next link establishment packet should be */
1073
1074 ubcsp_config.link_establishment_packet = next_le_packet[ubcsp_config.link_establishment_state + ubcsp_config.link_establishment_resp * 4];
1075
1076 /* We have now delt with any response packet that we needed */
1077
1078 ubcsp_config.link_establishment_resp = 0;
1079
1080 return 0;
1081 }
1082 }
1083
1084 /* We now need to receive any octets from the UART */
1085
1086 while ((ubcsp_config.receive_packet) && (get_uart (&value)))
1087 {
1088 /* If the last octet was SLIP_ESCAPE, then special processing is required */
1089
1090 if (ubcsp_config.receive_slip_escape)
1091 {
1092 /* WARNING - out of range values are not detected !!!
1093 This will probably be caught with the checksum or CRC check */
1094
1095 value = ubcsp_deslip[value - SLIP_ESCAPE_FRAME];
1096
1097 ubcsp_config.receive_slip_escape = 0;
1098 }
1099 else
1100 {
1101 /* Check for the SLIP_FRAME octet - must be start or end of packet */
1102 if (value == SLIP_FRAME)
1103 {
1104 /* If we had a full header then we have a packet */
1105
1106 if (ubcsp_config.receive_index >= 0)
1107 {
1108 /* process the received packet */
1109
1110 *activity |= ubcsp_recevied_packet ();
1111
1112 if (*activity & UBCSP_PACKET_ACK)
1113 {
1114 /* We need to ACK this packet, then don't delay its sending */
1115 ubcsp_config.delay = 0;
1116 }
1117 }
1118
1119 /* Setup to receive the next packet */
1120
1121 ubcsp_config.receive_index = -4;
1122
1123 /* Ok, next octet */
1124
1125 goto finished_receive;
1126 }
1127 else if (value == SLIP_ESCAPE)
1128 {
1129 /* If we receive a SLIP_ESCAPE,
1130 then remember to process the next special octet */
1131
1132 ubcsp_config.receive_slip_escape = 1;
1133
1134 goto finished_receive;
1135 }
1136 }
1137
1138 if (ubcsp_config.receive_index < 0)
1139 {
1140 /* We are still receiving the header */
1141
1142 ubcsp_receive_header[ubcsp_config.receive_index + 4] = value;
1143
1144 ubcsp_config.receive_index ++;
1145 }
1146 else if (ubcsp_config.receive_index < ubcsp_config.receive_packet->length)
1147 {
1148 /* We are receiving the payload */
1149 /* We might stop comming here if we are receiving a
1150 packet which is longer than the receive_packet->length
1151 given by the host */
1152
1153 ubcsp_config.receive_packet->payload[ubcsp_config.receive_index] = value;
1154
1155 ubcsp_config.receive_index ++;
1156 }
1157
1158 finished_receive:
1159 {
1160 }
1161 }
1162
1163 if (ubcsp_config.delay > 0)
1164 {
1165 /* We were delayed so delay some more
1166 this could be cancelled if we received something */
1167
1168 ubcsp_config.delay --;
1169 }
1170 else
1171 {
1172 /* We had no delay, so use the delay we just decided to us */
1173
1174 ubcsp_config.delay = delay;
1175 }
1176
1177 /* Report the current delay to the user */
1178
1179 return ubcsp_config.delay;
1180 }
1181