3 * BlueZ - Bluetooth protocol stack for Linux
\r
5 * Copyright (C) 2000-2005 CSR Ltd.
\r
8 * Permission is hereby granted, free of charge, to any person obtaining
\r
9 * a copy of this software and associated documentation files (the
\r
10 * "Software"), to deal in the Software without restriction, including
\r
11 * without limitation the rights to use, copy, modify, merge, publish,
\r
12 * distribute, sublicense, and/or sell copies of the Software, and to
\r
13 * permit persons to whom the Software is furnished to do so, subject to
\r
14 * the following conditions:
\r
16 * The above copyright notice and this permission notice shall be included
\r
17 * in all copies or substantial portions of the Software.
\r
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
\r
22 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
\r
23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
\r
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
\r
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
29 #ifdef HAVE_CONFIG_H
\r
33 /*****************************************************************************/
\r
34 /*****************************************************************************/
\r
35 /*****************************************************************************/
\r
39 /** MicroBCSP - a very low cost implementation of the BCSP protocol **/
\r
41 /*****************************************************************************/
\r
45 #if SHOW_PACKET_ERRORS || SHOW_LE_STATES
\r
47 #include <windows.h>
\r
50 static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc);
\r
51 static uint16 ubcsp_crc_reverse (uint16);
\r
53 /*****************************************************************************/
\r
55 /** Constant Data - ROM **/
\r
57 /*****************************************************************************/
\r
59 /* This is the storage for the link establishment messages */
\r
61 static const uint8 ubcsp_le_buffer[4][4] =
\r
63 { 0xDA, 0xDC, 0xED, 0xED },
\r
64 { 0xAC, 0xAF, 0xEF, 0xEE },
\r
65 { 0xAD, 0xEF, 0xAC, 0xED },
\r
66 { 0xDE, 0xAD, 0xD0, 0xD0 },
\r
69 /* These are the link establishment headers */
\r
70 /* The two version are for the CRC and non-CRC varients */
\r
73 static const uint8 ubcsp_send_le_header[4] =
\r
75 0x40, 0x41, 0x00, 0x7E
\r
78 static const uint8 ubcsp_send_le_header[4] =
\r
80 0x00, 0x41, 0x00, 0xBE
\r
84 /*****************************************************************************/
\r
86 /** Static Data - RAM **/
\r
88 /*****************************************************************************/
\r
90 /* This is the storage for all state data for ubcsp */
\r
92 static struct ubcsp_configuration ubcsp_config;
\r
94 /* This is the ACK packet header - this will be overwritten when
\r
95 we create an ack packet */
\r
97 static uint8 ubcsp_send_ack_header[4] =
\r
99 0x00, 0x00, 0x00, 0x00
\r
102 /* This is the deslip lookup table */
\r
104 static const uint8 ubcsp_deslip[2] =
\r
106 SLIP_FRAME, SLIP_ESCAPE,
\r
109 /* This is a state machine table for link establishment */
\r
111 static uint8 next_le_packet[16] =
\r
113 ubcsp_le_sync, // uninit
\r
114 ubcsp_le_conf, // init
\r
115 ubcsp_le_none, // active
\r
117 ubcsp_le_sync_resp, // sync_resp
\r
118 ubcsp_le_sync_resp,
\r
121 ubcsp_le_none, // conf_resp
\r
122 ubcsp_le_conf_resp,
\r
123 ubcsp_le_conf_resp,
\r
127 /* This is the storage required for building send and crc data */
\r
129 static uint8 ubcsp_send_header[4];
\r
130 static uint8 ubcsp_send_crc[2];
\r
132 /* This is where the receive header is stored before the payload arrives */
\r
134 static uint8 ubcsp_receive_header[4];
\r
136 /*****************************************************************************/
\r
138 /** Code - ROM or RAM **/
\r
140 /*****************************************************************************/
\r
142 /*****************************************************************************/
\r
144 /** ubcsp_initialize **/
\r
146 /** This initializes the state of the ubcsp engine to a known values **/
\r
148 /*****************************************************************************/
\r
150 void ubcsp_initialize (void)
\r
152 ubcsp_config.ack_number = 0;
\r
153 ubcsp_config.sequence_number = 0;
\r
154 ubcsp_config.send_ptr = 0;
\r
155 ubcsp_config.send_size = 0;
\r
156 ubcsp_config.receive_index = -4;
\r
158 ubcsp_config.delay = 0;
\r
161 printf ("Hello Link Uninitialized\n");
\r
164 ubcsp_config.link_establishment_state = ubcsp_le_uninitialized;
\r
165 ubcsp_config.link_establishment_packet = ubcsp_le_sync;
\r
168 /*****************************************************************************/
\r
170 /** ubcsp_send_packet **/
\r
172 /** This sends a packet structure for sending to the ubcsp engine **/
\r
173 /** This can only be called when the activity indication from ubcsp_poll **/
\r
174 /** indicates that a packet can be sent with UBCSP_PACKET_SENT **/
\r
176 /*****************************************************************************/
\r
178 void ubcsp_send_packet (struct ubcsp_packet *send_packet)
\r
180 /* Initialize the send data to the packet we want to send */
\r
182 ubcsp_config.send_packet = send_packet;
\r
184 /* we cannot send the packet at the moment
\r
185 when we can at the moment, just set things to 0 */
\r
187 ubcsp_config.send_size = 0;
\r
188 ubcsp_config.send_ptr = 0;
\r
191 /*****************************************************************************/
\r
193 /** ubcsp_receive_packet **/
\r
195 /** This sends a packet structure for receiving to the ubcsp engine **/
\r
196 /** This can only be called when the activity indication from ubcsp_poll **/
\r
197 /** indicates that a packet can be sent with UBCSP_PACKET_RECEIVED **/
\r
199 /*****************************************************************************/
\r
201 void ubcsp_receive_packet (struct ubcsp_packet *receive_packet)
\r
203 /* Initialize the receive data to the packet we want to receive */
\r
205 ubcsp_config.receive_packet = receive_packet;
\r
207 /* setup to receive the header first */
\r
209 ubcsp_config.receive_index = -4;
\r
212 /*****************************************************************************/
\r
214 /** ubcsp_calc_crc **/
\r
216 /** Takes the next 8 bit value ch, and updates the crc with this value **/
\r
218 /*****************************************************************************/
\r
223 static uint16 ubcsp_calc_crc (uint8 ch, uint16 crc)
\r
225 /* Calculate the CRC using the above 16 entry lookup table */
\r
227 static const uint16 crc_table[] =
\r
229 0x0000, 0x1081, 0x2102, 0x3183,
\r
230 0x4204, 0x5285, 0x6306, 0x7387,
\r
231 0x8408, 0x9489, 0xa50a, 0xb58b,
\r
232 0xc60c, 0xd68d, 0xe70e, 0xf78f
\r
235 /* Do this four bits at a time - more code, less space */
\r
237 crc = (crc >> 4) ^ crc_table[(crc ^ ch) & 0x000f];
\r
238 crc = (crc >> 4) ^ crc_table[(crc ^ (ch >> 4)) & 0x000f];
\r
243 /*****************************************************************************/
\r
245 /** ubcsp_crc_reverse **/
\r
247 /** Reserves the bits in crc and returns the new value **/
\r
249 /*****************************************************************************/
\r
251 static uint16 ubcsp_crc_reverse (uint16 crc)
\r
257 /* Reserse the bits to compute the actual CRC value */
\r
259 for (b = 0, rev=0; b < 16; b++)
\r
271 /*****************************************************************************/
\r
273 /** ubcsp_put_slip_uart **/
\r
275 /** Outputs a single octet to the uart **/
\r
276 /** If the octet needs to be escaped, then output the escape value **/
\r
277 /** and then store the second octet to be output later **/
\r
279 /*****************************************************************************/
\r
281 static void ubcsp_put_slip_uart (uint8 ch)
\r
283 /* output a single UART octet */
\r
285 /* If it needs to be escaped, then output the escape octet
\r
286 and set the send_slip_escape so that the next time we
\r
287 output the second octet for the escape correctly.
\r
288 This is done right at the top of ubcsp_poll */
\r
290 if (ch == SLIP_FRAME)
\r
292 put_uart (SLIP_ESCAPE);
\r
293 ubcsp_config.send_slip_escape = SLIP_ESCAPE_FRAME;
\r
295 else if (ch == SLIP_ESCAPE)
\r
297 put_uart (SLIP_ESCAPE);
\r
298 ubcsp_config.send_slip_escape = SLIP_ESCAPE_ESCAPE;
\r
302 /* Not escaped, so just output octet */
\r
308 /*****************************************************************************/
\r
310 /** ubcsp_which_le_payload **/
\r
312 /** Check the payload of this packet, and determine which of the four **/
\r
313 /** link establishment packets this was. **/
\r
314 /** Can return 5 if it is not a valid link establishment packet **/
\r
316 /*****************************************************************************/
\r
318 static uint32 ubcsp_which_le_payload (const uint8 *payload)
\r
324 /* Search through the various link establishment payloads to find
\r
325 which one we have received */
\r
327 for (loop = 0; loop < 4; loop ++)
\r
329 for (octet = 0; octet < 4; octet ++)
\r
331 if (payload[octet] != ubcsp_le_buffer[loop][octet])
\r
333 /* Bad match, just to loop again */
\r
334 goto bad_match_loop;
\r
338 /* All the octets matched, return the value */
\r
342 /* Jumps out of octet loop if we got a bad match */
\r
347 /* Non of the link establishment payloads matched - return invalid value */
\r
352 /*****************************************************************************/
\r
354 /** ubcsp_recevied_packet **/
\r
356 /** This function is called when we have a SLIP END octet and a full **/
\r
357 /** packet header and possibly data in the receive packet **/
\r
359 /*****************************************************************************/
\r
361 static uint8 ubcsp_recevied_packet (void)
\r
380 /* Keep track of what activity this received packet will cause */
\r
384 /*** Do all error checks that we can ***/
\r
386 /* First check the header checksum */
\r
388 if (((ubcsp_receive_header[0] + ubcsp_receive_header[1] + ubcsp_receive_header[2] + ubcsp_receive_header[3]) & 0xff) != 0xff)
\r
390 /* Header Checksum Error */
\r
392 #if SHOW_PACKET_ERRORS
\r
393 printf ("\n######################## Header Checksum Error %02X %02X %02X %02X\n",
\r
394 ubcsp_receive_header[0],
\r
395 ubcsp_receive_header[1],
\r
396 ubcsp_receive_header[2],
\r
397 ubcsp_receive_header[3]);
\r
400 /* If we have a header checksum error, send an ack in return
\r
401 this gets a packet to be resent as quickly as possible */
\r
403 ubcsp_config.send_ack = 1;
\r
408 /* Decode the received packets header */
\r
410 ubcsp_config.receive_packet->reliable = (ubcsp_receive_header[0] & 0x80) >> 7;
\r
412 receive_crc = (ubcsp_receive_header[0] & 0x40) >> 6;
\r
413 receive_ack = (ubcsp_receive_header[0] & 0x38) >> 3;
\r
414 receive_seq = (ubcsp_receive_header[0] & 0x07);
\r
416 ubcsp_config.receive_packet->channel = (ubcsp_receive_header[1] & 0x0f);
\r
419 ((ubcsp_receive_header[1] & 0xf0) >> 4) |
\r
420 (ubcsp_receive_header[2] << 4);
\r
422 #if SHOW_PACKET_ERRORS
\r
423 if (ubcsp_config.receive_packet->reliable)
\r
425 printf (" : %10d Recv SEQ: %d ACK %d\n",
\r
426 GetTickCount () % 100000,
\r
430 else if (ubcsp_config.receive_packet->channel != 1)
\r
432 printf (" : %10d Recv ACK %d\n",
\r
433 GetTickCount () % 100000,
\r
438 /* Check for length errors */
\r
443 /* If this packet had a CRC, then the length of the payload
\r
444 should be 2 less than the received size of the payload */
\r
446 if (length + 2 != ubcsp_config.receive_index)
\r
448 /* Slip Length Error */
\r
450 #if SHOW_PACKET_ERRORS
\r
451 printf ("\n######################## Slip Length Error (With CRC) %d,%d\n", length, ubcsp_config.receive_index - 2);
\r
454 /* If we have a payload length error, send an ack in return
\r
455 this gets a packet to be resent as quickly as possible */
\r
457 ubcsp_config.send_ack = 1;
\r
461 /* We have a CRC at the end of this packet */
\r
463 ubcsp_config.receive_index -= 2;
\r
465 /* Calculate the packet CRC */
\r
469 /* CRC the packet header */
\r
471 for (loop = 0; loop < 4; loop ++)
\r
473 crc = ubcsp_calc_crc (ubcsp_receive_header[loop], crc);
\r
476 /* CRC the packet payload - without the CRC bytes */
\r
478 for (loop = 0; loop < ubcsp_config.receive_index; loop ++)
\r
480 crc = ubcsp_calc_crc (ubcsp_config.receive_packet->payload[loop], crc);
\r
483 /* Reverse the CRC */
\r
485 crc = ubcsp_crc_reverse (crc);
\r
487 /* Check the CRC is correct */
\r
491 (((crc & 0xff00) >> 8) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index]) ||
\r
492 ((crc & 0xff) != ubcsp_config.receive_packet->payload[ubcsp_config.receive_index + 1])
\r
495 #if SHOW_PACKET_ERRORS
\r
496 printf ("\n######################## CRC Error\n");
\r
499 /* If we have a packet crc error, send an ack in return
\r
500 this gets a packet to be resent as quickly as possible */
\r
502 ubcsp_config.send_ack = 1;
\r
509 /* No CRC present, so just check the length of payload with that received */
\r
511 if (length != ubcsp_config.receive_index)
\r
513 /* Slip Length Error */
\r
515 #if SHOW_PACKET_ERRORS
\r
516 printf ("\n######################## Slip Length Error (No CRC) %d,%d\n", length, ubcsp_config.receive_index);
\r
519 /* If we have a payload length error, send an ack in return
\r
520 this gets a packet to be resent as quickly as possible */
\r
522 ubcsp_config.send_ack = 1;
\r
529 /*** We have a fully formed packet having passed all data integrity checks ***/
\r
531 /* Check if we have an ACK for the last packet we sent */
\r
533 if (receive_ack != ubcsp_config.sequence_number)
\r
535 /* Since we only have a window size of 1, if the ACK is not equal to SEQ
\r
536 then the packet was sent */
\r
540 (ubcsp_config.send_packet) &&
\r
541 (ubcsp_config.send_packet->reliable)
\r
544 /* We had sent a reliable packet, so clear this packet
\r
545 Then increament the sequence number for the next packet */
\r
547 ubcsp_config.send_packet = 0;
\r
548 ubcsp_config.sequence_number ++;
\r
549 ubcsp_config.delay = 0;
\r
551 /* Notify the caller that we have SENT a packet */
\r
553 activity |= UBCSP_PACKET_SENT;
\r
557 /*** Now we can concentrate of the packet we have received ***/
\r
559 /* Check for Link Establishment packets */
\r
561 if (ubcsp_config.receive_packet->channel == 1)
\r
563 /* Link Establishment */
\r
565 ubcsp_config.delay = 0;
\r
567 /* Find which link establishment packet this payload means
\r
568 This could return 5, meaning none */
\r
570 switch (ubcsp_which_le_payload (ubcsp_config.receive_packet->payload))
\r
577 printf ("Recv SYNC\n");
\r
580 /* If we receive a SYNC, then we respond to it with a SYNC RESP
\r
581 but only if we are not active.
\r
582 If we are active, then we have a PEER RESET */
\r
584 if (ubcsp_config.link_establishment_state < ubcsp_le_active)
\r
586 ubcsp_config.link_establishment_resp = 1;
\r
590 /* Peer reset !!!! */
\r
593 printf ("\n\n\n\n\nPEER RESET\n\n");
\r
596 /* Reinitialize the link */
\r
598 ubcsp_initialize ();
\r
600 /* Tell the host what has happened */
\r
602 return UBCSP_PEER_RESET;
\r
609 /* SYNC RESP Recv'd */
\r
612 printf ("Recv SYNC RESP\n");
\r
615 /* If we receive a SYNC RESP, push us into the initialized state */
\r
617 if (ubcsp_config.link_establishment_state < ubcsp_le_initialized)
\r
620 printf ("Link Initialized\n");
\r
622 ubcsp_config.link_establishment_state = ubcsp_le_initialized;
\r
633 printf ("Recv CONF\n");
\r
636 /* If we receive a CONF, and we are initialized or active
\r
637 then respond with a CONF RESP */
\r
639 if (ubcsp_config.link_establishment_state >= ubcsp_le_initialized)
\r
641 ubcsp_config.link_establishment_resp = 2;
\r
649 /* CONF RESP Recv'd */
\r
652 printf ("Recv CONF RESP\n");
\r
655 /* If we received a CONF RESP, then push us into the active state */
\r
657 if (ubcsp_config.link_establishment_state < ubcsp_le_active)
\r
660 printf ("Link Active\n");
\r
663 ubcsp_config.link_establishment_state = ubcsp_le_active;
\r
664 ubcsp_config.send_size = 0;
\r
666 return activity | UBCSP_PACKET_SENT;
\r
673 /* We have finished processing Link Establishment packets */
\r
675 else if (ubcsp_config.receive_index)
\r
677 /* We have some payload data we need to process
\r
678 but only if we are active - otherwise, we just ignore it */
\r
680 if (ubcsp_config.link_establishment_state == ubcsp_le_active)
\r
682 if (ubcsp_config.receive_packet->reliable)
\r
684 /* If the packet we've just received was reliable
\r
685 then send an ACK */
\r
687 ubcsp_config.send_ack = 1;
\r
689 /* We the sequence number we received is the same as
\r
690 the last ACK we sent, then we have received a packet in sequence */
\r
692 if (receive_seq == ubcsp_config.ack_number)
\r
694 /* Increase the ACK number - which will be sent in the next ACK
\r
695 or normal packet we send */
\r
697 ubcsp_config.ack_number ++;
\r
699 /* Set the values in the receive_packet structure, so the caller
\r
700 knows how much data we have */
\r
702 ubcsp_config.receive_packet->length = length;
\r
703 ubcsp_config.receive_packet = 0;
\r
705 /* Tell the caller that we have received a packet, and that it
\r
708 activity |= UBCSP_PACKET_RECEIVED | UBCSP_PACKET_ACK;
\r
713 /* Set the values in the receive_packet structure, so the caller
\r
714 knows how much data we have */
\r
716 ubcsp_config.receive_packet->length = length;
\r
717 ubcsp_config.receive_packet = 0;
\r
719 /* Tell the caller that we have received a packet */
\r
721 activity |= UBCSP_PACKET_RECEIVED;
\r
726 /* Just return any activity that occurred */
731 /*****************************************************************************/
\r
733 /** ubcsp_setup_packet **/
\r
735 /** This function is called to setup a packet to be sent **/
\r
736 /** This allows just a header, or a header and payload to be sent **/
\r
737 /** It also allows the header checksum to be precalcuated **/
\r
738 /** or calculated here **/
\r
739 /** part1 is always 4 bytes **/
\r
741 /*****************************************************************************/
\r
743 static void ubcsp_setup_packet (uint8 *part1, uint8 calc, uint8 *part2, uint16 len2)
\r
745 /* If we need to calculate the checksum, do that now */
\r
750 ~(part1[0] + part1[1] + part1[2]);
\r
753 /* Setup the header send pointer and size so we can clock this out */
\r
755 ubcsp_config.send_ptr = part1;
\r
756 ubcsp_config.send_size = 4;
\r
758 /* Setup the payload send pointer and size */
\r
760 ubcsp_config.next_send_ptr = part2;
\r
761 ubcsp_config.next_send_size = len2;
\r
764 /* Initialize the crc as required */
\r
766 ubcsp_config.send_crc = -1;
\r
768 ubcsp_config.need_send_crc = 1;
\r
772 /*****************************************************************************/
\r
774 /** ubcsp_sent_packet **/
\r
776 /** Called when we have finished sending a packet **/
\r
777 /** If this packet was unreliable, then notify caller, and clear the data **/
\r
779 /*****************************************************************************/
\r
781 static uint8 ubcsp_sent_packet (void)
\r
783 if (ubcsp_config.send_packet)
\r
785 if (!ubcsp_config.send_packet->reliable)
\r
787 /* We had a packet sent that was unreliable */
\r
789 /* Forget about this packet */
\r
791 ubcsp_config.send_packet = 0;
\r
793 /* Notify caller that they can send another one */
\r
795 return UBCSP_PACKET_SENT;
\r
799 /* We didn't have a packet, or it was reliable
\r
800 Must wait for ACK before allowing another packet to be sent */
\r
805 /*****************************************************************************/
\r
809 /** This is the main function for ubcsp **/
\r
810 /** It performs a number of tasks **/
\r
812 /** 1) Send another octet to the UART - escaping as required **/
\r
813 /** 2) Setup the payload to be sent after the header has been sent **/
\r
814 /** 3) Send the CRC for the packet if required **/
\r
816 /** 4) Calculate the next Link Establishment State **/
\r
817 /** 5) Send a Link Establishment packet **/
\r
818 /** 6) Send a normal packet if available **/
\r
819 /** 7) Send an ACK packet if required **/
\r
821 /** 8) Receive octets from UART and deslip them as required **/
\r
822 /** 9) Place received octets into receive header or receive payload buffer **/
\r
823 /** 10) Process received packet when SLIP_END is received **/
\r
825 /** 11) Keep track of ability of caller to delay recalling **/
\r
827 /*****************************************************************************/
\r
829 uint8 ubcsp_poll (uint8 *activity)
\r
832 delay = UBCSP_POLL_TIME_IMMEDIATE;
\r
837 /* Assume no activity to start with */
\r
841 /* If we don't have to delay, then send something if we can */
\r
843 if (!ubcsp_config.delay)
\r
845 /* Do we have something we are sending to send */
\r
847 if (ubcsp_config.send_size)
\r
849 /* We have something to send so send it */
\r
851 if (ubcsp_config.send_slip_escape)
\r
853 /* Last time we send a SLIP_ESCAPE octet
\r
854 this time send the second escape code */
\r
856 put_uart (ubcsp_config.send_slip_escape);
\r
858 ubcsp_config.send_slip_escape = 0;
\r
863 /* get the value to send, and calculate CRC as we go */
\r
865 value = *ubcsp_config.send_ptr ++;
\r
867 ubcsp_config.send_crc = ubcsp_calc_crc (value, ubcsp_config.send_crc);
\r
869 /* Output the octet */
\r
871 ubcsp_put_slip_uart (value);
\r
873 /* Just output the octet*/
\r
875 ubcsp_put_slip_uart (*ubcsp_config.send_ptr ++);
\r
879 /* If we did output a SLIP_ESCAPE, then don't process the end of a block */
\r
881 if ((!ubcsp_config.send_slip_escape) && ((ubcsp_config.send_size = ubcsp_config.send_size - 1) == 0))
\r
883 /*** We are at the end of a block - either header or payload ***/
\r
885 /* setup the next block */
\r
887 ubcsp_config.send_ptr = ubcsp_config.next_send_ptr;
\r
888 ubcsp_config.send_size = ubcsp_config.next_send_size;
\r
889 ubcsp_config.next_send_ptr = 0;
\r
890 ubcsp_config.next_send_size = 0;
\r
893 /* If we have no successor block
\r
894 then we might need to send the CRC */
\r
896 if (!ubcsp_config.send_ptr)
\r
898 if (ubcsp_config.need_send_crc)
\r
900 /* reverse the CRC from what we computed along the way */
\r
902 ubcsp_config.need_send_crc = 0;
\r
904 ubcsp_config.send_crc = ubcsp_crc_reverse (ubcsp_config.send_crc);
\r
906 /* Save in the send_crc buffer */
\r
908 ubcsp_send_crc[0] = (uint8) (ubcsp_config.send_crc >> 8);
\r
909 ubcsp_send_crc[1] = (uint8) ubcsp_config.send_crc;
\r
911 /* Setup to send this buffer */
\r
913 ubcsp_config.send_ptr = ubcsp_send_crc;
\r
914 ubcsp_config.send_size = 2;
\r
918 /* We don't need to send the crc
\r
919 either we just have, or this packet doesn't include it */
\r
921 /* Output the end of FRAME marker */
\r
923 put_uart (SLIP_FRAME);
\r
925 /* Check if this is an unreliable packet */
\r
927 *activity |= ubcsp_sent_packet ();
\r
929 /* We've sent the packet, so don't need to have be called quickly soon */
\r
931 delay = UBCSP_POLL_TIME_DELAY;
\r
935 /* If we have no successor block
\r
936 then we might need to send the CRC */
\r
938 if (!ubcsp_config.send_ptr)
\r
940 /* Output the end of FRAME marker */
\r
942 put_uart (SLIP_FRAME);
\r
944 /* Check if this is an unreliable packet */
\r
946 *activity |= ubcsp_sent_packet ();
\r
948 /* We've sent the packet, so don't need to have be called quickly soon */
\r
950 delay = UBCSP_POLL_TIME_DELAY;
\r
955 else if (ubcsp_config.link_establishment_packet == ubcsp_le_none)
\r
957 /* We didn't have something to send
\r
958 AND we have no Link Establishment packet to send */
\r
960 if (ubcsp_config.link_establishment_resp & 2)
\r
962 /* Send the start of FRAME packet */
\r
964 put_uart (SLIP_FRAME);
\r
966 /* We did require a RESP packet - so setup the send */
\r
968 ubcsp_setup_packet ((uint8*) ubcsp_send_le_header, 0, (uint8*) ubcsp_le_buffer[ubcsp_le_conf_resp], 4);
\r
970 /* We have now "sent" this packet */
\r
972 ubcsp_config.link_establishment_resp = 0;
\r
974 else if (ubcsp_config.send_packet)
\r
976 /* There is a packet ready to be sent */
\r
978 /* Send the start of FRAME packet */
\r
980 put_uart (SLIP_FRAME);
\r
982 /* Encode up the packet header using ACK and SEQ numbers */
\r
984 ubcsp_send_header[0] =
\r
985 (ubcsp_config.send_packet->reliable << 7) |
\r
987 0x40 | /* Always use CRC's */
\r
989 (ubcsp_config.ack_number << 3) |
\r
990 (ubcsp_config.sequence_number);
\r
992 /* Encode up the packet header's channel and length */
\r
993 ubcsp_send_header[1] =
\r
994 (ubcsp_config.send_packet->channel & 0x0f) |
\r
995 ((ubcsp_config.send_packet->length << 4) & 0xf0);
\r
997 ubcsp_send_header[2] =
\r
998 (ubcsp_config.send_packet->length >> 4) & 0xff;
\r
1000 /* Let the ubcsp_setup_packet function calculate the header checksum */
\r
1002 ubcsp_setup_packet ((uint8*) ubcsp_send_header, 1, ubcsp_config.send_packet->payload, ubcsp_config.send_packet->length);
\r
1004 /* Don't need to send an ACK - we just place on in this packet */
\r
1006 ubcsp_config.send_ack = 0;
\r
1008 #if SHOW_PACKET_ERRORS
\r
1009 printf (" : %10d Send %d Ack %d\n",
\r
1010 GetTickCount () % 100000,
\r
1011 ubcsp_config.sequence_number,
\r
1012 ubcsp_config.ack_number);
\r
1015 else if (ubcsp_config.send_ack)
\r
1017 /* Send the start of FRAME packet */
\r
1019 put_uart (SLIP_FRAME);
\r
1021 #if SHOW_PACKET_ERRORS
\r
1022 printf (" : %10d Send ACK %d\n",
\r
1023 GetTickCount () % 100000,
\r
1024 ubcsp_config.ack_number);
\r
1027 /* The ack packet is already computed apart from the first octet */
\r
1029 ubcsp_send_ack_header[0] =
\r
1033 (ubcsp_config.ack_number << 3);
\r
1035 /* Let the ubcsp_setup_packet function calculate the header checksum */
\r
1037 ubcsp_setup_packet (ubcsp_send_ack_header, 1, 0, 0);
\r
1039 /* We've now sent the ack */
\r
1041 ubcsp_config.send_ack = 0;
\r
1045 /* We didn't have a Link Establishment response packet,
\r
1046 a normal packet or an ACK packet to send */
\r
1048 delay = UBCSP_POLL_TIME_DELAY;
\r
1053 #if SHOW_PACKET_ERRORS
\r
1054 // printf (" : %10d Send LE %d\n",
\r
1055 // GetTickCount () % 100000,
\r
1056 // ubcsp_config.link_establishment_packet);
\r
1059 /* Send A Link Establishment Message */
\r
1061 put_uart (SLIP_FRAME);
\r
1063 /* Send the Link Establishment header followed by the
\r
1064 Link Establishment packet */
\r
1066 ubcsp_setup_packet ((uint8*) ubcsp_send_le_header, 0, (uint8*) ubcsp_le_buffer[ubcsp_config.link_establishment_packet], 4);
\r
1068 /* start sending immediately */
\r
1070 ubcsp_config.delay = 0;
\r
1072 /* workout what the next link establishment packet should be */
\r
1074 ubcsp_config.link_establishment_packet = next_le_packet[ubcsp_config.link_establishment_state + ubcsp_config.link_establishment_resp * 4];
\r
1076 /* We have now delt with any response packet that we needed */
\r
1078 ubcsp_config.link_establishment_resp = 0;
\r
1084 /* We now need to receive any octets from the UART */
\r
1086 while ((ubcsp_config.receive_packet) && (get_uart (&value)))
\r
1088 /* If the last octet was SLIP_ESCAPE, then special processing is required */
\r
1090 if (ubcsp_config.receive_slip_escape)
\r
1092 /* WARNING - out of range values are not detected !!!
\r
1093 This will probably be caught with the checksum or CRC check */
\r
1095 value = ubcsp_deslip[value - SLIP_ESCAPE_FRAME];
\r
1097 ubcsp_config.receive_slip_escape = 0;
\r
1101 /* Check for the SLIP_FRAME octet - must be start or end of packet */
\r
1102 if (value == SLIP_FRAME)
\r
1104 /* If we had a full header then we have a packet */
\r
1106 if (ubcsp_config.receive_index >= 0)
\r
1108 /* process the received packet */
\r
1110 *activity |= ubcsp_recevied_packet ();
\r
1112 if (*activity & UBCSP_PACKET_ACK)
\r
1114 /* We need to ACK this packet, then don't delay its sending */
\r
1115 ubcsp_config.delay = 0;
\r
1119 /* Setup to receive the next packet */
\r
1121 ubcsp_config.receive_index = -4;
\r
1123 /* Ok, next octet */
\r
1125 goto finished_receive;
\r
1127 else if (value == SLIP_ESCAPE)
\r
1129 /* If we receive a SLIP_ESCAPE,
\r
1130 then remember to process the next special octet */
\r
1132 ubcsp_config.receive_slip_escape = 1;
\r
1134 goto finished_receive;
\r
1138 if (ubcsp_config.receive_index < 0)
\r
1140 /* We are still receiving the header */
\r
1142 ubcsp_receive_header[ubcsp_config.receive_index + 4] = value;
\r
1144 ubcsp_config.receive_index ++;
\r
1146 else if (ubcsp_config.receive_index < ubcsp_config.receive_packet->length)
1148 /* We are receiving the payload */
1149 /* We might stop coming here if we are receiving a
1150 packet which is longer than the receive_packet->length
1151 given by the host */
1153 ubcsp_config.receive_packet->payload[ubcsp_config.receive_index] = value;
\r
1155 ubcsp_config.receive_index ++;
\r
1163 if (ubcsp_config.delay > 0)
\r
1165 /* We were delayed so delay some more
\r
1166 this could be cancelled if we received something */
\r
1168 ubcsp_config.delay --;
\r
1172 /* We had no delay, so use the delay we just decided to us */
\r
1174 ubcsp_config.delay = delay;
\r
1177 /* Report the current delay to the user */
\r
1179 return ubcsp_config.delay;
\r