home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume2 / boss-sparc / part03 / packet.c < prev   
Encoding:
C/C++ Source or Header  |  1990-10-23  |  6.3 KB  |  229 lines

  1. /************************************************************************/
  2. /*    Copyright 1990 by Chuck Musciano and Harris Corporation        */
  3. /*                                    */
  4. /*    Permission to use, copy, modify, and distribute this software    */
  5. /*    and its documentation for any purpose and without fee is    */
  6. /*    hereby granted, provided that the above copyright notice    */
  7. /*    appear in all copies and that both that copyright notice and    */
  8. /*    this permission notice appear in supporting documentation, and    */
  9. /*    that the name of Chuck Musciano and Harris Corporation not be    */
  10. /*    used in advertising or publicity pertaining to distribution    */
  11. /*    of the software without specific, written prior permission.    */
  12. /*    Chuck Musciano and Harris Corporation make no representations    */
  13. /*    about the suitability of this software for any purpose.  It is    */
  14. /*    provided "as is" without express or implied warranty.        */
  15. /*                                    */
  16. /*    This code contains data and information that is proprietary    */
  17. /*    to Casio Corporation.  You may be subject to legal action if    */
  18. /*    this information is released without explicit permission from    */
  19. /*    Casio.                                */
  20. /************************************************************************/
  21.  
  22. /************************************************************************/
  23. /*                                    */
  24. /*    packet.c    handle sending and receiving raw packets    */
  25. /*                                    */
  26. /************************************************************************/
  27.  
  28. #include    "manifest.h"
  29. #include    "casio.h"
  30.  
  31. PRIVATE    int    session_open = FALSE;
  32. PRIVATE    char    hex[] = "0123456789ABCDEF";
  33.  
  34. /************************************************************************/
  35. PRIVATE    int    read_byte(b, len)
  36.  
  37. byte    *b;
  38. int    len;
  39.  
  40. {    char    buf[1024], *v1, *v2, *p, *index();
  41.  
  42.     if (read_casio(buf, 2 * len, 1000) == 2 * len) {
  43.        for (p = buf; len > 0; len--, p += 2, b++)
  44.           if ((v1 = index(hex, *p)) && (v2 = index(hex, *(p + 1))))
  45.              *b = ((v1 - hex) << 4) + (v2 - hex);
  46.           else {
  47.              error("Invalid Hex-ASCII byte from BOSS: %c%c (%02x%02x)", *p, *(p + 1), *p, *(p + 1));
  48.              return(FALSE);
  49.              }
  50.        return(TRUE);
  51.        }
  52.     else
  53.        error("error reading %d byte%s from BOSS", len, (len == 1)? "" : "s");
  54.     return(FALSE);
  55. }
  56.  
  57. /************************************************************************/
  58. EXPORT    int    start_session()
  59.  
  60. {    byte    b;
  61.     int    i;
  62.  
  63.     if (session_open)
  64.        return(TRUE);
  65.     if (!flush_casio())
  66.        return(FALSE);
  67.     if (!disable_flow_control())
  68.        return(FALSE);
  69.     for (i = 0; i < 16; i++) {
  70.        b = '\r';
  71.        if (write_casio(&b, 1) == 1) {
  72.           usleep(5000);
  73.           b = '\n';
  74.           if (write_casio(&b, 1) == 1)
  75.              if (read_casio(&b, 1, 1000) == 1)
  76.                 if (b == '\021')
  77.                    if (enable_flow_control()) {
  78.                       session_open = TRUE;
  79.                       return(TRUE);
  80.                       }
  81.           }
  82.        usleep(100000);
  83.        }
  84.     error("BOSS session not started");
  85.     return(FALSE);
  86. }
  87.  
  88. /************************************************************************/
  89. EXPORT    end_session()
  90.  
  91. {    byte    buf[8];
  92.  
  93.     if (session_open) {
  94.        buf[0] = 0; /* length of 0 */
  95.        buf[1] = 0; /* address of 0 */
  96.        buf[2] = 0;
  97.        buf[3] = 0xff; /* type REC_EXIT */
  98.        send_packet(buf);
  99.        buf[0] = XMIT_TERMINATE;
  100.        write_casio(buf, 1);
  101.        session_open = FALSE;
  102.        }
  103. }
  104.  
  105. /************************************************************************/
  106. EXPORT    send_packet(buf)
  107.  
  108. byte    *buf;
  109.  
  110. {    int    len, i;
  111.     byte    b, checksum;
  112.     char    real[1024];
  113.  
  114.     if (session_open) {
  115.        real[0] = PACKET_START;
  116.        for (len = buf[0] + 4, i = checksum = 0; i < len; i++) {
  117.           checksum += buf[i];
  118.           real[2 * i + 1] = hex[buf[i] >> 4];
  119.           real[2 * i + 2] = hex[buf[i] & 0x0f];
  120.           }
  121.        checksum = 256 - checksum;
  122.        real[2 * i + 1] = hex[checksum >> 4];
  123.        real[2 * i + 2] = hex[checksum & 0x0f];
  124.        while (TRUE) {
  125.           if (write_casio(real, 2 * len + 3) != 2 * len + 3) {
  126.              error("unable to write packet to BOSS");
  127.              return(FALSE);
  128.              }
  129.           if ((i = read_casio(&b, 1, 50)) == 0)
  130.              return(TRUE); /* no complaints from BOSS */
  131.           else if (i == -1) {
  132.              error("error awaiting packet ACK from BOSS");
  133.              return(FALSE);
  134.              }
  135.           else if (b == '?') {
  136.              disable_flow_control();
  137.              usleep(20000);
  138.              i = read_casio(&b, 1, 1000);
  139.              enable_flow_control();
  140.              if (i != 1 || b != '\021') {
  141.                 error("protocol error during packet retry prologue");
  142.                 return(FALSE);
  143.                 }
  144.              }
  145.           else {
  146.              unget_byte(b);
  147.              return(TRUE);
  148.              }
  149.           }
  150.        }
  151.     else {
  152.        error("attempted to send a packet without opening a session");
  153.        return(FALSE);
  154.        }
  155. }
  156.  
  157. /************************************************************************/
  158. EXPORT    int    receive_packet(packet)
  159.  
  160. byte    *packet;
  161.  
  162. {    byte    checksum;
  163.     int    i;
  164.  
  165.     while (TRUE) {
  166.        if (read_casio(packet, 1, 60000) != 1) {
  167.           error("no transmission received from BOSS");
  168.           return(FALSE);
  169.           }
  170.        if (packet[0] == '\n' || packet[0] == '\r') {
  171.           packet[0] = '\021';
  172.           if (write_casio(packet, 1) != 1) {
  173.              error("could not reply to BOSS polling");
  174.              return(FALSE);
  175.              }
  176.           }
  177.        else if (packet[0] == PACKET_START)
  178.           break;
  179.        else if (packet[0] == XMIT_TERMINATE)
  180.           return(FALSE);
  181.        else {
  182.           error("unexpected data from the BOSS: %c (%02x)", packet[0], packet[0]);
  183.           return(FALSE);
  184.           }
  185.        }
  186.     if (!read_byte(packet, 4))
  187.        return(FALSE);
  188.     if (!read_byte(packet + 4, packet[0] + 1))
  189.        return(FALSE);
  190.     for (i = checksum = 0; i < packet[0] + 5; i++)
  191.        checksum += packet[i];
  192.     if (checksum != 0) {
  193.        error("parity error, retrying receive");
  194.        packet[0] = RCV_ERROR;
  195.        write_casio(packet, 1);
  196.        usleep(20000);
  197.        packet[0] = '\021';
  198.        write_casio(packet, 1);
  199.        return(receive_packet(packet));
  200.        }
  201.     else
  202.        return(TRUE);
  203. }
  204.  
  205. /************************************************************************/
  206. EXPORT    acknowledge_object()
  207.  
  208. {    byte    b;
  209.  
  210.     b = PACKET_ACK;
  211.     if (!write_casio(&b, 1))
  212.        error("error acknowledging packet");
  213. }
  214.  
  215. /************************************************************************/
  216. EXPORT    int    wait_for_acknowledgement()
  217.  
  218. {    byte    b;
  219.  
  220.     if (read_casio(&b, 1, 60000) == 1)
  221.        if (b == PACKET_ACK)
  222.           return(TRUE);
  223.        else
  224.           error("invalid object acknowledgement: %c (%02x)", b, b);
  225.     else
  226.        error("no acknowledgement received from BOSS");
  227.     return(FALSE);
  228. }
  229.