/* SERIAL.C */

#include        <exec/types.h>
#include        <devices/serial.h>
#undef NULL
#include        <stdio.h>

extern struct Port *CreatePort();
struct Port *mySerWritePort;
struct IOExtSer *mySerWriteReq;

/***********************************************************************/
main( argc, argv ) 
   int argc;
   char *argv[];
{
   char program[30], qline[5] ;
   int i, iunit, delay, unit[9], qunit, qvalue, loop ;

   loop = - 1 ;
   delay = 50 ;
   qunit = -1 ;
   strcpy( qline, "XX" ) ;
   for (iunit=0;iunit<9;iunit++) {
      unit[iunit] = 0 ;
   }

/*
   printf( "argc is %d \n", argc ) ;
   for (i=0;i<argc;++i) {
      printf( "arg # %d is %s \n", i, argv[i] ) ;
   }
   printf( "%s \n", *argv ) ;
*/
     
   i = option( argc, argv, unit, &delay, program, qline, &qunit, &qvalue,
       &loop ) ;
/*
   printf( "qline is  %s \n", qline ) ;  
   printf( "qunit is  %d \n", qunit ) ;
   printf( "qvalue is %d \n", qvalue ) ;
   printf( "loop   is %d \n", loop ) ;
   printf( "Program is: %s \n", program ) ;
   for (iunit=0;iunit<9;iunit++) {
      printf("Unit %d is %d \n", iunit, unit[iunit] ) ;
   }
   printf( "Delay is %d \n", delay ) ;
*/
   if( i == 0 ) {
      OpenSerial( unit, delay, program, qline, qunit, qvalue, loop );
   }
   else {
      printf( "No execution due to above error \n" ) ;
   }   
   return ( 0 ) ;
}  /* main() */
/**********************************************************************/
option( argc, argv, unit, pdelay, program, qline, pqunit, pqvalue, ploop )
   int argc, *pdelay, *pqunit, *pqvalue, *ploop, unit[] ;
   char program[], qline[] ;
   char *argv[] ;
{
   int i ;

   i = 1 ;
   while( i < argc ) {
      if( strcmpu( argv[i], "?" ) == 0 ) {
         help( ) ;
         return( 1 ) ;
      }
      if( i == 1 ) {
         strcpy( program, argv[i] ) ;
      }
      else if( strcmpu( argv[i], "L" ) == 0 ) {
         i = i + 1 ;
         sscanf( argv[i], "%d", ploop ) ;
      }
      else if( strcmpu( argv[i], "U" ) == 0 ) {
         i = i + 1 ;
         if(      strcmpu( argv[i], "0" ) == 0 ) unit[0] = 1 ;
         else if( strcmpu( argv[i], "1" ) == 0 ) unit[1] = 1 ;
         else if( strcmpu( argv[i], "2" ) == 0 ) unit[2] = 1 ;
         else if( strcmpu( argv[i], "3" ) == 0 ) unit[3] = 1 ;
         else if( strcmpu( argv[i], "4" ) == 0 ) unit[4] = 1 ;
         else if( strcmpu( argv[i], "5" ) == 0 ) unit[5] = 1 ;
         else if( strcmpu( argv[i], "6" ) == 0 ) unit[6] = 1 ;
         else if( strcmpu( argv[i], "7" ) == 0 ) unit[7] = 1 ;
         else if( strcmpu( argv[i], "8" ) == 0 ) unit[8] = 1 ;
         else {
            printf( "Illegal unit is %s \n", argv[i] ) ;
            return( 1 ) ;
         }
      }
      else if( strcmpu( argv[i], "D" ) == 0 ) {
         i = i + 1 ;
         sscanf( argv[i], "%d", pdelay ) ;
      }
      else if( strcmpu( argv[i], "Q" ) == 0 ) {
         /* get the quit option:   Q line unit value  */
         i = i + 1 ;
         if( strcmpu( argv[i], "CD" ) == 0 ) {
            strcpy( qline, "CD" ) ;
         }
         else if( strcmpu( argv[i], "CTS" ) == 0 ) {
            strcpy( qline, "CTS" ) ;
         }
         else if( strcmpu( argv[i], "DSR" ) == 0 ) {
            strcpy( qline, "DSR" ) ;
         }
         else {
            printf( "Illegal line value was %s, expecting CD, CTS, or DSR\n",
            argv[i] ) ;
            return( 1 ) ;
         }
         i = i + 1 ;
         if(      strcmpu( argv[i], "0" ) == 0 ) *pqunit = 0 ;
         else if( strcmpu( argv[i], "1" ) == 0 ) *pqunit = 1 ;
         else if( strcmpu( argv[i], "2" ) == 0 ) *pqunit = 2 ;
         else if( strcmpu( argv[i], "3" ) == 0 ) *pqunit = 3 ;
         else if( strcmpu( argv[i], "4" ) == 0 ) *pqunit = 4 ;
         else if( strcmpu( argv[i], "5" ) == 0 ) *pqunit = 5 ;
         else if( strcmpu( argv[i], "6" ) == 0 ) *pqunit = 6 ;
         else if( strcmpu( argv[i], "7" ) == 0 ) *pqunit = 7 ;
         else if( strcmpu( argv[i], "8" ) == 0 ) *pqunit = 8 ;
         else {
            printf( "Illegal quit unit is %s, expecting 0 thru 8 \n", 
            argv[i] ) ;
            return( 1 ) ;
         }
         i = i + 1 ;
         if(      strcmpu( argv[i], "0" ) == 0 ) *pqvalue = 0 ;
         else if( strcmpu( argv[i], "1" ) == 0 ) *pqvalue = 1 ;
         else {
            printf( "Illegal quit value is %s, expecting 0 or 1 \n", 
            argv[i] ) ;
            return( 1 ) ;
         }
      }
      else {
         printf( "Illegal option %s \n", argv[i] ) ;
         return( 1 ) ;
      }
      i = i + 1 ;
   }
   return( 0 ) ;
}
/**********************************************************************/
OpenSerial( unit, delay, program, qline, qunit, qvalue, loop )
   char program[], qline[] ;
   int unit[], delay, qunit, qvalue, loop ;
{

   /* create a reply port to which serial device can return the request */
   mySerWritePort = CreatePort( "mySerial", 0 ) ;
   if( mySerWritePort == NULL ) {
      printf( "Problems during CreatePort \n" ) ;   /* can't create port */
      }
   else {
      /* create a request block appropriate to serial */
      mySerWriteReq = (struct IOExtSer *)CreateExtIO(mySerWritePort,
               sizeof( struct IOExtSer ) ) ;
      if( mySerWriteReq == NULL ) {
         printf( "CreateExtIO error \n" ) ; /* error during CreateExtIO! */
      }
      else {
         mySerWriteReq->io_SerFlags = 0 ;

         looper( unit, delay, program, qline, qunit, qvalue, loop ) ;

         /*     printf( "Closing IOExtSer... \n" ) ; */
         /* delete request block */
         DeleteExtIO( mySerWriteReq, sizeof(struct IOExtSer) ) ;
      }
      /* printf ("Closing Port...\n");  */
      DeletePort( mySerWritePort ) ;
   }
   return ( 0 ) ;
}  
/************************************************************************/
int looper( unit, delay, program, qline, qunit, qvalue, loop )
   char program[], qline[] ;
   int unit[], delay, qunit, qvalue, loop ;
{
   char cmd[255] ;
   int cont, error, iunit, loopc, qloop ;
   int cd[9], cdold[9], cts[9], ctsold[9], dsr[9], dsrold[9] ;

   for( iunit=0;iunit<9;iunit++) {
      cdold[iunit]  = -1 ;
      ctsold[iunit] = -1 ;
      dsrold[iunit] = -1 ;
   }
   qloop = loop ;
   loopc = 0 ;
   cont = 1 ;
   if( loop < 0 && qunit < 0 ) {
      /* no quiting constraints.  So lets do this once. */
      qloop = 1 ;
   }
   while( cont == 1 ) {
/*      printf( "At top of loop \n" ) ; */
      for( iunit=0;iunit<9;iunit++) {
         if( unit[iunit] == 1 ) {
            error = OpenDevice( "serial.device", iunit, mySerWriteReq, 0 ) ;
            if( error != 0 ) {
               printf( "Serial device unit %d did not open \n", iunit ) ; 
               /* device not available */
            }
            else {
               WriteSer( mySerWriteReq, iunit, dsr, cts, cd, "test", 4 ) ;
               /* print_request( mySerWriteReq ); */
               CloseDevice( mySerWriteReq ) ;
               if( cd[iunit] != cdold[iunit] ) {
                  cdold[iunit] = cd[iunit] ;
                  cmdup( cmd, program, "CD", iunit, cd[iunit] ) ; 
                  if( qunit >= 0 ) {
                     if( strcmp( qline, "CD" ) == 0 ) {
                        if( qvalue == cd[qunit] ) {
                           cont = 0 ;
                        }
                     }
                  }
               }
               if( cts[iunit] != ctsold[iunit] ) {
                  ctsold[iunit] = cts[iunit] ;
                  cmdup( cmd, program, "CTS", iunit, cts[iunit] ) ; 
                  if( qunit >= 0 ) {
                     if( strcmp( qline, "CTS" ) == 0 ) {
                        if( qvalue == cts[qunit] ) {
                           cont = 0 ;
                        }
                     }
                  }
               }
               if( dsr[iunit] != dsrold[iunit] ) {
                  dsrold[iunit] = dsr[iunit] ;
                  cmdup( cmd, program, "DSR", iunit, dsr[iunit] ) ; 
                  if( qunit >= 0 ) {
                     if( strcmp( qline, "DSR" ) == 0 ) {
                        if( qvalue == dsr[qunit] ) {
                           cont = 0 ;
                        }
                     }
                  }
               }
            }
         }
      }
/*      if( strcmp( cmd, "" ) != 0 ) {
         printf( "%s \n", cmd ) ;
         Execute( cmd, 0, 0 ) ;
      }
*/
      if( cont == 0 ) {
         printf( "Quiting because of condition on unit %d line %s \n",
         qunit, qline ) ;
      }
      if( qloop > 0 ) {
         loopc = loopc + 1 ;
         if( loopc >= qloop ) {
            cont = 0 ;
            printf( "Quiting because loop count of %d was reached \n",
            qloop ) ;
         }
      }
      if( cont == 1 ) {
         Delay( delay ) ;
      }
   }
   return( 0 ) ;
}
/************************************************************************/
int cmdup( cmd, program, bit, iunit, status ) 
   char cmd[], bit[], program[] ;
   int iunit, status ;
{
   char string[10] ;
   int value ;

   strcpy( cmd, "rx " ) ;
   strcat( cmd, program ) ;
   strcat( cmd, ".rexx SERIAL " ) ;
   strcat( cmd, bit ) ;
   value = status ;
   if( value != 0 ) {
      value = 1 ;
   }
   sprintf( string, " %d %d ", iunit, value ) ;
   strcat( cmd, string ) ;
   Execute( cmd, 0, 0 ) ;
   return( 0 ) ;
}
/************************************************************************/
int WriteSer( io, iunit, dsr, cts, cd, data, length )
   struct IOExtSer *io ;
   char *data ;
   int cd[], cts[], dsr[], length, iunit ;
{
   int error;

   io->IOSer.io_Data    = (APTR)data;
   io->IOSer.io_Length  = length ;
   io->IOSer.io_Command = CMD_WRITE ;
   io->IOSer.io_Command = SDCMD_QUERY ;
   error = DoIO( io ) ;
   if( error != 0 ) {
      printf( "serial.device write error \n" ) ;
      }
   else {
      /* look for Request To Send, Data Set Ready, and Carrier Detect */
/*
      printf( "io_Status is %d \n", io->io_Status ) ;
*/
      dsr[iunit] = io->io_Status & 010 ;
      cts[iunit] = io->io_Status & 020 ;
      cd[iunit]  = io->io_Status & 040 ;
      if( dsr[iunit] != 0 ) {
         dsr[iunit] = 1 ;
      }
      if( cd[iunit] != 0 ) {
         cd[iunit] = 1 ;
      }
      if( cts[iunit] != 0 ) {
         cts[iunit] = 1 ;
      }
/*
      printf( "For unit %d \n", iunit ) ;
      printf( "  DSR is %d \n", dsr[iunit] ) ;
      printf( "  CTS is %d \n", cts[iunit] ) ;
      printf( "  CD  is %d \n", cd[iunit]  ) ;
*/
   }
   return( error ) ;
}
/************************************************************************/
print_request( IORser )
    struct IOExtSer *IORser;     /* Serial port IO request block */
{
#define PRINT( field )           printf( "      %s = %8lx %8ld\n" \
                                 , "field", (ULONG) IORser->field \
                                 , (ULONG) IORser->field )
