/* includes for serial communication */ 
       #include <sys/types.h> 
       #include <sys/stat.h>
       #include <fcntl.h>
       #include <termios.h>
       #include <stdio.h>
       
/* includes for jni */ 
       #include <stdio.h>
       #include <jni.h> 

/* the following is generated by javah */ 
       #include "ReadIR.h" 

/* define properties of the serial port */ 
       #define BAUDRATE B300
       #define MODEMDEVICE "/dev/ttyS1"
       /* ttyS1 is lower port on phoebe.cse, ttyS0 is upper 11/1/99 R. Chapman  */
       #define _POSIX_SOURCE 1 
       #define FALSE 0
       #define TRUE 1

static   int fd;
static   struct termios oldtio,newtio;
static   char buffer[255]; 


/* this is the method that the Java program calls to initialize the serial port. 
   It probably doesn't need any changing */ 
JNIEXPORT jint JNICALL Java_ReadIR_openIR(JNIEnv *env, jobject obj) { 
        fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
        if (fd <0) {perror(MODEMDEVICE); exit(-1); }

        tcgetattr(fd,&oldtio); /* save current port settings */

        bzero(&newtio, sizeof(newtio));
        newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
        newtio.c_iflag = IGNPAR;
        newtio.c_oflag = 0;

        /* set input mode (non-canonical, no echo,...) */
        newtio.c_lflag = 0;

        newtio.c_cc[VTIME]    = 0;   /* inter-character timer unused */
        newtio.c_cc[VMIN]     = 1;   /* blocking read until 5 chars received */

        tcflush(fd, TCIFLUSH);
        tcsetattr(fd,TCSANOW,&newtio);
        return(0); 
        
} 

/* this reads a valid badge and returns it as a byte array to Java. This is the routine that
   defines the communication with the basic stamp */ 

JNIEXPORT jint JNICALL Java_ReadIR_readIR(JNIEnv *env, jobject obj, jbyteArray  b)
       {
       int res=0; /* used to store return codes from read(); */  
       int i,j;  /* index vars */ 
       jbyte buf[255],ident[255]; 
       int chksum = 0; 
       


        while (1) {       /* loop for input till a return gets you out */
	  memset((char *) ident, 0, 255);
          res = read(fd,buf,255);   /* read 1 char */ 
          /*  printf("scan mode -- looking for a badge : %s\n",buf);  */
          i = 0;  
          chksum = 0; 
          /* badge starts out with some '{{{{' chars, at least 5 */ 
	  if (buf[0]  == '{') { 
	    while (buf[0] == '{') {  
                     res=read(fd,buf,255);
                    i++; 
                    /* printf("header mode: %s\n",buf);   */ 
            } 
            if (i < 5) continue; /* bad string */  
            /* now we've read the first data character, put it in ident */ 
            i = 0; 
            /* keep reading data until you hit a '}' */ 
            while (buf[0] != '}' & i < 30 ) { 
                    ident[i]=buf[0];
                    chksum = (chksum + (jbyte) buf[0]) % 256; 
		    i++; 
                    res = read(fd,buf,255); 
            }  
            j = 0; 
            while (buf[0] == '}') { 
                    res=read(fd,buf,255);
                    j++; 
                    /* printf("tail mode: %s\n",buf);   */
            }  
            if (j < 5) continue; /* bad string */   
	    fprintf(stderr,"(%s) checksum computed = %d, checksum xmit = %d\n",
			ident, (jbyte) 
 chksum, buf[0]);        
            if ( buf[0] != (jbyte) chksum) continue; /* bad string */ 
            ident[i] = 0; /* terminate the string */  
            /* printf("%d: Identified a badge:%s\n",  k, ident); */ 
            /* copy the string into the java parameter */ 
            (*env)->SetByteArrayRegion(env,b,0,i,ident); 
            return(0); /* got a good string */ 
          }
        }
       }



JNIEXPORT jint JNICALL Java_ReadIR_closeIR(JNIEnv *env, jobject obj) {
        /* restore the old port settings */ 
	tcsetattr(fd,TCSANOW,&oldtio); 
}






