/*---------------------------------------------------------- I2CPort.readArray accept: offset (offset to start storing data in the jbarray) and Length (bytes to read) perform: read bytes from the port into a byte array return: bytes read on success 0 on read timeout exceptions: IOException comments: throws ArrayIndexOutOfBoundsException if asked to read more than SSIZE_MAX bytes ----------------------------------------------------------*/ JNIEXPORT jint JNICALL Java_gnu_io_I2CPort_readArray( JNIEnv *env, jobject jobj, jbyteArray jbarray, jint offset, jint length ) { int bytes; jbyte *body; unsigned char *buffer; int fd = get_java_var( env, jobj, "fd", "I" ); int timeout = get_java_var( env, jobj, "timeout", "I" ); if( (size_t) length > SSIZE_MAX || length < 0 ) { throw_java_exception( env, ARRAY_INDEX_OUT_OF_BOUNDS, "readArray", "Invalid length" ); return -1; } buffer = (unsigned char *)malloc( sizeof( unsigned char ) * length ); if( buffer == 0 ) { throw_java_exception( env, OUT_OF_MEMORY, "readArray", "Unable to allocate buffer" ); return -1; } bytes = read_byte_array( fd, buffer, length, timeout ); if( bytes < 0 ) { free( buffer ); throw_java_exception( env, IO_EXCEPTION, "readArray", strerror( errno ) ); return -1; } body = (*env)->GetByteArrayElements( env, jbarray, 0 ); memcpy(body + offset, buffer, bytes); (*env)->ReleaseByteArrayElements( env, jbarray, body, 0 ); free( buffer ); return (bytes ? bytes : -1); }
// TheTransportRegistry::remove_inst void JNICALL Java_OpenDDS_DCPS_transport_TheTransportRegistry_remove_1inst (JNIEnv * jni, jclass, jobject jobj) { try { OpenDDS::DCPS::TransportInst_rch inst(recoverCppObj<OpenDDS::DCPS::TransportInst>(jni, jobj), false); // Don't take ownership if (inst != 0) { TheTransportRegistry->remove_inst(inst); } } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); } catch (const OpenDDS::DCPS::Transport::Exception &te) { throw_java_exception(jni, te); } }
// TheTransportRegistry::global_config void JNICALL Java_OpenDDS_DCPS_transport_TheTransportRegistry_global_1config__LOpenDDS_DCPS_transport_TransportConfig_2 (JNIEnv * jni, jclass, jobject jobj) { try { OpenDDS::DCPS::TransportConfig_rch config(recoverCppObj<OpenDDS::DCPS::TransportConfig>(jni, jobj), false); // Don't take ownership if (config != 0) { TheTransportRegistry->global_config(config); } } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); } catch (const OpenDDS::DCPS::Transport::Exception &te) { throw_java_exception(jni, te); } }
/*---------------------------------------------------------- I2CPort.nativeSetI2CPortParams accept: speed, data bits, stop bits, parity perform: set the i2c port parameters return: void exceptions: UnsupportedCommOperationException ----------------------------------------------------------*/ JNIEXPORT void JNICALL Java_gnu_io_I2CPort_nativeSetI2CPortParams( JNIEnv *env, jobject jobj, jint speed, jint dataBits, jint stopBits, jint parity ) { struct termios ttyset; int fd = get_java_var( env, jobj,"fd","I" ); int cspeed = translate_speed( env, speed ); if( !cspeed ) return; if( tcgetattr( fd, &ttyset ) < 0 ) goto fail; if( !translate_data_bits( env, (int *)&(ttyset.c_cflag), dataBits ) ) return; /* dima darwin defime c_cflag as unsigned long */ if( !translate_stop_bits( env, (int *)&(ttyset.c_cflag), stopBits ) ) return; /* dima darwin defime c_cflag as unsigned long */ if( !translate_parity( env, (int *)&(ttyset.c_cflag), parity ) ) return;/* dima darwin defime c_cflag as unsigned long */ #ifdef __FreeBSD__ if( cfsetspeed( &ttyset, cspeed ) < 0 ) goto fail; #else if( cfsetispeed( &ttyset, cspeed ) < 0 ) goto fail; if( cfsetospeed( &ttyset, cspeed ) < 0 ) goto fail; #endif if( tcsetattr( fd, TCSANOW, &ttyset ) < 0 ) goto fail; /* dump_termios("set",*ttyset); */ return; fail: throw_java_exception( env, UNSUPPORTED_COMM_OPERATION, "nativeSetI2CPortParams", strerror( errno ) ); }
/*---------------------------------------------------------- translate_speed accept: speed in bits-per-second perform: convert bits-per-second to a speed_t constant return: speed_t constant exceptions: UnsupportedCommOperationException comments: Only the lowest level code should know about the magic constants. ----------------------------------------------------------*/ int translate_speed( JNIEnv *env, jint speed ) { switch( speed ) { case 0: return B0; case 50: return B50; case 75: return B75; case 110: return B110; case 134: return B134; case 150: return B150; case 200: return B200; case 300: return B300; case 600: return B600; case 1200: return B1200; case 1800: return B1800; case 2400: return B2400; case 4800: return B4800; case 9600: return B9600; case 19200: return B19200; case 38400: return B38400; case 57600: return B57600; case 115200: return B115200; case 230400: return B230400; #ifdef B460800 case 460800: return B460800; #endif } throw_java_exception( env, UNSUPPORTED_COMM_OPERATION, "translate_speed", "speed" ); return 0; }
/*---------------------------------------------------------- translate_parity accept: gnu.io.I2CPort.PARITY_* constant perform: set proper termios c_cflag bits return: 1 if successful 0 if an exception is thrown exceptions: UnsupportedCommOperationException comments: The CMSPAR bit should be used for 'mark' and 'space' parity, but it's not in glibc's includes. Oh well, rarely used anyway. ----------------------------------------------------------*/ int translate_parity( JNIEnv *env, int *cflag, jint parity ) { (*cflag) &= ~(PARENB | PARODD); switch( parity ) { case PARITY_NONE: return 1; #ifdef CMSPAR case PARITY_EVEN: (*cflag) |= PARENB; return 1; case PARITY_ODD: (*cflag) |= PARENB | PARODD; return 1; case PARITY_MARK: (*cflag) |= PARENB | PARODD | CMSPAR; return 1; case PARITY_SPACE: (*cflag) |= PARENB | CMSPAR; return 1; #else case PARITY_EVEN: (*cflag) |= PARENB; return 1; case PARITY_ODD: (*cflag) |= PARENB | PARODD; return 1; #endif } throw_java_exception( env, UNSUPPORTED_COMM_OPERATION, "translate_parity", "parity" ); return 0; }
/*---------------------------------------------------------- I2CPort.setflowcontrol accept: flowmode FLOWCONTROL_NONE none FLOWCONTROL_RTSCTS_IN hardware flow control FLOWCONTROL_RTSCTS_OUT "" FLOWCONTROL_XONXOFF_IN input software flow control FLOWCONTROL_XONXOFF_OUT output software flow control perform: set flow control to flowmode return: none exceptions: IOException comments: there is no differentiation between input and output hardware flow control ----------------------------------------------------------*/ JNIEXPORT void JNICALL Java_gnu_io_I2CPort_setflowcontrol( JNIEnv *env, jobject jobj, jint flowmode ) { struct termios ttyset; int fd = get_java_var( env, jobj,"fd","I" ); if( tcgetattr( fd, &ttyset ) ) goto fail; if ( flowmode & ( FLOWCONTROL_RTSCTS_IN | FLOWCONTROL_RTSCTS_OUT ) ) ttyset.c_cflag |= HARDWARE_FLOW_CONTROL; else ttyset.c_cflag &= ~HARDWARE_FLOW_CONTROL; ttyset.c_iflag &= ~IXANY; if ( flowmode & FLOWCONTROL_XONXOFF_IN ) ttyset.c_iflag |= IXOFF; else ttyset.c_iflag &= ~IXOFF; if ( flowmode & FLOWCONTROL_XONXOFF_OUT ) ttyset.c_iflag |= IXON; else ttyset.c_iflag &= ~IXON; if( tcsetattr( fd, TCSANOW, &ttyset ) ) goto fail; return; fail: throw_java_exception( env, IO_EXCEPTION, "setHWFC", strerror( errno ) ); return; }
/*---------------------------------------------------------- RS485Port.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_RS485Port_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 ); /* turn on the DTR */ ioctl(fd, TIOCMGET, &result); result |= TIOCM_DTR; ioctl(fd, TIOCMSET, &result); /* send the data */ do { result=write (fd, bytes + total, count - total); if(result >0) { total += result; } }while ((total<count)||(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; free( bytes ); return; fail: free( bytes ); throw_java_exception( env, IO_EXCEPTION, "writeArray", strerror( errno ) ); }
void JNICALL Java_i2jrt_ORB_destroy(JNIEnv *jni, jobject jThis) { try { recoverTaoORB(jni, jThis)->destroy(); } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); } }
void JNICALL Java_i2jrt_ORB_shutdown(JNIEnv *jni, jobject jThis, jboolean wait) { try { recoverTaoORB(jni, jThis)->shutdown(wait); } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); } }
// TheTransportRegistry::get_inst jobject JNICALL Java_OpenDDS_DCPS_transport_TheTransportRegistry_get_1inst (JNIEnv * jni, jclass, jstring name) { JStringMgr jsm_name(jni, name); try { OpenDDS::DCPS::TransportInst_rch inst = TheTransportRegistry->get_inst(jsm_name.c_str()); return constructTransportInst(jni, inst); } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); return 0; } catch (const OpenDDS::DCPS::Transport::Exception &te) { throw_java_exception(jni, te); return 0; } }
// TheTransportRegistry::bind_config void JNICALL Java_OpenDDS_DCPS_transport_TheTransportRegistry_bind_1config__Ljava_lang_String_2LDDS_Entity_2 (JNIEnv * jni, jclass, jstring name, jobject entity_jobj) { JStringMgr jsm_name(jni, name); try { DDS::Entity_var entity; copyToCxx(jni, entity, entity_jobj); TheTransportRegistry->bind_config(jsm_name.c_str(), entity.in()); } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); } catch (const OpenDDS::DCPS::Transport::Exception &te) { throw_java_exception(jni, te); } }
// TheTransportRegistry::bind_config void JNICALL Java_OpenDDS_DCPS_transport_TheTransportRegistry_bind_1config__LOpenDDS_DCPS_transport_TransportConfig_2LDDS_Entity_2 (JNIEnv * jni, jclass, jobject config_jobj, jobject entity_jobj) { try { OpenDDS::DCPS::TransportConfig_rch config(recoverCppObj<OpenDDS::DCPS::TransportConfig>(jni, config_jobj), false); // Don't take ownership DDS::Entity_var entity; copyToCxx(jni, entity, entity_jobj); TheTransportRegistry->bind_config(config, entity.in()); } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); } catch (const OpenDDS::DCPS::Transport::Exception &te) { throw_java_exception(jni, te); } }
void throw_java_exception_system_msg( JNIEnv *env, char *exc, char *foo ) { #ifdef WIN32 char *allocTextBuf; FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&allocTextBuf, 16, NULL ); throw_java_exception( env, exc, foo, allocTextBuf ); LocalFree(allocTextBuf); #else throw_java_exception( env, exc, foo, strerror( errno ) ); #endif }
/*---------------------------------------------------------- LPRPort.readArray accept: offset (bytes to skip) and Length (bytes to read) perform: read bytes from the port into a byte array return: bytes read on success 0 on read timeout exceptions: IOException comments: throws IOException if asked to read > SSIZE_MAX ----------------------------------------------------------*/ JNIEXPORT jint JNICALL LPRPort(readArray)( JNIEnv *env, jobject jobj, jbyteArray jbarray, jint offset, jint length ) { int bytes, i, fd, threshold, timeout; jbyte *body; unsigned char *buffer; fd = get_java_var( env, jobj,"fd","I" ); threshold = get_java_var( env, jobj,"threshold","I" ); timeout = get_java_var( env, jobj,"threshold","I" ); if( (size_t) length < 1 || (size_t) length > SSIZE_MAX ) { throw_java_exception( env, IO_EXCEPTION, "readArray", "Invalid length" ); return -1; } buffer = (unsigned char *)malloc( sizeof( unsigned char ) * length ); if( buffer == 0 ) { throw_java_exception( env, IO_EXCEPTION, "readArray", "Unable to allocate buffer" ); return -1; } bytes = read_byte_array( fd, buffer, length, threshold, timeout ); if( bytes < 0 ) { free( buffer ); throw_java_exception_system_msg( env, IO_EXCEPTION, "readArray" ); return -1; } body = (*env)->GetByteArrayElements( env, jbarray, 0 ); for( i = 0; i < bytes; i++ ) body[ i + offset ] = buffer[ i ]; (*env)->ReleaseByteArrayElements( env, jbarray, body, 0 ); free( buffer ); return (bytes ? bytes : -1); }
// TheTransportRegistry::global_config jobject JNICALL Java_OpenDDS_DCPS_transport_TheTransportRegistry_global_1config__ (JNIEnv * jni, jclass) { try { OpenDDS::DCPS::TransportConfig_rch config = TheTransportRegistry->global_config(); jclass configClazz = findClass(jni, "OpenDDS/DCPS/transport/TransportConfig"); jmethodID ctor = jni->GetMethodID(configClazz, "<init>", "(J)V"); return jni->NewObject(configClazz, ctor, reinterpret_cast<jlong>(config._retn())); } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); return 0; } catch (const OpenDDS::DCPS::Transport::Exception &te) { throw_java_exception(jni, te); return 0; } }
/*---------------------------------------------------------- RS485Port.NativegetReceiveTimeout accept: none perform: get termios.c_cc[VTIME] return: VTIME comments: see NativeEnableReceiveTimeoutThreshold ----------------------------------------------------------*/ JNIEXPORT jint JNICALL Java_gnu_io_RS485Port_NativegetReceiveTimeout( JNIEnv *env, jobject jobj) { int fd = get_java_var(env, jobj, "fd", "I"); struct termios ttyset; if (tcgetattr(fd, &ttyset) < 0) goto fail; return (ttyset.c_cc[ VTIME] * 100); fail: throw_java_exception(env, IO_EXCEPTION, "getReceiveTimeout", strerror( errno)); return -1; }
/*---------------------------------------------------------- RawPort.nativeClose accept: none perform: get the fd from the java end and close it return: none exceptions: none ----------------------------------------------------------*/ JNIEXPORT jint JNICALL Java_gnu_io_RawPort_nativeClose( JNIEnv *env, jobject jobj ) { int ciAddress = get_java_var( env, jobj,"ciAddress","I" ); if(ioperm(ciAddress, 3, 0)) goto fail; return(0); fail: throw_java_exception( env, IO_EXCEPTION, "close", "failed" ); return -1; }
jobject JNICALL Java_OpenDDS_DCPS_TheParticipantFactory_getInstance(JNIEnv *jni, jclass) { try { jobject j_dpf; copyToJava(jni, j_dpf, TheParticipantFactory, true); return j_dpf; } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); return 0; } }
/*---------------------------------------------------------- RS485Port.NativeisReceiveTimeoutEnabled accept: none perform: determine if VTIME is none 0 return: JNI_TRUE if VTIME > 0 else JNI_FALSE comments: see NativeEnableReceiveTimeoutThreshold ----------------------------------------------------------*/ JNIEXPORT jboolean JNICALL Java_gnu_io_RS485Port_NativeisReceiveTimeoutEnabled( JNIEnv *env, jobject jobj) { int fd = get_java_var(env, jobj, "fd", "I"); struct termios ttyset; if (tcgetattr(fd, &ttyset) < 0) goto fail; return (ttyset.c_cc[ VTIME] > 0 ? JNI_TRUE : JNI_FALSE); fail: throw_java_exception(env, IO_EXCEPTION, "isReceiveTimeoutEnabled", strerror( errno)); return JNI_FALSE; }
/*---------------------------------------------------------- RS485Port.readByte accept: none perform: Read a single byte from the port return: The byte read exceptions: IOException ----------------------------------------------------------*/ JNIEXPORT jint JNICALL Java_gnu_io_RS485Port_readByte(JNIEnv *env, jobject jobj) { int bytes; unsigned char buffer[1]; int fd = get_java_var(env, jobj, "fd", "I"); int timeout = get_java_var(env, jobj, "timeout", "I"); bytes = read_byte_array(fd, buffer, 1, timeout); if (bytes < 0) { throw_java_exception(env, IO_EXCEPTION, "readByte", strerror( errno)); return -1; } return (bytes ? (jint) buffer[0] : -1); }
/*---------------------------------------------------------- RawPort.open accept: The device to open. ie "/dev/ttyS0" perform: open the device, set the termios struct to sane settings and return the filedescriptor return: fd exceptions: IOExcepiton comments: Very often people complain about not being able to get past this function and it turns out to be permissions on the device file or bios has the device disabled. ----------------------------------------------------------*/ JNIEXPORT jint JNICALL Java_gnu_io_RawPort_open( JNIEnv *env, jobject jobj, jint ciAddress ) { if(ioperm(ciAddress, 3, 1)) goto fail; return (0); fail: throw_java_exception( env, IO_EXCEPTION, "open", strerror( errno ) ); return -1; }
/*---------------------------------------------------------- RS485Port.nativeavailable accept: none perform: find out the number of bytes available for reading return: available bytes -1 on error exceptions: none ----------------------------------------------------------*/ JNIEXPORT jint JNICALL Java_gnu_io_RS485Port_nativeavailable(JNIEnv *env, jobject jobj) { int fd = get_java_var(env, jobj, "fd", "I"); int result; if (ioctl(fd, FIONREAD, &result)) { throw_java_exception(env, IO_EXCEPTION, "nativeavailable", strerror( errno)); return -1; } else return (jint) result; }
void JNICALL Java_OpenDDS_DCPS_TheServiceParticipant_set_1repo_1ior (JNIEnv *envp, jclass, jstring ior, jstring repo) { JStringMgr ior_jsm(envp, ior); JStringMgr repo_jsm(envp, repo); try { TheServiceParticipant->set_repo_ior(ior_jsm.c_str(), repo_jsm.c_str()); } catch (const CORBA::SystemException &se) { throw_java_exception(envp, se); } }
jint JNICALL Java_i2jrt_TAOObject__1hash(JNIEnv *jni, jobject jThis, jint i) { CORBA::Object_ptr ptr = recoverTaoObject(jni, jThis); try { return ptr->_hash(i); } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); } return 0; }
/*---------------------------------------------------------- translate_stop_bits accept: gnu.io.RS485Port.STOPBITS_* constant perform: set proper termios c_cflag bits return: 1 if successful 0 if an exception is thrown exceptions: UnsupportedCommOperationException comments: If you specify 5 data bits and 2 stop bits, the port will allegedly use 1.5 stop bits. Does anyone care? ----------------------------------------------------------*/ int translate_stop_bits(JNIEnv *env, int *cflag, jint stopBits) { switch (stopBits) { case STOPBITS_1: (*cflag) &= ~CSTOPB; return 1; case STOPBITS_2: (*cflag) |= CSTOPB; return 1; } throw_java_exception(env, UNSUPPORTED_COMM_OPERATION, "translate_stop_bits", "stop bits"); return 0; }
/*---------------------------------------------------------- I2CPort.drain accept: none perform: wait until all data is transmitted return: none exceptions: IOException comments: java.io.OutputStream.flush() is equivalent to tcdrain, not tcflush, which throws away unsent bytes count logic added to avoid infinite loops when EINTR is true... Thread.yeild() was suggested. ----------------------------------------------------------*/ JNIEXPORT void JNICALL Java_gnu_io_I2CPort_drain( JNIEnv *env, jobject jobj ) { int fd = get_java_var( env, jobj,"fd","I" ); int result, count=0; do { result=tcdrain (fd); count++; } while (result && errno==EINTR && count <5); if( result ) throw_java_exception( env, IO_EXCEPTION, "drain", strerror( errno ) ); }
JNIEXPORT void JNICALL Java_gnu_io_I2CPort_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; }
/*---------------------------------------------------------- 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 ) ); }
jboolean JNICALL Java_i2jrt_TAOObject__1non_1existent(JNIEnv *jni, jobject jThis) { CORBA::Object_ptr ptr = recoverTaoObject(jni, jThis); try { return ptr->_non_existent(); } catch (const CORBA::SystemException &se) { throw_java_exception(jni, se); } return 0; }