Subversion Repositories Programming Utils

Rev

Rev 72 | Rev 80 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 72 Rev 77
Line 24... Line 24...
24
        #include <termios.h>
24
        #include <termios.h>
25
        #include <unistd.h>
25
        #include <unistd.h>
26
        #include <fcntl.h>
26
        #include <fcntl.h>
27
        #include <unistd.h>
27
        #include <unistd.h>
28
        #include <dirent.h>
28
        #include <dirent.h>
-
 
29
        #include <pthread.h>
29
30
30
        #ifdef CRTSCTS
31
        #ifdef CRTSCTS
31
                #define HW_FLOW CRTSCTS
32
                #define HW_FLOW CRTSCTS
32
        #elif CNEW_RTSCTS
33
        #elif CNEW_RTSCTS
33
                #define HW_FLOW CNEW_RTSCTS
34
                #define HW_FLOW CNEW_RTSCTS
Line 63... Line 64...
63
struct port_descriptor{
64
struct port_descriptor{
64
#ifdef _WIN32
65
#ifdef _WIN32
65
        HANDLE port;
66
        HANDLE port;
66
#else
67
#else
67
        int port;
68
        int port;
-
 
69
        /* There appears to be a case where we can free() the port_descriptor
-
 
70
         * after the select() call in SerialInputStream_readByte().
-
 
71
         * This means that we segfault on the FD_SET() call.
-
 
72
         * This mutex will keep us alive until we have exited the
-
 
73
         * readByte() call.
-
 
74
         */
-
 
75
        pthread_mutex_t in_use;
68
#endif
76
#endif
69
};
77
};
70
78
71
//
79
//
72
// Local Variables
80
// Local Variables
73
//
81
//
74
struct port_descriptor** port_list = NULL;
-
 
75
int port_list_size;
-
 
-
 
82
static struct port_descriptor** port_list = NULL;
-
 
83
static int port_list_size;
76
84
77
#ifdef _WIN32
85
#ifdef _WIN32
78
//Unfortunately, Windows does not let us get the state of the DTR/RTS lines.
86
//Unfortunately, Windows does not let us get the state of the DTR/RTS lines.
79
//So, we need to keep track of that manually.  
87
//So, we need to keep track of that manually.  
80
int winDTR = 0;
88
int winDTR = 0;
Line 472... Line 480...
472
                        return -1;
480
                        return -1;
473
                }
481
                }
474
        }
482
        }
475
       
483
       
476
#else
484
#else
-
 
485
        pthread_mutex_init( &(new_port->in_use), NULL );
477
        new_port->port = open( port_to_open, O_RDWR );
486
        new_port->port = open( port_to_open, O_RDWR );
478
        if( new_port->port < 0 && errno == ENOENT ){
487
        if( new_port->port < 0 && errno == ENOENT ){
479
                //That's not a valid serial port, error out
488
                //That's not a valid serial port, error out
480
                jclass exception_class;
489
                jclass exception_class;
481
                (*env)->ExceptionDescribe( env );
490
                (*env)->ExceptionDescribe( env );
Line 634... Line 643...
634
                        free( new_port );
643
                        free( new_port );
635
                        return -1;
644
                        return -1;
636
                }
645
                }
637
        }
646
        }
638
#else
647
#else
-
 
648
        pthread_mutex_init( &(new_port->in_use), NULL );
639
        new_port->port = open( port_to_open, O_RDWR );
649
        new_port->port = open( port_to_open, O_RDWR );
640
        if( new_port->port < 0 && errno == ENOENT ){
650
        if( new_port->port < 0 && errno == ENOENT ){
641
                //That's not a valid serial port, error out
651
                //That's not a valid serial port, error out
642
                jclass exception_class;
652
                jclass exception_class;
643
                (*env)->ExceptionDescribe( env );
653
                (*env)->ExceptionDescribe( env );
Line 703... Line 713...
703
                throw_io_exception_message( env, "Unable to get descriptor" );
713
                throw_io_exception_message( env, "Unable to get descriptor" );
704
                return;
714
                return;
705
        }
715
        }
706
       
716
       
707
        close( desc->port );
717
        close( desc->port );
-
 
718
#ifndef _WIN32
-
 
719
        pthread_mutex_lock( &(desc->in_use) );
-
 
720
        pthread_mutex_unlock( &(desc->in_use) );
-
 
721
#endif
708
        free( port_list[ array_pos ] );
722
        free( port_list[ array_pos ] );
709
        port_list[ array_pos ] = NULL;
723
        port_list[ array_pos ] = NULL;
