home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* Copyright 1990 by Chuck Musciano and Harris Corporation */
- /* */
- /* Permission to use, copy, modify, and distribute this software */
- /* and its documentation for any purpose and without fee is */
- /* hereby granted, provided that the above copyright notice */
- /* appear in all copies and that both that copyright notice and */
- /* this permission notice appear in supporting documentation, and */
- /* that the name of Chuck Musciano and Harris Corporation not be */
- /* used in advertising or publicity pertaining to distribution */
- /* of the software without specific, written prior permission. */
- /* Chuck Musciano and Harris Corporation make no representations */
- /* about the suitability of this software for any purpose. It is */
- /* provided "as is" without express or implied warranty. */
- /* */
- /* This code contains data and information that is proprietary */
- /* to Casio Corporation. You may be subject to legal action if */
- /* this information is released without explicit permission from */
- /* Casio. */
- /************************************************************************/
-
- /************************************************************************/
- /* */
- /* packet.c handle sending and receiving raw packets */
- /* */
- /************************************************************************/
-
- #include "manifest.h"
- #include "casio.h"
-
- PRIVATE int session_open = FALSE;
- PRIVATE char hex[] = "0123456789ABCDEF";
-
- /************************************************************************/
- PRIVATE int read_byte(b, len)
-
- byte *b;
- int len;
-
- { char buf[1024], *v1, *v2, *p, *index();
-
- if (read_casio(buf, 2 * len, 1000) == 2 * len) {
- for (p = buf; len > 0; len--, p += 2, b++)
- if ((v1 = index(hex, *p)) && (v2 = index(hex, *(p + 1))))
- *b = ((v1 - hex) << 4) + (v2 - hex);
- else {
- error("Invalid Hex-ASCII byte from BOSS: %c%c (%02x%02x)", *p, *(p + 1), *p, *(p + 1));
- return(FALSE);
- }
- return(TRUE);
- }
- else
- error("error reading %d byte%s from BOSS", len, (len == 1)? "" : "s");
- return(FALSE);
- }
-
- /************************************************************************/
- EXPORT int start_session()
-
- { byte b;
- int i;
-
- if (session_open)
- return(TRUE);
- if (!flush_casio())
- return(FALSE);
- if (!disable_flow_control())
- return(FALSE);
- for (i = 0; i < 16; i++) {
- b = '\r';
- if (write_casio(&b, 1) == 1) {
- usleep(5000);
- b = '\n';
- if (write_casio(&b, 1) == 1)
- if (read_casio(&b, 1, 1000) == 1)
- if (b == '\021')
- if (enable_flow_control()) {
- session_open = TRUE;
- return(TRUE);
- }
- }
- usleep(100000);
- }
- error("BOSS session not started");
- return(FALSE);
- }
-
- /************************************************************************/
- EXPORT end_session()
-
- { byte buf[8];
-
- if (session_open) {
- buf[0] = 0; /* length of 0 */
- buf[1] = 0; /* address of 0 */
- buf[2] = 0;
- buf[3] = 0xff; /* type REC_EXIT */
- send_packet(buf);
- buf[0] = XMIT_TERMINATE;
- write_casio(buf, 1);
- session_open = FALSE;
- }
- }
-
- /************************************************************************/
- EXPORT send_packet(buf)
-
- byte *buf;
-
- { int len, i;
- byte b, checksum;
- char real[1024];
-
- if (session_open) {
- real[0] = PACKET_START;
- for (len = buf[0] + 4, i = checksum = 0; i < len; i++) {
- checksum += buf[i];
- real[2 * i + 1] = hex[buf[i] >> 4];
- real[2 * i + 2] = hex[buf[i] & 0x0f];
- }
- checksum = 256 - checksum;
- real[2 * i + 1] = hex[checksum >> 4];
- real[2 * i + 2] = hex[checksum & 0x0f];
- while (TRUE) {
- if (write_casio(real, 2 * len + 3) != 2 * len + 3) {
- error("unable to write packet to BOSS");
- return(FALSE);
- }
- if ((i = read_casio(&b, 1, 50)) == 0)
- return(TRUE); /* no complaints from BOSS */
- else if (i == -1) {
- error("error awaiting packet ACK from BOSS");
- return(FALSE);
- }
- else if (b == '?') {
- disable_flow_control();
- usleep(20000);
- i = read_casio(&b, 1, 1000);
- enable_flow_control();
- if (i != 1 || b != '\021') {
- error("protocol error during packet retry prologue");
- return(FALSE);
- }
- }
- else {
- unget_byte(b);
- return(TRUE);
- }
- }
- }
- else {
- error("attempted to send a packet without opening a session");
- return(FALSE);
- }
- }
-
- /************************************************************************/
- EXPORT int receive_packet(packet)
-
- byte *packet;
-
- { byte checksum;
- int i;
-
- while (TRUE) {
- if (read_casio(packet, 1, 60000) != 1) {
- error("no transmission received from BOSS");
- return(FALSE);
- }
- if (packet[0] == '\n' || packet[0] == '\r') {
- packet[0] = '\021';
- if (write_casio(packet, 1) != 1) {
- error("could not reply to BOSS polling");
- return(FALSE);
- }
- }
- else if (packet[0] == PACKET_START)
- break;
- else if (packet[0] == XMIT_TERMINATE)
- return(FALSE);
- else {
- error("unexpected data from the BOSS: %c (%02x)", packet[0], packet[0]);
- return(FALSE);
- }
- }
- if (!read_byte(packet, 4))
- return(FALSE);
- if (!read_byte(packet + 4, packet[0] + 1))
- return(FALSE);
- for (i = checksum = 0; i < packet[0] + 5; i++)
- checksum += packet[i];
- if (checksum != 0) {
- error("parity error, retrying receive");
- packet[0] = RCV_ERROR;
- write_casio(packet, 1);
- usleep(20000);
- packet[0] = '\021';
- write_casio(packet, 1);
- return(receive_packet(packet));
- }
- else
- return(TRUE);
- }
-
- /************************************************************************/
- EXPORT acknowledge_object()
-
- { byte b;
-
- b = PACKET_ACK;
- if (!write_casio(&b, 1))
- error("error acknowledging packet");
- }
-
- /************************************************************************/
- EXPORT int wait_for_acknowledgement()
-
- { byte b;
-
- if (read_casio(&b, 1, 60000) == 1)
- if (b == PACKET_ACK)
- return(TRUE);
- else
- error("invalid object acknowledgement: %c (%02x)", b, b);
- else
- error("no acknowledgement received from BOSS");
- return(FALSE);
- }
-