Exemple #1
0
/*----------------------------------------------------------
I2CPort.writeByte

   accept:      byte to write (passed as int)
   perform:     write a single byte to the port
   return:      none
   exceptions:  IOException
----------------------------------------------------------*/ 
JNIEXPORT void JNICALL Java_gnu_io_I2CPort_writeByte( JNIEnv *env,
	jobject jobj, jint ji ) 
{
	unsigned char byte = (unsigned char)ji;
	int fd = get_java_var( env, jobj,"fd","I" );
	int result;

	do {
		result=write (fd, &byte, sizeof(unsigned char));
	}  while (result < 0 && errno==EINTR);
	if(result >= 0)
		return;
	throw_java_exception( env, IO_EXCEPTION, "writeByte",
		strerror( errno ) );
}
Exemple #2
0
JNIEXPORT void JNICALL Java_gnu_io_RS485Port_NativeEnableReceiveTimeoutThreshold(JNIEnv *env, jobject jobj, jint vtime, jint threshold, jint buffer)
{
	int fd = get_java_var( env, jobj,"fd","I" );
	struct termios ttyset;

	if( tcgetattr( fd, &ttyset ) < 0 ) goto fail;
	ttyset.c_cc[ VMIN ] = threshold;
	ttyset.c_cc[ VTIME ] = vtime/100;
	if( tcsetattr( fd, TCSANOW, &ttyset ) < 0 ) goto fail;

	return;
fail:
	throw_java_exception( env, IO_EXCEPTION, "TimeoutThreshold", strerror( errno ) );
	return;
}
Exemple #3
0
/*----------------------------------------------------------
 RS485Port.writeByte

 accept:      byte to write (passed as int)
 perform:     write a single byte to the port
 return:      none
 exceptions:  IOException
 ----------------------------------------------------------*/
JNIEXPORT void JNICALL Java_gnu_io_RS485Port_writeByte( JNIEnv *env,
		jobject jobj, jint ji )
{
	unsigned char byte = (unsigned char)ji;
	int fd = get_java_var( env, jobj,"fd","I" );
	int result=0,count=0;

	/* turn on the DTR */
	ioctl(fd, TIOCMGET, &result);
	result |= TIOCM_DTR;
	ioctl(fd, TIOCMSET, &result);

	/* send the data */
	do {
		result=write (fd, &byte, sizeof(unsigned char));
	}while (result < 0 && errno==EINTR);
	if(result < 0) goto fail;
	/* wait for the last bit to go 
	 * see get_lsr_info in linux/driver/char/serial.c 
	 * */
#if defined(TIOCSERGETLSR) /* dima ????????? I did it in exactly the same way as in SerialImp.c */
	do
	{
		result=ioctl(fd, TIOCSERGETLSR);
		/*  FIXME this should work but its a hack  */
		if (result != TIOCSER_TEMT)
		{
			usleep(100);
		}
	}while(result != TIOCSER_TEMT);
#endif /* TIOCSERGETLSR */
	/* shut down the DTR */
	ioctl(fd, TIOCMGET, &result);
	result &= ~TIOCM_DTR;
	ioctl(fd, TIOCMSET, &result);

	/* flush input (we dont want to get our own message */
	do {
		result=tcflush(fd, TCIFLUSH);
	}while (result && errno==EINTR && count <5);

	if(result) goto fail;

	return;
	fail:
	throw_java_exception( env, IO_EXCEPTION, "writeByte",
			strerror( errno ) );
}
Exemple #4
0
/*----------------------------------------------------------
LPRPort.isPrinterSelected
   accept:      none
   perform:     check if printer is selected
   return:      JNI_TRUE if printer is selected other wise JNI_FALSE
   exceptions:  none
   comments:    LP_SELEC   unchanged selected input, active high
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL LPRPort(isPrinterSelected)(JNIEnv *env,
	jobject jobj)
{
	int fd = get_java_var( env, jobj,"fd","I" );
#if defined (__linux__)
	int status;
	ioctl(fd, LPGETSTATUS, &status);
	return( status & LP_SELEC ? JNI_TRUE : JNI_FALSE );
#elif defined (WIN32)
	return getWin32ParallelStatus( fd, PARALLEL_SELECTED); 
#else
/*  FIXME??  */
	printf("ParallelImp.c LPGETSTATUS not defined\n");
	return(JNI_FALSE);
