/***************************************************************/
/*                                                             */
/*    Copyright 1991 by Wayne E. McDaniel                      */
/*    All Rights Reserved                                      */
/*    AutoLibrary is a Trademark of Avid Software              */
/*                                                             */
/***************************************************************/

#include <stdio.h>
#include <ctype.h>
#include "al.h"

/* Include file only required for AutoLibrary system source files. */
#include "al_sys.h"


#include "\gls\gf.h"
#include "\gls\asiports.h"

/********************************************************/
    int         /* The return status. */
CommInterfaceClose (com, info, opts)
    int com;    /* The AutoLibrary communication port. */
    int *info;
    char *opts; /* Options. */
/********************************************************/
{
int err;

    opts = opts; /* for compiler */

    /* Start out with no errors. */
    *info = ERR_OK;

    err = asiquit (comlist[com]->hw_port);
    if (err != ASSUCCESS) {
	*info = err;
	return(ERR_COMM_PACKAGE);
    }

    return(ERR_OK);
}

/********************************************************/
    int
CommInterfaceOpen (com, device, info, opts)
    int com;      /* The AutoLibrary communication port. */
    char *device; /* The device name. */
    int *info;
    char *opts;   /* Options. */
/********************************************************/
{
int mode, word_len, baud, stop_bits, parity, port_num, strip, dtr, rts, xon;
unsigned int rx_length, tx_length;
char sc, control;
char temp_buf[85];
int s_num, err;
long temp_long;

    /* Start out with no errors. */
    *info = ERR_OK;

    /* Let valid input for device be com1 or 1 (for example) */
    if (sscanf (device, "com%d", &port_num) == 0) {

	if (sscanf (device, "%d", &port_num) == 0) {
	    *info = ASINVPORT;
	    return (ERR_COMM_PACKAGE);
	}
    }

    /* Make sure wild number did not make it through. */
    if ((port_num < 1) || (port_num > 17)) {
	*info = ASINVPORT;
	return (ERR_COMM_PACKAGE);
    }

    /* For Greenleaf COM1 is defined as 0. */
    port_num--;

    /* Save the port number for closing. */
    comlist[com]->hw_port = port_num;

    /* No ASCII device names in this comm package. */
    comlist[com]->hw_port_name = (char *)NULL;

    mode = 0;
    baud = 9600;
    parity = P_ODD;
    stop_bits = 1;
    word_len = 8;
    dtr = 0;
    rts = 0;
    rx_length = 8192;
    tx_length = 512;
    strip = ASCII;
    xon = TRUE;

    s_num = 0; /* Required for AvidProcessOptions. */
    while ((sc = AvidProcessOptions (AVID, opts, "", &control,
					       temp_buf, &s_num)) != '\0') {

	if ((o_strip_yes[0] == control) && (o_strip_yes[1] == sc))
	    strip = ASCII;

	if ((o_strip_no[0] == control) && (o_strip_no[1] == sc))
	    strip = BINARY;

	if ((o_even[0] == control) && (o_even[1] == sc))
	    parity = P_EVEN;

	if ((o_odd[0] == control) && (o_odd[1] == sc))
	    parity = P_ODD;

	if ((o_none[0] == control) && (o_none[1] == sc))
	    parity = P_NONE;

	if ((o_baud[0] == control) && (o_baud[1] == sc))
	    baud = atoi (temp_buf);

	if ((o_stop_bits_1[0] == control) && (o_stop_bits_2[1] == sc))
	    stop_bits = 1;

	if ((o_stop_bits_2[0] == control) && (o_stop_bits_2[1] == sc))
	    stop_bits = 2;

	if ((o_word_len_7[0] == control) && (o_word_len_7[1] == sc))
	    word_len = 7;

	if ((o_word_len_8[0] == control) && (o_word_len_8[1] == sc))
	    word_len = 8;

	if ((o_dtr[0] == control) && (o_dtr[1] == sc))
	    dtr = 1;

	if ((o_xon_yes[0] == control) && (o_xon_yes[1] == sc))
	    xon = TRUE;

	if ((o_xon_no[0] == control) && (o_xon_no[1] == sc))
	    xon = FALSE;

	if ((o_rx_len[0] == control) && (o_rx_len[1] == sc)) {
	    temp_long = atol (temp_buf);
	    rx_length = temp_long;
	}

	if ((o_tx_len[0] == control) && (o_tx_len[1] == sc)) {
	    temp_long = atol (temp_buf);
	    tx_length = temp_long;
	}
    }

    mode = strip | ASINOUT | NORMALRX;

    err = asiopen (comlist[com]->hw_port, mode, rx_length, tx_length,
			baud, parity, stop_bits, word_len, dtr,	rts);
    if (err != ASSUCCESS) {
	*info = err;
	return(ERR_COMM_PACKAGE);
    }

    if (xon) {
	err = asixon(comlist[com]->hw_port, 30, 70, XON, XOFF);
	if (err != ASSUCCESS) {
	    *info = err;
	    return(ERR_COMM_PACKAGE);
	}
    }

    return(ERR_OK);
}

