/* ANA Commands for Recording from pore2 on to Optical Disk */
/* this is a clone from optdisk.c called optdisk2.c for a second line */
/* uses op2cmd, etc, and serial port 3 */
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
 
#include "ana_structures.h"
#include <ctype.h>
#include <stdlib.h>
#if	NeXT
#include <sys/ioctl.h>
#else
#include <termios.h>    /* added termio and unistd to enable unbuffered */
#include <sys/unistd.h>    /* input -> history buffer etc.  LS 8may92 */
#endif
 static	int	fd;	/* file number */
 static	int	open_flag=0, kilroy=0;
 extern int	*pscrat;
 extern char	*expand_name(char *, char *);
 extern struct sym_desc	sym[];
#if	NeXT
 static struct sgttyb new_params, old_params;
#else
 static struct termio new_params, old_params;
#endif
 /*------------------------------------------------------------------------- */
int ana_op2cmd_send(int narg, int ps[])
 /* send commands to optical disk # 1.  Commands are changed to upper case.
   If a command ends with a digit, a colon : is added before send-off. 
   LS 17sep92 */
 /* modified 11/14/92 ras */
 {
 int	n, n2;
 char	*buf, *p;
 
 buf = (char *) pscrat;
 if (sym[*ps].class != 2) return execute_error(70);
 if (open_flag == 0) {
 fd = open("/dev/ttyd3", O_RDWR);
 if (fd < 0 ) { perror("could not open /dev/ttyd3");   return -1; }
#if	NeXT
 /* not implemented yet on NeXT */
 if (ioctl(fd, TIOCGETP, &old_params) < 0)
   {printf("IOCTL get failed\n"); }
 else {
 new_params = old_params;
 new_params.sg_flags = CBREAK | ANYP | CRMOD; }
#else
 if (ioctl(fd, TCGETA, &old_params) < 0)
   {printf("IOCTL get failed\n"); }
 else {
 new_params = old_params;
 /* set the line to 9600 baud and non-canonical */
 new_params.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
 new_params.c_cc[VMIN] = 0;
 new_params.c_cc[VTIME] = 20;	/* 10 per second */
 new_params.c_lflag &= ICANON;
 new_params.c_lflag &= ~ECHO;
 if (ioctl(fd, TCSETA, &new_params) < 0) perror("IOCTL set failed");
 }
#endif
 open_flag = 1; 
 }
  p = (char *) sym[*ps].spec.array.ptr;
   strcpy(buf + 1, p);
   for (p = buf + 1; *p; p++) *p = toupper(*p);
   if (isdigit(*(p - 1))) { *p++ = ':'; *p = 0; }
   *buf = 2;
   buf[strlen(buf)] = 4;
   if (ioctl(fd, TCFLSH, 0)) perror("flush failed");
   if (write(fd, buf, strlen(buf)) < 0)
   { perror("could not write to optical disk");
     return -1; }
 return 1;
 /* note no checking of response done, this is done in ana_op2cmd_check
 allows user to do something else in the meantime */
 }
 /*------------------------------------------------------------------------- */
int ana_op2cmd_check(int narg, int ps[])
 {
 /* this is a function, returns either 1 or 4 which are symbols for 1 or 0 */
 int	n, n2;
 char	*buf;
 buf = (char *) pscrat;
 if (open_flag == 0) return 4;
 new_params.c_lflag &= ~ICANON;
 if (ioctl(fd, TCSETA, &new_params) < 0) perror("IOCTL set failed"); 
 n = read(fd, buf, 1);	/* first character should be an ACK */
 if (n <= 0) { perror("read back from video disk");	return 4; }
 if ( *buf == 6 ) {
 printf("got an ACK\n");
 new_params.c_lflag &= ICANON;
 if (ioctl(fd, TCSETA, &new_params) < 0) perror("IOCTL set failed"); 
 return 1; }
 printf("got something else, value = %d\n", *buf);
 /* no ack, a problem ? nak is a 21*/
 if ( *buf == 21 ) {	/* read error number if nak */
 n=read(fd, buf, 2);
 if ( n < 2 || *buf != '2')
 	{ perror("can't read error code");	return 4; }
 switch (buf[1]) {
 case '1': printf("video disk transmission error\n"); break;
 case '2': printf("video disk buffer overflow\n"); break;
 }
 }
 /* after one of these, just flush the buffer */
 new_params.c_lflag &= ICANON;
 if (ioctl(fd, TCSETA, &new_params) < 0) perror("IOCTL set failed"); 
 if (ioctl(fd, TCFLSH, 0)) perror("flush failed");
 return 4;
 }
 /*------------------------------------------------------------------------- */
int ana_op2read(int narg, int ps[])
 {
 int	n, result_sym, i;
 char	*buf, *p;
 
 if (open_flag == 0) return -1;
 buf = (char *) pscrat;
 n = read(fd, buf, 40);
 if (n <= 0) return -1;
 result_sym = string_scratch(n);
 bcopy(buf, sym[result_sym].spec.array.ptr, n);
 p = (char *) sym[result_sym].spec.array.ptr;
 *(p+n) = 0;
 return result_sym;
}
/*------------------------------------------------------------------------- */
int ana_op2cmd(int narg, int ps[])
 /* communication with optical disk drive # 1  */
 /*   Call:  op2CMD,string */
 {
 if (ana_op2cmd_send( narg, ps) != 1 ) return -1;
 if (ana_op2cmd_check( narg, ps) != 1) return -1;
 return 1;
 }
/*------------------------------------------------------------------------- */ 
int ana_op2cmd_f(int narg, int ps[])
/* function form of op2cmd; returns response string */
 {
 if (ana_op2cmd_send( narg, ps) != 1 ) return -1;
 return  ana_op2read(narg, ps);
 }
/*------------------------------------------------------------------------- */