#endif
}
Exemple #5
0
/*----------------------------------------------------------
LPRPort.nativeavailable

   accept:      none
   perform:     find out the number of bytes available for reading
   return:      available bytes
                -1 on error
   exceptions:  none
----------------------------------------------------------*/
JNIEXPORT jint JNICALL LPRPort(nativeavailable)( JNIEnv *env,
	jobject jobj )
{
	int fd = get_java_var( env, jobj,"fd","I" );
	int result;
/*
	char message[80];

	ENTER( "LPRPort:nativeavailable" );
*/
/*
    On SCO OpenServer FIONREAD always fails for serial devices,
    so try ioctl FIORDCHK instead; will only tell us whether
    bytes are available, not how many, but better than nothing.

    This turns out to be true on Solaris also.  taj.
*/
#ifdef FIORDCHK  /* __unixware__ __sun__ probably others */
	result = ioctl(fd, FIORDCHK, 0);
#else
	if( ioctl( fd, FIONREAD, &result ) < 0 )
	{
		goto fail;
	}
#endif /* FIORDCHK */
	if (result == -1) {
		goto fail;
	}
	if( result )
	{
/*		sprintf(message, "    nativeavailable: FIORDCHK result %d, \
				errno %d\n", result , result == -1 ? errno : 0);
		report( message );
*/
	}
/*
	LEAVE( "LPRPort:nativeavailable" );
*/
	return (jint)result;
fail:
/*
	report("LPRPort:nativeavailable:  ioctl() failed\n");
	LEAVE( "LPRPort:nativeavailable" );
*/
	throw_java_exception_system_msg( env, IO_EXCEPTION, "nativeavailable" );
	return (jint)result;
}
Exemple #6
0
/*----------------------------------------------------------
LPRPort.writeArray

   accept:      jbarray: bytes used for writing
                offset: offset in array to start writing
                count: Number of bytes to write
   perform:     write length bytes of jbarray
   return:      none
   exceptions:  IOException
----------------------------------------------------------*/
JNIEXPORT void JNICALL LPRPort(writeArray)( JNIEnv *env,
	jobject jobj, jbyteArray jbarray, jint offset, jint count )
{
#ifdef WIN32
	DWORD countWritten; /* Fixme, should be a loop until all is written */
	COMMTIMEOUTS timeouts;
	int errorCount = 0;
#endif
	int fd = get_java_var( env, jobj,"fd","I" );
	jbyte *body = (*env)->GetByteArrayElements( env, jbarray, 0 );
	unsigned char *bytes = (unsigned char *)malloc( count );
	int i;
	for( i = 0; i < count; i++ ) bytes[ i ] = body[ i + offset ];
	(*env)->ReleaseByteArrayElements( env, jbarray, body, 0 );
#ifdef WIN32
	/*
	we set a timeout because all calls are sequentiell (also with asynchron)
	 this means that the default timeout of unlimited
	blocks all calls (also close and status request) if the device is down
	*/
	GetCommTimeouts( (HANDLE)fd, &timeouts );
	timeouts.WriteTotalTimeoutMultiplier = 0;
	timeouts.WriteTotalTimeoutConstant = 2000; /*  2000 is the min value for the default Windows NT and Windows 2000 driver */
	SetCommTimeouts( (HANDLE)fd, &timeouts );
	while( count > 0 ){
		if(!WriteFile( (HANDLE)fd, bytes, count, &countWritten, NULL ) && countWritten == 0){
			/*
			this are 20 * 2 seconds, in this time a printer (or other parallel device)
			should solv all problems like buffer full, etc
			*/
			if(errorCount++ < 20){
				Sleep( 20 ); /* make a small pause to execute all other requests in all other threads */
				continue;
			}
			throw_java_exception_system_msg( env, IO_EXCEPTION, "writeArray" );
			break;
		}
		errorCount = 0;
		bytes += countWritten;
		count -= countWritten;
	}
#else
	if( write( fd, bytes, count ) < 0 )
		throw_java_exception_system_msg( env, IO_EXCEPTION, "writeArray" );
#endif
	free( bytes );
}
Exemple #7
0
/*----------------------------------------------------------
LPRPort.isPrinterTimedOut
   accept:       none
   perform:      Not really sure see isPaperOut
   return:       JNI_FALSE if the printer does not return out of paper other
                 wise JNI_TRUE.
   exceptions:   none
   comments:     Is this documented right in the javadocs?
	         not sure this is correct FIXME
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL LPRPort(isPrinterTimedOut)(JNIEnv *env,
	jobject jobj)
{
#if defined(__linux__)
	int fd = get_java_var( env, jobj,"fd","I" );
	int status;
	ioctl(fd, LPGETSTATUS, &status);
	return( status & LP_BUSY ? JNI_TRUE : JNI_FALSE );
#endif
#if defined(__FreeBSD__)
	printf("ParallelImp.c LPGETSTATUS not defined\n");
	/*
	return( status & EBUSY ? JNI_TRUE : JNI_FALSE );
	*/