/********************************************************/
    int
CommInterfaceRead (com, r_timeout, e_timeout, info, opts)
    int com;         /* The AutoLibrary communication port. */
    long r_timeout;  /* The repeating timeout. */
    long e_timeout;  /* The ending timeout. */
    int *info;
    char *opts;      /* Options. */
/********************************************************/
{
int c;
long seconds;

    /* Start out with no errors. */
    *info = ERR_OK;

    /* Have to check for an ending timeout. */
    time (&seconds);
    if (seconds >= e_timeout) {
	*info = ERR_ENDING_TIMEOUT;
	return(ERR_EOF);
    }

    /* Try to get a character without setting up for a timeout. */
    c = asigetc (comlist[com]->hw_port);
    if ((c >=0) && (c <= 0xFF)) {
	EveryChar(c);
	return(c);
    }

    if (c == ASINVPORT) {
	*info = ASINVPORT;
	return(ERR_COMM_PACKAGE);
    }

    if (c == ASNOTSETUP) {
	*info = ASNOTSETUP;
	return(ERR_COMM_PACKAGE);
    }

    /* A timeout is required so set up for it. */
    time(&seconds);
    if (r_timeout < seconds)
	r_timeout = r_timeout + seconds;

    while (1 > 0) {

	/* Do not try to get a character if an ending timeout has occurred. */
	time (&seconds);
	if (seconds >= e_timeout) {
	    *info = ERR_ENDING_TIMEOUT;
	    return(ERR_EOF);
	}

	/* Try to get a character. */
	c = asigetc (comlist[com]->hw_port);
	if ((c >=0) && (c <= 0xFF)) {
	    EveryChar(c);
	    return(c);
	}

	if (c == ASBUFREMPTY) {

	    time (&seconds);
	    if (seconds >= r_timeout) {
		*info = ERR_REPEAT_TIMEOUT;
		return(ERR_EOF);
	    }

	} else {
	    /* Error ASINVPORT or ASNOTSETUP occurred. */
	    *info = c;
	    return(ERR_COMM_PACKAGE);
	}
    }

    opts = opts; /* for compiler */

    /* Nothing should reach here but if it does... */
    *info = c;
    return(ERR_COMM_PACKAGE);
}

/********************************************************/
    int
CommInterfaceSend (com, bef, bet, s, len, info, opts)
    int com; /* The AutoLibrary communication port. */
    int bef; /* The number of milliseconds to delay before sending first character. */
    int bet; /* The number of milliseconds to delay between each character. */
    char *s; /* The string to send. */
    int len; /* The length of the string. May not equal strlen(s) because of null characters in the string. */
    int *info;
    char *opts; /* Options. */
/********************************************************/
{
int i, status;

    opts = opts; /* for compiler */

    /* Start out with no errors. */
    *info = ERR_OK;

    /* The delay before the first character sent. */
    delay (bef);

    for (i=0; i<len; i++) {

	/* The delay before the first character sent. */
	delay (bet);

	status = asiputc (comlist[com]->hw_port, s[i]);
	if (status != ASSUCCESS) {
	    *info = status;
	    return(ERR_COMM_PACKAGE);
	}
    }

    return(ERR_OK);
}
