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 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 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 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 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 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 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 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 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 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 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 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