#endif
	return( JNI_FALSE );
}
Exemple #8
0
/*----------------------------------------------------------
LPRPort.isPrinterError
   accept:      none
   perform:     check for printer error
   return:      JNI_TRUE if there is an printer error otherwise JNI_FALSE
   exceptions:  none
   comments:    LP_ERR   unchanged error input, active low
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL LPRPort(isPrinterError)(JNIEnv *env,
	jobject jobj)
{
	int fd = get_java_var( env, jobj,"fd","I" );
#if defined (__linux__)
	int status;
	ioctl(fd, LPGETSTATUS, &status);
	return( status & LP_ERR ? JNI_TRUE : JNI_FALSE );
#elif defined (WIN32)
	return getWin32ParallelStatus( fd, PARALLEL_PAPER_EMPTY | 
									   PARALLEL_OFF_LINE |
									   PARALLEL_POWER_OFF |
									   PARALLEL_NOT_CONNECTED |
									   PARALLEL_BUSY); 
#else
/*  FIXME??  */
	printf("ParallelImp.c LPGETSTATUS not defined\n");
	return(JNI_FALSE);
#endif
}
Exemple #9
0
/*----------------------------------------------------------
I2CPort.writeArray

   accept:      jbarray: bytes used for writing 
                offset: offset in array to start writing
                count: Number of bytes to write
   perform:     write length bytes of jbarray
   return:      none
   exceptions:  IOException
----------------------------------------------------------*/ 
JNIEXPORT void JNICALL Java_gnu_io_I2CPort_writeArray( JNIEnv *env,
	jobject jobj, jbyteArray jbarray, jint offset, jint count )
{
	int fd = get_java_var( env, jobj,"fd","I" );
	int result=0,total=0,i;

	unsigned char *bytes = (unsigned char *)malloc( count );

	jbyte *body = (*env)->GetByteArrayElements( env, jbarray, 0 );
	for( i = 0; i < count; i++ ) bytes[ i ] = body[ i + offset ];
	(*env)->ReleaseByteArrayElements( env, jbarray, body, 0 );
	do {
		result=write (fd, bytes + total + offset, count - total); /* dima */
		if(result >0){
			total += result;
		}
	}  while ((total<count)||(result < 0 && errno==EINTR));
	free( bytes );
	if( result < 0 ) throw_java_exception( env, IO_EXCEPTION,
		"writeArray", strerror( errno ) );
}
Exemple #10
0
/*----------------------------------------------------------
LPRPort.isPrinterBusy
   accept:      none
   perform:     Check to see if the printer is printing.
   return:      JNI_TRUE if the printer is Busy, JNI_FALSE if its idle
   exceptions:  none
   comments:    LP_BUSY     inverted busy input, active high
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL LPRPort(isPrinterBusy)(JNIEnv *env,
	jobject jobj)
{
	int fd = get_java_var( env, jobj,"fd","I" );
	int status;
#if defined (__linux__)
	ioctl(fd, LPGETSTATUS, &status);
#elif defined (WIN32)
	return getWin32ParallelStatus( fd, PARALLEL_BUSY); 
#else
/*  FIXME??  */
	printf("ParallelImp.c LPGETSTATUS not defined\n");
#endif
#if defined(__linux__)
	return( status & LP_BUSY ? JNI_TRUE : JNI_FALSE );
#endif
#if defined(__FreeBSD__)
	return( status & EBUSY ? JNI_TRUE : JNI_FALSE );