710
}
724
}
711
725
712
/*
726
/*
Line 1272... Line 1286...
1272
        //is better than the POSIX way.
1286
        //is better than the POSIX way.
1273
        fd_set fdset;
1287
        fd_set fdset;
1274
        struct timeval timeout;
1288
        struct timeval timeout;
1275
        int originalState;
1289
        int originalState;
1276
        int selectStatus;
1290
        int selectStatus;
-
 
1291
-
 
1292
        pthread_mutex_lock( &(desc->in_use) );
1277
1293
1278
        //first get the original state of the serial port lines
1294
        //first get the original state of the serial port lines
1279
        if( ioctl( desc->port, TIOCMGET, &originalState ) < 0 ){
1295
        if( ioctl( desc->port, TIOCMGET, &originalState ) < 0 ){
1280
                throw_io_exception( env, errno );
1296
                throw_io_exception( env, errno );
-
 
1297
                pthread_mutex_unlock( &(desc->in_use) );
1281
                return -1;
1298
                return -1;
1282
        }
1299
        }
1283
       
1300
       
1284
        while( 1 ){
1301
        while( 1 ){
1285
                FD_ZERO( &fdset );
1302
                FD_ZERO( &fdset );
1286
                FD_SET( desc->port, &fdset );
1303
                FD_SET( desc->port, &fdset );
1287
                timeout.tv_sec = 0;
1304
                timeout.tv_sec = 0;
1288
                timeout.tv_usec = 1000; // 1,000 microseconds = 100ms
-
 
-
 
1305
                timeout.tv_usec = 10000; // 10,000 microseconds = 10ms
1289
1306
1290
                selectStatus = select( desc->port + 1, &fdset, NULL, NULL, &timeout );
1307
                selectStatus = select( desc->port + 1, &fdset, NULL, NULL, &timeout );
1291
                if( selectStatus < 0 ){
1308
                if( selectStatus < 0 ){
1292
                        throw_io_exception( env, errno );
-
 
1293
                        return -1;
-
 
-
 
1309
                        int errval;
-
 
1310
                        if( errno == EBADF ){
-
 
1311
                                // EOF
-
 
1312
                                errval= 0;
-
 
1313
                        }else{
-
 
1314
                                throw_io_exception( env, errno );
-
 
1315
                                errval = -1;
-
 
1316
                        }
-
 
1317
                        pthread_mutex_unlock( &(desc->in_use) );
-
 
1318
                        return errval;
1294
                }
1319
                }
1295
1320
1296
                if( selectStatus == 0 ){
1321
                if( selectStatus == 0 ){
1297
                        //This was a timeout
1322
                        //This was a timeout
1298
                        if( ioctl( desc->port, TIOCMGET, &get_val ) < 0 ){
1323
                        if( ioctl( desc->port, TIOCMGET, &get_val ) < 0 ){
1299
                                throw_io_exception( env, errno );
1324
                                throw_io_exception( env, errno );
-
 
1325
                                pthread_mutex_unlock( &(desc->in_use) );
1300
                                return -1;
1326
                                return -1;
1301
                        }
1327
                        }
1302
1328
1303
                        if( get_val == originalState ){
1329
                        if( get_val == originalState ){
1304
                                //The state of the lines have not changed, 
1330
                                //The state of the lines have not changed, 
Line 1311... Line 1337...
1311
                if( FD_ISSET( desc->port, &fdset ) ){
1337
                if( FD_ISSET( desc->port, &fdset ) ){
1312
                        stat = read( desc->port, &ret_val, 1 );
1338
                        stat = read( desc->port, &ret_val, 1 );
1313
                        if( stat < 0 ){
1339
                        if( stat < 0 ){
1314
                                //throw new exception
1340
                                //throw new exception
1315
                                throw_io_exception( env, errno );
1341
                                throw_io_exception( env, errno );
-
 
1342
                                pthread_mutex_unlock( &(desc->in_use) );
1316
                                return -1;
1343
                                return -1;
1317
                        }
1344
                        }
1318
               
1345
               
1319
                        //This is a valid byte, set our valid bit
1346
                        //This is a valid byte, set our valid bit
1320
                        ret_val |= ( 0x01 << 15 );
1347
                        ret_val |= ( 0x01 << 15 );
Line 1330... Line 1357...
1330
        //Now, because we only read one byte at a time, we will use the lower 8 bytes to 
1357
        //Now, because we only read one byte at a time, we will use the lower 8 bytes to 
1331
        //return the character that we read.  The other bytes will be used to return
1358
        //return the character that we read.  The other bytes will be used to return
1332
        //information on our serial port state.
1359
        //information on our serial port state.
1333
        if( ioctl( desc->port, TIOCMGET, &get_val ) < 0 ){
1360
        if( ioctl( desc->port, TIOCMGET, &get_val ) < 0 ){
1334
                throw_io_exception( env, errno );
1361
                throw_io_exception( env, errno );
-
 
1362
                pthread_mutex_unlock( &(desc->in_use) );
1335
                return -1;
1363
                return -1;
1336
        }
1364
        }
1337
1365
1338
        if( get_val & TIOCM_CD ){
1366
        if( get_val & TIOCM_CD ){
1339
                // Carrier detect
1367
                // Carrier detect
Line 1363... Line 1391...
1363
        if( get_val & TIOCM_RI ){
1391
        if( get_val & TIOCM_RI ){
1364
                // Ring Indicator
1392
                // Ring Indicator
1365
                ret_val |= ( 0x01 << 14 );
1393
                ret_val |= ( 0x01 << 14 );
1366
        }
1394
        }
1367
       
1395
       
-
 
1396
        pthread_mutex_unlock( &(desc->in_use) );
1368
#endif
1397
#endif
1369
1398
1370
        return ret_val;
1399
        return ret_val;
1371
}
1400
}
1372
1401