#define IPRINT( index, field ) printf( " %2ld   %s = %8lx %8ld\n" \
                                    , index, "field", (ULONG) IORser->field \
                                                    , (ULONG) IORser->field )

      printf( "index field name       hexadec  decimal\n" ); 
      IPRINT( 1, io_CtlChar   ); 
      IPRINT( 2, io_RBufLen   );
      IPRINT( 3, io_ExtFlags  ); 
      IPRINT( 4, io_Baud      );
      IPRINT( 5, io_BrkTime   ); 
      IPRINT( 6, io_TermArray.TermArray0   );
      IPRINT( 7, io_TermArray.TermArray1   );
      IPRINT( 8, io_ReadLen   );
      IPRINT( 9, io_WriteLen  );
      IPRINT(10, io_StopBits  );
      IPRINT(11, io_SerFlags  );
      printf( "\n" );   /* Not associated with an index */
          PRINT( io_Status    );
/*
      UWORD  io_Status
      status of serial port, as follows:

      BIT   ACTIVE  FUNCTION
        0      low  busy
        1      low  paper out
        2      low  select
        3      low  Data Set Ready
        4      low  Clear To Send
        5      low  Carrier Detect
        6      low  Ready To Send
        7      low  Data Terminal Ready
        8     high  read overrun
        9     high  break event
       10     high  break recieved
       11     high  transmit x-OFFed
       12     high  recieve x-OFFed
    13-15    (not)  reserved
*/
      return ( 0 ) ;
}  /* print_request() */