#endif
	return(JNI_FALSE);
}
Exemple #11
0
/*----------------------------------------------------------
I2CPort.eventLoop

   accept:      none
   perform:     periodically check for I2CPortEvents
   return:      none
   exceptions:  none
   comments:    FIXME This is probably wrong on bsd.
----------------------------------------------------------*/ 
JNIEXPORT void JNICALL Java_gnu_io_I2CPort_eventLoop( JNIEnv *env,
	jobject jobj )
{
	int fd, ret, change;
	fd_set rfds;
	struct timeval tv_sleep;
	unsigned int mflags;
#if defined(TIOCGICOUNT)
	struct serial_icounter_struct sis, osis;
#endif /* TIOCGICOUNT */
	unsigned int omflags;

	jmethodID method, interrupt;
	jboolean interrupted = 0;
	jclass jclazz, jthread;
	jclazz = (*env)->GetObjectClass( env, jobj );
	fd = get_java_var(env, jobj, "fd", "I");
	method = (*env)->GetMethodID( env, jclazz, "sendEvent", "(IZ)V" );
	jthread = (*env)->FindClass( env, "java/lang/Thread" );
	interrupt = (*env)->GetStaticMethodID( env, jthread, "interrupted", "()Z" );

	/* Some multiport i2c cards do not implement TIOCGICOUNT ... */
#if defined(TIOCGICOUNT)
	if( ioctl( fd, TIOCGICOUNT, &osis ) < 0 ) {
		fprintf( stderr, "Port does not support TIOCGICOUNT events\n" );
		return; 
	}
#else
	fprintf( stderr, "Port does not support all Hardware events\n" );
#endif /*  TIOCGICOUNT */

	if( ioctl( fd, TIOCMGET, &omflags) <0 ) {
		fprintf( stderr, "Port does not support events\n" );
 		return;
	}

	FD_ZERO( &rfds );
	while( !interrupted ) {
		FD_SET( fd, &rfds );
		/* Check every 1 second, or on receive data */
		tv_sleep.tv_sec = 1; 
		tv_sleep.tv_usec = 0;
		do {
			ret=select( fd + 1, &rfds, NULL, NULL, &tv_sleep );
		}  while (ret < 0 && errno==EINTR);
		if( ret < 0 ) {
			fprintf( stderr, "select() Failed\n" );
			break; 
		}

#if defined TIOCSERGETLSR
		if( ioctl( fd, TIOCSERGETLSR, &change ) ) {
			fprintf( stderr, "TIOCSERGETLSR Failed\n" );
			break;
		}
		else if( change ) {
			(*env)->CallVoidMethod( env, jobj, method,
				(jint)SPE_OUTPUT_BUFFER_EMPTY, JNI_TRUE );
		}
#endif /* TIOCSERGETLSR */
#if defined(TIOCGICOUNT)
	/*	wait for RNG, DSR, CD or CTS  but not DataAvailable
	 *      The drawback here is it never times out so if someone
	 *      reads there will be no chance to try again.
	 *      This may make sense if the program does not want to 
	 *      be notified of data available or errors.
	 *	ret=ioctl(fd,TIOCMIWAIT);
	 */
		if( ioctl( fd, TIOCGICOUNT, &sis ) ) {
			fprintf( stderr, "TIOCGICOUNT Failed\n" );
			break; 
		}
		while( sis.frame != osis.frame ) {
			(*env)->CallVoidMethod( env, jobj, method, (jint)SPE_FE, JNI_TRUE );
			osis.frame++;
		}
		while( sis.overrun != osis.overrun ) {
			(*env)->CallVoidMethod( env, jobj, method, (jint)SPE_OE, JNI_TRUE );
			osis.overrun++;
		}
		while( sis.parity != osis.parity ) {
			(*env)->CallVoidMethod( env, jobj, method, (jint)SPE_PE, JNI_TRUE );
			osis.parity++;
		}
		while( sis.brk != osis.brk ) {
			(*env)->CallVoidMethod( env, jobj, method, (jint)SPE_BI, JNI_TRUE );
			osis.brk++;
		}
		osis = sis;
#endif /*  TIOCGICOUNT */
		if( ioctl( fd, TIOCMGET, &mflags ) ) {
			fprintf( stderr, "TIOCMGET Failed\n" );
			break; 
		}
		interrupted = (*env)->CallStaticBooleanMethod( env, jthread, interrupt );
	       /* A Portable implementation */
		change = (mflags&TIOCM_CTS) - (omflags&TIOCM_CTS);
		if( change ) {
			fprintf(stderr, "Sending SPE_CTS\n");
			(*env)->CallVoidMethod( env, jobj, method,
				(jint)SPE_CTS, JNI_TRUE );
		}
		change = (mflags&TIOCM_DSR) - (omflags&TIOCM_DSR);
		if( change ) {
			fprintf(stderr, "Sending SPE_DSR\n");
			(*env)->CallVoidMethod( env, jobj, method,
				(jint)SPE_DSR, JNI_TRUE );
		}
		change = (mflags&TIOCM_RNG) - (omflags&TIOCM_RNG);
		if( change ) {
			fprintf(stderr, "Sending SPE_RI\n");
			(*env)->CallVoidMethod( env, jobj, method,
				(jint)SPE_RI, JNI_TRUE );
		}
		change = (mflags&TIOCM_CD) - (omflags&TIOCM_CD);
		if( change ) {
			fprintf(stderr, "Sending SPE_CD\n");
			(*env)->CallVoidMethod( env, jobj, method,
				(jint)SPE_CD, JNI_TRUE );
		}
		omflags = mflags;
		if( ioctl( fd, FIONREAD, &change ) ) {
			fprintf( stderr, "FIONREAD Failed\n" );
		}
		else if( change ) {
			(*env)->CallVoidMethod( env, jobj, method,
				(jint)SPE_DATA_AVAILABLE, JNI_TRUE );
			usleep(1000); /* select wont block */
		}
	}
	return;
}
Exemple #12
0
/*----------------------------------------------------------
I2CPort.sendBreak

   accept:     duration in milliseconds.
   perform:    send break for actual time.  not less than 0.25 seconds.
   exceptions: none
   comments:   not very precise
----------------------------------------------------------*/ 
JNIEXPORT void JNICALL Java_gnu_io_I2CPort_sendBreak( JNIEnv *env,
	jobject jobj, jint duration )
{
	int fd = get_java_var( env, jobj,"fd","I" );
	tcsendbreak( fd, (int)( duration / 250 ) );
}
Exemple #13
0
/*----------------------------------------------------------
LPRPort.eventLoop

   accept:      none
   perform:     periodically check for ParallelPortEvents
   return:      none
   exceptions:  none
   comments:    lots of work needed here.  Yes its a mess.
struct lp_stats
{
	unsigned long chars;
	unsigned long sleeps;
	unsigned int maxrun;
	unsigned int maxwait;
	unsigned int meanwait;
	unsigned int mdev;
};

----------------------------------------------------------*/
JNIEXPORT void JNICALL LPRPort(eventLoop)( JNIEnv *env,
	jobject jobj )
{
	int fd, ret;
	unsigned int pflags = 0;
	fd_set rfds;
	struct timeval sleep;
	jboolean interrupted = 0;

	fd = get_java_var( env, jobj,"fd","I" );

	interrupted = is_interrupted(env, jobj);

	FD_ZERO( &rfds );
	while( !interrupted )
	{
		FD_SET( fd, &rfds );
		/* Check every 1 second, or on receive data */
		sleep.tv_sec = 1;	
		sleep.tv_usec = 0;
		do {
			ret = select( fd + 1, &rfds, NULL, NULL, &sleep );
		}
		while (ret < 0 && errno == EINTR);
		if( ret < 0 ) break;
		interrupted = is_interrupted(env, jobj);
		if(interrupted) {
			return;
		}

#if defined(LPGETSTATUS)
		ioctl( fd, LPGETSTATUS, &pflags );
#elif defined(WIN32)
		pflags = getWin32ParallelStatusFlags(fd);
#else
	/*  FIXME??  */
	printf("ParallelImp.c LPGETSTATUS is undefined!\n");
#endif

/*
			PAR_EV_BUFFER:
			PAR_EV_ERROR:
*/

#if defined(PARALLEL_BUSY)
		if (pflags & PARALLEL_BUSY)
			send_event( env, jobj, PAR_EV_ERROR, JNI_TRUE );
#elif defined(LP_BUSY)
		if (pflags&LP_BUSY)    /* inverted input, active high */
			send_event( env, jobj, PAR_EV_ERROR, JNI_TRUE );
#elif defined(EBUSY)
		if (pflags&EBUSY)    /* inverted input, active high */
			send_event( env, jobj, PAR_EV_ERROR, JNI_TRUE );
#endif /* EBUSY LP_BUSY */
/*  FIXME  this has moved into the ifdef __kernel__?  Need to get the
           posix documentation on this.
		if (pflags&LP_ACK)
			send_event( env, jobj, PAR_EV_ERROR, JNI_TRUE );
*/


#if defined (__linux__)
		/* unchanged input, active low */
		if (pflags&LP_NOPA)   /* unchanged input, active high */
			send_event( env, jobj, PAR_EV_ERROR, 1 );
		if (pflags&LP_SELEC)  /* unchanged input, active high */
			send_event( env, jobj, PAR_EV_ERROR, 1 );
		if (pflags&LP_ERR)  /* unchanged input, active low */
			send_event( env, jobj, PAR_EV_ERROR, 1 );
#else
	/*  FIXME??  */
	printf("ParallelImp.c LPGETSTATUS is undefined!\n");
#endif
		usleep(1000);
	}
	return;
}