Subversion Repositories Programming Utils

Compare Revisions

Ignore whitespace Rev 54 → Rev 55

/trunk/JavaSerial/NativeCode/SerialPortImpl.c
1,6 → 1,9
#ifdef _WIN32
#include <windows.h>
/* Make inline functions work */
#define inline __inline
#define SPEED_SWITCH(SPD,io) case SPD: io.BaudRate = CBR_##SPD; break;
#define GET_SPEED_SWITCH(SPD,io) case CBR_##SPD: return SPD;
40,20 → 43,6
#endif
 
/**
* TODO actually make this an inline function
*/
#define GET_PORT_DESCRIPTOR( array_pos, desc, env, obj ) array_pos = get_handle( env, obj ); \
if( array_pos < 0 || array_pos > port_list_size ){ \
throw_io_exception_message( env, "Unable to get handle" );\
return 0; \
} \
desc = port_list[ array_pos ]; \
if( desc == NULL ){ \
throw_io_exception_message( env, "Unable to get descriptor" ); \
return 0; \
}
 
#include <stdlib.h>
#include <errno.h>
#include <string.h>
85,7 → 74,7
//
// Helper Methods
//
static jint get_handle(JNIEnv * env, jobject obj){
static inline jint get_handle(JNIEnv * env, jobject obj){
jfieldID fid;
jint array_pos;
jclass cls = (*env)->GetObjectClass( env, obj );
100,7 → 89,7
return array_pos;
}
 
static jboolean get_bool( JNIEnv* env, jobject obj, const char* name ){
static inline jboolean get_bool( JNIEnv* env, jobject obj, const char* name ){
jfieldID fid;
jboolean boolVal;
jclass cls = (*env)->GetObjectClass( env, obj );
115,7 → 104,7
return boolVal;
}
 
static int set_baud_rate( struct port_descriptor* desc, int baud_rate ){
static inline int set_baud_rate( struct port_descriptor* desc, int baud_rate ){
GET_SERIAL_PORT_STRUCT( desc->port, newio );
 
switch( baud_rate ){
152,7 → 141,7
return 1;
}
 
static int set_raw_input( struct port_descriptor* desc ){
static inline int set_raw_input( struct port_descriptor* desc ){
GET_SERIAL_PORT_STRUCT( desc->port, newio );
 
#ifdef _WIN32
196,7 → 185,7
/**
* @param data_bits The number of data bits
*/
static int set_data_bits( struct port_descriptor* desc, int data_bits ){
static inline int set_data_bits( struct port_descriptor* desc, int data_bits ){
GET_SERIAL_PORT_STRUCT( desc->port, newio );
 
#ifdef _WIN32
222,7 → 211,7
/**
* @param stop_bits 1 for 1, 2 for 2
*/
static int set_stop_bits( struct port_descriptor* desc, int stop_bits ){
static inline int set_stop_bits( struct port_descriptor* desc, int stop_bits ){
GET_SERIAL_PORT_STRUCT( desc->port, newio );
 
#ifdef _WIN32
247,7 → 236,7
/**
* @param parity 0 for no parity, 1 for odd parity, 2 for even parity
*/
static int set_parity( struct port_descriptor* desc, int parity ){
static inline int set_parity( struct port_descriptor* desc, int parity ){
GET_SERIAL_PORT_STRUCT( desc->port, newio );
 
#ifdef _WIN32
276,7 → 265,7
/**
* @param flow_control 0 for none, 1 for hardware, 2 for software
*/
static int set_flow_control( struct port_descriptor* desc, int flow_control ){
static inline int set_flow_control( struct port_descriptor* desc, int flow_control ){
GET_SERIAL_PORT_STRUCT( desc->port, newio );
 
#ifdef _WIN32
311,7 → 300,7
return 1;
}
 
static void throw_io_exception( JNIEnv * env, int errorNumber ){
static inline void throw_io_exception( JNIEnv * env, int errorNumber ){
#ifdef _WIN32
LPTSTR error_text = NULL;
jclass exception_class;
338,7 → 327,7
#endif /* _WIN32 */
}
 
static void throw_io_exception_message( JNIEnv * env, const char* message ){
static inline void throw_io_exception_message( JNIEnv * env, const char* message ){
jclass exception_class;
(*env)->ExceptionDescribe( env );
(*env)->ExceptionClear( env );
346,6 → 335,24
(*env)->ThrowNew(env, exception_class, message );
}
 
static inline struct port_descriptor* get_port_descriptor( JNIEnv* env, jobject obj ){
int array_pos;
struct port_descriptor* desc;
array_pos = get_handle( env, obj );
if( array_pos < 0 || array_pos > port_list_size ){
throw_io_exception_message( env, "Unable to get handle" );
return NULL;
}
desc = port_list[ array_pos ];
if( desc == NULL ){
throw_io_exception_message( env, "Unable to get descriptor" );
return NULL;
}
return desc;
}
 
//
// JNI Methods
//
434,7 → 441,7
DCB io_name = {0};
io_name.DCBlength = sizeof( io_name );
if (!GetCommState( new_port->port, &io_name ) ) {
LPTSTR error_text = NULL;
LPTSTR error_text = NULL;
jclass exception_class;
(*env)->ExceptionDescribe( env );
(*env)->ExceptionClear( env );
441,19 → 448,6
exception_class = (*env)->FindClass(env, "com/rm5248/serial/NotASerialPortException");
(*env)->ThrowNew(env, exception_class, "You are attempting to open something which is not a serial port" );
free( new_port );
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&error_text,
0,
NULL );
printf("error is %s\n", error_text );
LocalFree( error_text );
return -1;
}
}
601,7 → 595,7
DCB io_name = {0};
io_name.DCBlength = sizeof( io_name );
if (!GetCommState( new_port->port, &io_name ) ) {
LPTSTR error_text = NULL;
LPTSTR error_text = NULL;
jclass exception_class;
(*env)->ExceptionDescribe( env );
(*env)->ExceptionClear( env );
608,19 → 602,6
exception_class = (*env)->FindClass(env, "com/rm5248/serial/NotASerialPortException");
(*env)->ThrowNew(env, exception_class, "You are attempting to open something which is not a serial port" );
free( new_port );
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&error_text,
0,
NULL );
printf("error is %s\n", error_text );
LocalFree( error_text );
return -1;
}
}
677,19 → 658,22
*/
JNIEXPORT void JNICALL Java_com_rm5248_serial_SerialPort_doClose
(JNIEnv * env, jobject obj){
jint array_pos;
//Note: We can't use get_serial_port_struct here, beacuse we need to set
//the position in the array to NULL
int array_pos;
struct port_descriptor* desc;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 || array_pos > port_list_size ){
return;
array_pos = get_handle( env, obj );
if( array_pos < 0 || array_pos > port_list_size ){
throw_io_exception_message( env, "Unable to get handle" );
return;
}
desc = port_list[ array_pos ];
if( desc == NULL ){
throw_io_exception_message( env, "Unable to get descriptor" );
return;
}
 
desc = port_list[ array_pos ];
if( desc == NULL ){
return;
}
 
close( desc->port );
free( desc );
port_list[ array_pos ] = NULL;
702,10 → 686,12
*/
JNIEXPORT jboolean JNICALL Java_com_rm5248_serial_SerialPort_setBaudRate
(JNIEnv * env, jobject obj, jint baud_rate ){
jint array_pos;
struct port_descriptor* desc;
 
GET_PORT_DESCRIPTOR( array_pos, desc, env, obj );
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
return 0;
}
 
return set_baud_rate( desc, baud_rate );
}
717,10 → 703,12
*/
JNIEXPORT jint JNICALL Java_com_rm5248_serial_SerialPort_getBaudRateInternal
(JNIEnv * env, jobject obj){
jint array_pos;
struct port_descriptor* desc;
 
GET_PORT_DESCRIPTOR( array_pos, desc, env, obj );
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
return 0;
}
 
//Now, let's get the baud rate information
{
766,21 → 754,10
*/
JNIEXPORT jboolean JNICALL Java_com_rm5248_serial_SerialPort_setStopBits
(JNIEnv * env, jobject obj, jint bits){
jint array_pos;
struct port_descriptor* desc;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return 0;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return 0;
}
794,21 → 771,10
*/
JNIEXPORT jint JNICALL Java_com_rm5248_serial_SerialPort_getStopBitsInternal
(JNIEnv * env, jobject obj){
jint array_pos;
struct port_descriptor* desc;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return 0;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return 0;
}
 
838,21 → 804,10
*/
JNIEXPORT jboolean JNICALL Java_com_rm5248_serial_SerialPort_setCharSize
(JNIEnv * env, jobject obj, jint size){
jint array_pos;
struct port_descriptor* desc;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return 0;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return 0;
}
866,21 → 821,10
*/
JNIEXPORT jint JNICALL Java_com_rm5248_serial_SerialPort_getCharSizeInternal
(JNIEnv * env, jobject obj){
jint array_pos;
struct port_descriptor* desc;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return 0;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return 0;
}
 
914,21 → 858,10
*/
JNIEXPORT jboolean JNICALL Java_com_rm5248_serial_SerialPort_setParity
(JNIEnv * env, jobject obj, jint parity){
jint array_pos;
struct port_descriptor* desc;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return 0;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return 0;
}
942,21 → 875,10
*/
JNIEXPORT jint JNICALL Java_com_rm5248_serial_SerialPort_getParityInternal
(JNIEnv * env, jobject obj){
jint array_pos;
struct port_descriptor* desc;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return 0;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return 0;
}
 
997,21 → 919,10
*/
JNIEXPORT jboolean JNICALL Java_com_rm5248_serial_SerialPort_setFlowControl
(JNIEnv * env, jobject obj, jint flow){
jint array_pos;
struct port_descriptor* desc;
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return 0;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return 0;
}
1025,21 → 936,10
*/
JNIEXPORT jint JNICALL Java_com_rm5248_serial_SerialPort_getFlowControlInternal
(JNIEnv * env, jobject obj){
jint array_pos;
struct port_descriptor* desc;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return 0;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return 0;
}
1078,22 → 978,11
*/
JNIEXPORT jint JNICALL Java_com_rm5248_serial_SerialPort_getSerialLineStateInternalNonblocking
(JNIEnv * env, jobject obj ){
jint array_pos;
struct port_descriptor* desc;
jint ret_val;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return 0;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return 0;
}
 
1170,22 → 1059,11
*/
JNIEXPORT jint JNICALL Java_com_rm5248_serial_SerialPort_setSerialLineStateInternal
(JNIEnv * env, jobject obj, jobject serial){
jint array_pos;
struct port_descriptor* desc;
jint ret_val;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return 0;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return 0;
}
 
1202,7 → 1080,7
}else{
}
 
//Can't set in Windows
//Can't set DSR in Windows
if( get_bool( env, serial, "dataSetReady" ) ){
}else{
}
1318,6 → 1196,9
// ------------------------------------------------------------------------
//
 
 
#include <stdio.h>
 
/*
* Class: com_rm5248_serial_SerialInputStream
* Method: readByte
1327,7 → 1208,6
(JNIEnv * env, jobject obj){
int stat;
int ret_val;
jint array_pos;
struct port_descriptor* desc;
int get_val = 0;
#ifdef _WIN32
1336,19 → 1216,9
int current_available = 0;
#endif
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return -1;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return -1;
return 0;
}
ret_val = 0;
1486,22 → 1356,11
JNIEXPORT jint JNICALL Java_com_rm5248_serial_SerialInputStream_getAvailable
(JNIEnv * env, jobject obj){
jint ret_val;
jint array_pos;
struct port_descriptor* desc;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return -1;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return -1;
return 0;
}
 
#ifdef _WIN32
1526,6 → 1385,8
return ret_val;
}
 
 
 
/*
* Class: com_rm5248_serial_SerialOutputStream
* Method: writeByte
1534,7 → 1395,6
JNIEXPORT void JNICALL Java_com_rm5248_serial_SerialOutputStream_writeByte
(JNIEnv * env, jobject obj, jint byte){
struct port_descriptor* desc;
jint array_pos;
char byte_write;
#ifdef _WIN32
DWORD bytes_written;
1545,18 → 1405,8
 
byte_write = byte;
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return;
}
 
1565,10 → 1415,12
overlap.hEvent = CreateEvent( 0, TRUE, 0, 0 );
if( !WriteFile( desc->port, &byte_write, sizeof( byte_write ), &bytes_written, &overlap ) ){
if( GetLastError() == ERROR_IO_PENDING ){
//Not in fact an error, we're just doing this asynchronously
WaitForSingleObject( overlap.hEvent, INFINITE );
//Probably not an error, we're just doing this in an async fasion
if( WaitForSingleObject( overlap.hEvent, INFINITE ) == WAIT_FAILED ){
throw_io_exception( env, GetLastError() );
return;
}
}else{
//throw new exception
throw_io_exception( env, GetLastError() );
return;
}
1581,7 → 1433,6
return;
}
#endif
 
}
 
/*
1593,7 → 1444,6
(JNIEnv * env, jobject obj, jbyteArray arr){
jbyte* data;
jint len;
jint array_pos;
int my_errnum;
struct port_descriptor* desc;
#ifdef _WIN32
1603,18 → 1453,8
int bytes_written;
#endif
 
array_pos = get_handle( env, obj );
if( array_pos < 0 ){
//throw new exception
throw_io_exception_message( env, "Unable to get handle" );
return;
}
 
desc = port_list[ array_pos ];
 
desc = get_port_descriptor( env, obj );
if( desc == NULL ){
//throw new exception
throw_io_exception_message( env, "Unable to get descriptor" );
return;
}
 
1622,16 → 1462,22
data = (*env)->GetByteArrayElements(env, arr, 0);
 
#ifdef _WIN32
 
memset( &overlap, 0, sizeof( overlap ) );
overlap.hEvent = CreateEvent( 0, TRUE, 0, 0 );
if( !WriteFile( desc->port, data, len, &bytes_written, &overlap ) ){
if( GetLastError() == ERROR_IO_PENDING ){
//Not in fact an error, we're just doing this asynchronously
WaitForSingleObject( overlap.hEvent, INFINITE );
//Probably not an error, we're just doing this in an async fasion
if( WaitForSingleObject( overlap.hEvent, INFINITE ) == WAIT_FAILED ){
throw_io_exception( env, GetLastError() );
return;
}
}else{
my_errnum = GetLastError();
throw_io_exception( env, GetLastError() );
return;
}
}
#else
bytes_written = write( desc->port, data, len );
if( bytes_written < 0 ){
1640,10 → 1486,5
#endif
 
(*env)->ReleaseByteArrayElements(env, arr, data, 0);
 
if( bytes_written != len ){
//OH SNAP AN ERROR
throw_io_exception( env, my_errnum );
}
}