1 /*-------------------------------------------------------------------------
2 |   RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
3 |   RXTX is a native interface to serial ports in java.
4 |   Copyright 1998 Kevin Hester, kevinh@acm.org
5 |   Copyright 2000-2008 Trent Jarvi tjarvi@qbang.org and others who
6 |   actually wrote it.  See individual source files for more information.
7 |
8 |   A copy of the LGPL v 2.1 may be found at
9 |   http://www.gnu.org/licenses/lgpl.txt on March 4th 2007.  A copy is
10 |   here for your convenience.
11 |
12 |   This library is free software; you can redistribute it and/or
13 |   modify it under the terms of the GNU Lesser General Public
14 |   License as published by the Free Software Foundation; either
15 |   version 2.1 of the License, or (at your option) any later version.
16 |
17 |   This library is distributed in the hope that it will be useful,
18 |   but WITHOUT ANY WARRANTY; without even the implied warranty of
19 |   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20 |   Lesser General Public License for more details.
21 |
22 |   An executable that contains no derivative of any portion of RXTX, but
23 |   is designed to work with RXTX by being dynamically linked with it,
24 |   is considered a "work that uses the Library" subject to the terms and
25 |   conditions of the GNU Lesser General Public License.
26 |
27 |   The following has been added to the RXTX License to remove
28 |   any confusion about linking to RXTX.   We want to allow in part what
29 |   section 5, paragraph 2 of the LGPL does not permit in the special
30 |   case of linking over a controlled interface.  The intent is to add a
31 |   Java Specification Request or standards body defined interface in the
32 |   future as another exception but one is not currently available.
33 |
34 |   http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
35 |
36 |   As a special exception, the copyright holders of RXTX give you
37 |   permission to link RXTX with independent modules that communicate with
38 |   RXTX solely through the Sun Microsytems CommAPI interface version 2,
39 |   regardless of the license terms of these independent modules, and to copy
40 |   and distribute the resulting combined work under terms of your choice,
41 |   provided that every copy of the combined work is accompanied by a complete
42 |   copy of the source code of RXTX (the version of RXTX used to produce the
43 |   combined work), being distributed under the terms of the GNU Lesser General
44 |   Public License plus this exception.  An independent module is a
45 |   module which is not derived from or based on RXTX.
46 |
47 |   Note that people who make modified versions of RXTX are not obligated
48 |   to grant this special exception for their modified versions; it is
49 |   their choice whether to do so.  The GNU Lesser General Public License
50 |   gives permission to release a modified version without this exception; this
51 |   exception also makes it possible to release a modified version which
52 |   carries forward this exception.
53 |
54 |   You should have received a copy of the GNU Lesser General Public
55 |   License along with this library; if not, write to the Free
56 |   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
57 |   All trademarks belong to their respective owners.
58 --------------------------------------------------------------------------*/
59 /**
60 *
61 *	Martin Pool <mbp@linuxcare.com> added support for
62 * 	explicitly-specified lists of ports, October 2000.
63 *
64 * 	Joseph Goldstone <joseph@lp.com> reorganized to support registered
65 * 	ports, known ports, and scanned ports, July 2001.
66 *
67 **/
68 
69 package gnu.io;
70 
71 import java.lang.*;
72 import java.util.*;
73 import java.io.*;
74 import java.util.StringTokenizer;
75 
76 /**
77 *   This is the JavaComm for Linux driver.
78 */
79 
80 public class RXTXCommDriver implements CommDriver
81 {
82 
83 	private final static boolean debug = "true".equals( System.getProperty( "gnu.io.rxtx.DEBUG" ) );
84 	private final static boolean CheckLPT = "true".equals( System.getProperty( "gnu.io.rxtx.CheckL" ) );
85 	private final static boolean noVersionOutput = "true".equals( System.getProperty( "gnu.io.rxtx.NoVersionOutput" ) );
86 
87 
88 	static
89 	{
90 		if(debug) System.out.println("RXTXCommDriver{}:Static");
91 		System.loadLibrary( "rxtxSerial" );
92 
93 		/**
94 		*	Perform a crude check to make sure people don't mix
95 		*	versions of the Jar and native lib
96 		*
97 		*	Mixing the libs can create a nightmare.
98 		*
99 		*	It could be possible to move this over to RXTXVersion
100 		*	but All we want to do is warn people when first loading
101 		*	the Library.
102 		**/
103 
104 		String JarVersion = RXTXVersion.getVersion();
105 		String LibVersion;
106 
107 		try
108 		{
109 			LibVersion = RXTXVersion.nativeGetVersion();
110 		}
111 		catch ( Error UnsatisfiedLinkError )
112 		{
113 
114 			/**
115 			*	for rxtx prior to 2.1.7
116 			**/
117 
118 			LibVersion = nativeGetVersion();
119 		}
120 		if (!debug)
121 		{
122 			if ( ! noVersionOutput )
123 			{
124 				System.out.println(" RXTX Comm  - Stable Library");
125 				System.out.println(" =================================");
126 				System.out.println(" Native lib Version = " + LibVersion);
127 				System.out.println(" Java lib Version   = " + JarVersion);
128 			}
129 
130 		}
131 		else
132 		{
133 			System.out.println(" ==================================");
134 			System.out.println(" =                                =");
135 			System.out.println(" = RXTX Comm - In Java DEBUG mode =");
136 			System.out.println(" =                                =");
137 			System.out.println(" ==================================");
138 
139 		}
140 
141 		if ( ! JarVersion.equals( LibVersion ) )
142 		{
143 			System.out.println(" WARNING:  RXTX Version mismatch");
144 			System.out.println(" ** Jar version = " + JarVersion);
145 			System.out.println(" ** Native lib Version = " + LibVersion);
146 		}
147 		else if (debug)
148 		{
149 			System.out.println(" ** Jar version = " + JarVersion);
150 			System.out.println(" ** Native lib Version = " + LibVersion);
151 		}
152 
153 		if(debug) System.out.println("RXTXCommDriver{}:Static:Exit");
154 
155 	}
156 
157 	/**
158 	*	Get the Serial port prefixes for the running OS
159 	**/
160 
161 	private String deviceDirectory;
162 	private String osName;
registerKnownPorts(int PortType)163 	private native boolean registerKnownPorts(int PortType);
isPortPrefixValid(String dev)164 	private native boolean isPortPrefixValid(String dev);
testRead(String dev, int type)165 	private native boolean testRead(String dev, int type);
getDeviceDirectory()166 	private native String getDeviceDirectory();
167 
168 	/**
169 	*	for rxtx prior to 2.1.7
170 	**/
171 
nativeGetVersion()172 	public static native String nativeGetVersion();
173 
getValidPortPrefixes( String CandidatePortPrefixes[] )174 	private final String[] getValidPortPrefixes(
175 		String CandidatePortPrefixes[]
176 	)
177 	{
178 		/**
179 		*  	256 is the number of prefixes ( COM, cua, ttyS, ...) not
180 		*	the number of devices (ttyS0, ttyS1, ttyS2, ...)
181 		*
182 		*	On a Linux system there are about 400 prefixes in
183 		*	deviceDirectory.
184 		*	registerScannedPorts() assigns CandidatePortPrefixes to
185 		*	something less than 50 prefixes.
186 		*
187 		*	Trent
188 		**/
189 
190 		String ValidPortPrefixes[]=new String [256];
191 
192 		if (debug) System.out.println("RXTXCommDriver:getValidPortPrefixes()");
193 
194 		if(CandidatePortPrefixes==null)
195 		{
196 			if (debug)
197 			{
198 				System.out.println(" No ports prefixes known for this System.");
199 				System.out.println(" Please check the port prefixes listed");
200 				System.out.println(" for " + osName + " in registerScannedPorts()");
201 			}
202 		}
203 
204 		int i=0;
205 		for(int j=0;j<CandidatePortPrefixes.length;j++)
206 		{
207 			if(isPortPrefixValid(CandidatePortPrefixes[j])) {
208 				ValidPortPrefixes[i++]= CandidatePortPrefixes[j];
209 			}
210 		}
211 
212 		String[] returnArray=new String[i];
213 		System.arraycopy(ValidPortPrefixes, 0, returnArray, 0, i);
214 
215 		if(ValidPortPrefixes[0]==null)
216 		{
217 			if (debug)
218 			{
219 				System.out.println(" No ports matched the list assumed for this");
220 				System.out.println(" System in the directory " + deviceDirectory);
221 				System.out.println(" Please check the ports listed for");
222 				System.out.println(" \"" + osName + "\" in");
223 				System.out.println(" RXTXCommDriver:registerScannedPorts()");
224 				System.out.println(" Tried:");
225 				for(int j=0;j<CandidatePortPrefixes.length;j++){
226 					System.out.println(" - " + CandidatePortPrefixes[i]);
227 				}
228 			}
229 		}
230 		else
231 		{
232 			if (debug)
233 			{
234 				System.out.println(" The following port prefixes have been");
235 				System.out.println(" identified as valid on " + osName + ":");
236 				System.out.println(" -- ouput withheld --");
237 
238 				/**
239 				*	for(int j=0;j<returnArray.length;j++)
240 				*	{
241 				*	if (debug) System.out.println("\t" + j + " " + returnArray[j]);
242 				*	}
243 				**/
244 			}
245 		}
246 		if (debug) System.out.println("RXTXCommDriver:getValidPortPrefixes:Exit");
247 
248 		return returnArray;
249 
250 
251 
252 	}
253 
254 	/**
255 	*	handle solaris/sunos /dev/cua/a convention
256 	**/
257 
checkSolaris( String PortName, int PortType )258 	private void checkSolaris(
259 		String PortName,
260 		int PortType
261 	)
262 	{
263 		System.out.println("RXTXCommDriver:checkSolaris()");
264 
265 		char p[] =  { 91 };
266 
267 		for( p[0] =97 ;p[0] < 123; p[0]++ )
268 		{
269 			if (testRead(PortName.concat(new String(p)),PortType))
270 			{
271 				CommPortIdentifier.addPortName(
272 					PortName.concat(new String(p)),
273 					PortType,
274 					this
275 				);
276 			}
277 		}
278 
279 		/**
280 		*	check for 0-9 in case we have them (Solaris USB)
281 		**/
282 
283 		for( p[0] =48 ;p[0] <= 57; p[0]++ )
284 		{
285 			if (testRead(PortName.concat(new String(p)),PortType))
286 			{
287 				CommPortIdentifier.addPortName(
288 						PortName.concat(new String(p)),
289 						PortType,
290 						this
291 				);
292 			}
293 		}
294 
295 		if (debug) System.out.println("RXTXCommDriver:checkSolaris:Exit");
296 	}
297 
registerValidPorts( String CandidateDeviceNames[], String ValidPortPrefixes[], int PortType )298 	private void registerValidPorts(
299 		String CandidateDeviceNames[],
300 		String ValidPortPrefixes[],
301 		int PortType
302 	)
303 	{
304 		if (debug) System.out.println("RXTXCommDriver:registerValidPorts(" + PortType + ")");
305 
306 		int i =0;
307 		int p =0;
308 
309 		/**
310 		*	FIXME quick fix to get COM1-8 on windows working.  The
311 		*	Read test is not working properly and its crunch time...
312 		*	if(osName.toLowerCase().indexOf("windows") != -1 )
313 		*	{
314 		*		for( i=0;i < CandidateDeviceNames.length;i++ )
315 		*		{
316 		*			CommPortIdentifier.addPortName(
317 		*				CandidateDeviceNames[i],
318 		*				PortType,
319 		*				this
320 		*			);
321 		*		}
322 		*		return;
323 		*
324 		*	}
325 		**/
326 
327 		if (debug)
328 		{
329 
330 			System.out.println(" Candidate Ports");
331 			for (
332 				int dn=0;
333 				dn<CandidateDeviceNames.length;
334 				dn++
335 			)
336 			{
337 				System.out.println(" - " + CandidateDeviceNames[dn]);
338 			}
339 			System.out.println(" Valid port prefixes:");
340 			for (
341 				int pp=0;
342 				pp<ValidPortPrefixes.length;
343 				pp++
344 			)
345 			{
346 				System.out.println(" - " + ValidPortPrefixes[pp]);
347 			}
348 		}
349 
350 		if ( CandidateDeviceNames!=null && ValidPortPrefixes!=null)
351 		{
352 			for( i = 0;i<CandidateDeviceNames.length; i++ )
353 			{
354 				for( p = 0;p<ValidPortPrefixes.length; p++ )
355 				{
356 					/**
357 					*	this determines:
358 					* 	device file Valid ports
359 					* 	/dev/ttyR[0-9]*  != /dev/ttyS[0-9]*
360 					* 	/dev/ttySI[0-9]* != /dev/ttyS[0-9]*
361 					* 	/dev/ttyS[0-9]*  == /dev/ttyS[0-9]*
362 					*
363 					*	Otherwise we check some ports
364 					*	multiple times.  Perl would rock
365 					*	here.
366 					*
367 					*	If the above passes, we try to read
368 					*	from the port.  If there is no err
369 					*	the port is added.
370 					*
371 					*	Trent
372 					**/
373 
374 					String V =  ValidPortPrefixes[ p ];
375 					String C =   CandidateDeviceNames[ i ];
376 
377 					int VL = V.length();
378 
379 					if( C.length() < VL ) continue;
380 
381 					String CU =	C.substring(VL).toUpperCase();
382 					String Cl =	C.substring(VL).toLowerCase();
383 
384 					if
385 					(
386 						!(
387 							C.regionMatches(0, V, 0, VL ) &&
388 							CU.equals( Cl )
389 						)
390 					)
391 					{
392 						continue;
393 					}
394 
395 					String PortName;
396 
397 					if(osName.toLowerCase().indexOf("windows") == -1 )
398 					{
399 						PortName = deviceDirectory + C;
400 					}
401 					else
402 					{
403 						PortName = C;
404 					}
405 
406 					if (debug)
407 					{
408 						System.out.println( " - " + C + " " + V );
409 						System.out.println( " - " + CU + " " + Cl );
410 					}
411 
412 					if
413 					(
414 						osName.equals("Solaris") ||
415 						osName.equals("SunOS"))
416 						checkSolaris(PortName,PortType);
417 					else
418 					{
419 						if (debug) System.out.println(" CheckLPT is " + CheckLPT + " and PortType is" + PortType);
420 						if ( (!CheckLPT) && (PortType!=1) )
421 						{
422 							/**
423 							*	Don't attempt to check LPT ports,
424 							*	if CheckLPT is set to false in env args
425 							**/
426 
427 							CommPortIdentifier.addPortName
428 							(
429 								PortName,
430 								PortType,
431 								this
432 							);
433 						}
434 						else
435 						{
436 							if (testRead(PortName, PortType))
437 							{
438 								CommPortIdentifier.addPortName
439 								(
440 									PortName,
441 									PortType,
442 									this
443 								);
444 							}
445 						}
446 
447 					}
448 				}
449 			}
450 		}
451 
452 		if (debug) System.out.println("RXTXCommDriver:registerValidPorts:Exit");
453 
454 	}
455 
456 
457 	/**
458 	*	initialize() will be called by the CommPortIdentifier's static
459 *	initializer. The responsibility of this method is:
460 *	1) Ensure that that the hardware is present.
461 *	2) Load any required native libraries.
462 *	3) Register the port names with the CommPortIdentifier.
463 	*
464 	*	<p>From the NullDriver.java CommAPI sample.
465 	*	added printerport stuff
466 	*	Holger Lehmann
467 	*	July 12, 1999
468 	*	IBM
469 	*
470 	* 	Added ttyM for Moxa boards
471 	* 	Removed obsolete device cuaa
472 	* 	Peter Bennett
473 	* 	January 02, 2000
474 	* 	Bencom
475 **/
476 
477 	/**
478 	*	Determine the OS and where the OS has the devices located
479 	**/
initialize()480 	public void initialize()
481 	{
482 
483 		if (debug) System.out.println("RXTXCommDriver:initialize()");
484 
485 		osName=System.getProperty("os.name");
486 		deviceDirectory=getDeviceDirectory();
487 
488 		/**
489 		*	First try to register ports specified in the properties
490 		*	file.  If that doesn't exist, then scan for ports.
491 		**/
492 
493 		for
494 		(
495 			int PortType=CommPortIdentifier.PORT_SERIAL;
496 			PortType<=CommPortIdentifier.PORT_PARALLEL;
497 			PortType++
498 		)
499 		{
500 			/**
501 			*	Load prefixes for all ports from env and file pairs
502 			**/
503 			if (!registerSpecifiedPorts(PortType))
504 			{
505 
506 				/**
507 				*	Load OS knoow ports (APPLE thing)
508 				**/
509 				if (!registerKnownPorts(PortType))
510 				{
511 
512 					/**
513 					*	Load ports via a scan...
514 					**/
515 					registerScannedPorts(PortType);
516 				}
517 			}
518 		}
519 
520 		if (debug) System.out.println("RXTXCommDriver:initialize:Exit");
521 
522 	}
523 
addSpecifiedPorts( String names, int PortType )524 	private void addSpecifiedPorts(
525 		String names,
526 		int PortType
527 	)
528 	{
529 
530 		if (debug) System.out.println("RXTXCommDriver:addSpecifiedPorts()");
531 
532 		final String pathSep = System.getProperty("path.separator", ":");
533 		final StringTokenizer tok = new StringTokenizer(names, pathSep);
534 
535 		while (tok.hasMoreElements())
536 		{
537 			String PortName = tok.nextToken();
538 
539 			if (testRead(PortName, PortType))
540 				CommPortIdentifier.addPortName(PortName,
541 					PortType, this);
542 		}
543 
544 		if (debug) System.out.println("RXTXCommDriver:addSpecifiedPorts:Exit");
545 
546 	}
547 
548 	/**
549 *	Register ports specified in the file "gnu.io.rxtx.properties"
550 *	Key system properties:
551 *	gnu.io.rxtx.SerialPorts
552 *	gnu.io.rxtx.ParallelPorts
553 *
554 *	Tested only with sun jdk1.3
555 *
556 *	The file gnu.io.rxtx.properties must reside in the java extension dir
557 *
558 *	Example: /usr/local/java/jre/lib/ext/gnu.io.rxtx.properties
559 *
560 *	The file contains the following key properties:
561 *
562 *  	gnu.io.rxtx.SerialPorts=/dev/ttyS0:/dev/ttyS1:
563 *  	gnu.io.rxtx.ParallelPorts=/dev/lp0:
564 *
565 **/
registerSpecifiedPorts( int PortType )566 	private boolean registerSpecifiedPorts(
567 		int PortType
568 	)
569 	{
570 		if (debug) System.out.println("RXTXCommDriver:registerSpecifiedPorts(" + PortType + ")");
571 
572 		final String pathSep = System.getProperty("path.separator", ":");
573 		final String fileSep = System.getProperty("file.separator");
574 		String val = null;
575 		String err_str = null;
576 		String ext_loc[];
577 		boolean props_loaded = false;
578 
579 		/**
580 		*	Save System properties, to restore on func exit.
581 		**/
582 
583 		Properties origp = System.getProperties();
584 
585 		String ext_dir=System.getProperty("java.ext.dirs");
586 
587 		if (ext_dir.length() > 0)
588 		{
589 
590 			if (ext_dir.indexOf(":") > 0)
591 			{
592 				ext_loc = ext_dir.split(pathSep);
593 			}
594 			else
595 			{
596 				ext_loc = new String[1];
597 				ext_loc[1] = ext_dir;
598 
599 			}
600 
601 			for (
602 				int el=0;
603 				el<ext_loc.length;
604 				el++
605 			)
606 			{
607 				ext_loc[el] = ext_loc[el] + fileSep;
608 
609 				if (debug)
610 					System.out.println(" - searching config location " + ext_loc[el]);
611 
612 				try
613 				{
614 					FileInputStream rxtx_prop=new FileInputStream(ext_loc[el] + "gnu.io.rxtx.properties");
615 					Properties p=new Properties();
616 					p.load(rxtx_prop);
617 					System.setProperties(p);
618 					for (Iterator it = p.keySet().iterator(); it.hasNext();)
619 					{
620 						String key = (String) it.next();
621 						System.setProperty(key, p.getProperty(key));
622 					}
623 				}
624 				catch(Exception e)
625 				{
626 					err_str = e.toString();
627 
628 					if (debug)
629 					{
630 						if (err_str.indexOf("java.io.FileNotFoundException") < 0)
631 						{
632 							System.out.println(err_str);
633 						}
634 						else
635 						{
636 							System.out.println("   -> The file '" + ext_loc[el] + "gnu.io.rxtx.properties' doesn't exists.");
637 						}
638 					}
639 				}
640 			}
641 		}
642 		if (debug)
643 			System.out.println(" Checking Environment Properties for ports of type " + PortType);
644 
645 		switch (PortType) {
646 			case CommPortIdentifier.PORT_SERIAL:
647 				if ((val = System.getProperty("gnu.io.rxtx.SerialPorts")) == null)
648 				{
649 					val = System.getProperty("gnu.io.SerialPorts");
650 					if (debug)
651 						System.out.println(" - Capture gnu.io.SerialPorts = '" + val + "' where Port Type =" + PortType);
652 				}
653 				break;
654 
655 			case CommPortIdentifier.PORT_PARALLEL:
656 				if ((val = System.getProperty("gnu.io.rxtx.ParallelPorts")) == null)
657 				{
658 					val = System.getProperty("gnu.io.ParallelPorts");
659 					if (debug)
660 						System.out.println(" - Capture gnu.io.ParallelPorts = '" + val + "' where Port Type =" + PortType);
661 				}
662 				break;
663 			default:
664 				if (debug)
665 				System.out.println(" !!ERROR - Unknown port type " + PortType + " passed to RXTXCommDriver.registerSpecifiedPorts()");
666 		}
667 
668 		/**
669 		*	Not sure if the following line undoes the properties load,
670 		*	or just ensures properties before the proc is called are
671 		*	not manipulated.  Anti-injection?  - We've finished with
672 		*	them anyway...
673 		**/
674 		System.setProperties(origp); //recall saved properties
675 
676 		if (val != null)
677 		{
678 
679 			addSpecifiedPorts(val, PortType);
680 			if (debug)
681 			{
682 				System.out.println(" = Ports added from Environmental Properties");
683 				System.out.println("RXTXCommDriver:registerSpecifiedPorts(True):Exit");
684 			}
685 			return true;
686 		}
687 		else
688 		{
689 			if (debug) System.out.println("RXTXCommDriver:registerSpecifiedPorts(False):Exit");
690 			return false;
691 		}
692 	}
693 
694 	/**
695 	*	Look for all entries in deviceDirectory, and if they look like they should
696 	*	be serial ports on this OS and they can be opened then register
697 	*	them.
698 	**/
699 
registerScannedPorts( int PortType )700 	private void registerScannedPorts(
701 		int PortType
702 	)
703 	{
704 		if (debug) System.out.println("RXTXCommDriver:registerScannedPorts(" + PortType + ")");
705 
706 		String[] 	CandidateDeviceNames;
707 		int 		iFound;
708 
709 		if (debug) System.out.println(" Scanning " + deviceDirectory + " for ports of type " + PortType);
710 
711 		if(osName.equals("Windows CE"))
712 		{
713 			String[] temp = {
714 				"COM1:",
715 				"COM2:",
716 				"COM3:",
717 				"COM4:",
718 				"COM5:",
719 				"COM6:",
720 				"COM7:",
721 				"COM8:"
722 			};
723 			CandidateDeviceNames=temp;
724 		}
725 		else if(osName.toLowerCase().indexOf("windows") != -1 )
726 		{
727 			String[] temp = new String[259];
728 			for( int i = 1; i <= 256; i++ )
729 			{
730 				temp[i - 1] = "COM" + i;
731 			}
732 			for( int i = 1; i <= 3; i++ )
733 			{
734 				temp[i + 255] = "LPT" + i;
735 			}
736 			CandidateDeviceNames=temp;
737 		}
738 		else if ( osName.equals("Solaris") || osName.equals("SunOS"))
739 		{
740 			/**
741 			*	Solaris uses a few different ways to identify ports.
742 			*	They could be /dev/term/a /dev/term0 /dev/cua/a /dev/cuaa
743 			*	the /dev/???/a appears to be on more systems.
744 			*
745 			*	The uucp lock files should not cause problems.
746 			*/
747 
748 			/**
749 			*	File dev = new File( "/dev/term" );
750 			*	String deva[] = dev.list();
751 			*	dev = new File( "/dev/cua" );
752 			*	String devb[] = dev.list();
753 			*	String[] temp = new String[ deva.length + devb.length ];
754 			*	for(int j =0;j<deva.length;j++)
755 			*		deva[j] = "term/" + deva[j];
756 			*	for(int j =0;j<devb.length;j++)
757 			*		devb[j] = "cua/" + devb[j];
758 			*	System.arraycopy( deva, 0, temp, 0, deva.length );
759 			*	System.arraycopy( devb, 0, temp,
760 			*			deva.length, devb.length );
761 			*	if( debug ) {
762 			*		for( int j = 0; j< temp.length;j++)
763 			*			System.out.println( temp[j] );
764 			*	}
765 			*	CandidateDeviceNames=temp;
766 			**/
767 
768 			/**
769 			*	ok..  Look the the dirctories representing the port
770 			*	kernel driver interface.
771 			*
772 			*	If there are entries there are possibly ports we can
773 			*	use and need to enumerate.
774 			**/
775 
776 			String term[] = new String[2];
777 			int l = 0;
778 			File dev = null;
779 			dev = new File( "/dev/term" );
780 			if( dev.list().length > 0 ) term[l++] ="term/";
781 
782 			/**
783 			*	dev = new File( "/dev/cua0" );
784 			*	if( dev.list().length > 0 ) term[l++] = "cua/";
785 			**/
786 
787 			String[] temp = new String[l];
788 			for(l--;l >= 0;l--) temp[l] = term[l];
789 			CandidateDeviceNames=temp;
790 		}
791 		else
792 		{
793 			File dev = new File( deviceDirectory );
794 			String[] temp = dev.list();
795 			CandidateDeviceNames=temp;
796 		}
797 
798 		if (CandidateDeviceNames==null)
799 		{
800 				if (debug) System.out.println(" No device files to check ");
801 				return;
802 		}
803 		else
804 		{
805 			int found = CandidateDeviceNames.length;
806 			if (debug) System.out.println(" Found " + found + " devices files to check");
807 		}
808 
809 		String CandidatePortPrefixes[] = {};
810 
811 		switch (PortType) {
812 			case CommPortIdentifier.PORT_SERIAL:
813 				if (debug) System.out.println(" scanning for serial ports for os " + osName);
814 
815 				/**
816 				*	There are _many_ possible ports that can be used
817 				*	on Linux.  See below in the fake Linux-all-ports
818 				*	case for a list.  You may add additional ports
819 				*	here but be warned that too many will significantly
820 				*	slow down port enumeration.  Linux 2.6 has udev
821 				*	support which should be faster as only ports the
822 				*	kernel finds should be exposed in /dev
823 				*
824 				*	See also how to override port enumeration and
825 				*	specifying port in INSTALL.
826 				*
827 				*	taj
828 				**/
829 
830 				if(osName.equals("Linux"))
831 				{
832 					String[] Temp = {
833 					"ttyS",		// linux Serial Ports
834 					"ttySA",	// for the IPAQs
835 					"ttyUSB",	// for USB frobs
836 					"rfcomm",   // bluetooth serial device
837 					"ttyircomm"	// linux IrCommdevices (IrDA serial emu)
838 					};
839 					CandidatePortPrefixes=Temp;
840 				}
841 				else if(osName.equals("Linux-all-ports"))
842 				{
843 					/**
844 					*	If you want to enumerate all ports ~5000
845 					*	possible, then replace the above with this
846 					**/
847 
848 					String[] Temp = {
849 						"comx",  // linux COMMX synchronous serial card
850 						"holter",// custom card for heart monitoring
851 						"modem", // linux symbolic link to modem.
852 						"rfcomm",   // bluetooth serial device
853 						"ttyircomm",	// linux IrCommdevices (IrDA serial emu)
854 						"ttycosa0c",	// linux COSA/SRP synchronous serial card
855 						"ttycosa1c",	// linux COSA/SRP synchronous serial card
856 						"ttyACM",		// linux CDC ACM devices
857 						"ttyC",			// linux cyclades cards
858 						"ttyCH",		// linux Chase Research AT/PCI-Fast serial card
859 						"ttyD",			// linux Digiboard serial card
860 						"ttyE",			// linux Stallion serial card
861 						"ttyF",			// linux Computone IntelliPort serial card
862 						"ttyH",			// linux Chase serial card
863 						"ttyI",			// linux virtual modems
864 						"ttyL",			// linux SDL RISCom serial card
865 						"ttyM",			// linux PAM Software's multimodem boards
866 						"ttyMX",		// linux Moxa Smart IO cards
867 						"ttyP",			// linux Hayes ESP serial card
868 						"ttyR",			// linux comtrol cards
869 						"ttyS",			// linux Serial Ports
870 						"ttySI",		// linux SmartIO serial card
871 						"ttySR",		// linux Specialix RIO serial card 257+
872 						"ttyT",			// linux Technology Concepts serial card
873 						"ttyUSB",		//linux USB serial converters
874 						"ttyV",			// linux Comtrol VS-1000 serial controller
875 						"ttyW",			// linux specialix cards
876 						"ttyX"			// linux SpecialX serial card
877 					};
878 
879 					CandidatePortPrefixes=Temp;
880 				}
881 				else if(osName.toLowerCase().indexOf("qnx") != -1 )
882 				{
883 					String[] Temp = {
884 						"ser"
885 					};
886 					CandidatePortPrefixes=Temp;
887 				}
888 				else if(osName.equals("Irix"))
889 				{
890 					String[] Temp = {
891 						"ttyc",	// irix raw character devices
892 						"ttyd", // irix basic serial ports
893 						"ttyf", // irix serial ports with hardware flow
894 						"ttym", // irix modems
895 						"ttyq", // irix pseudo ttys
896 						"tty4d",// irix RS422
897 						"tty4f",// irix RS422 with HSKo/HSki
898 						"midi", // irix serial midi
899 						"us"	// irix mapped interface
900 					};
901 					CandidatePortPrefixes=Temp;
902 				}
903 				else if(osName.equals("FreeBSD"))
904 				//See here: http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/serial.html
905 				{
906 					String[] Temp = {
907 						"ttyu",	//general purpose serial ports
908 						"ttyU",	//general purpose serial ports (UArduino Drv)
909 						"cuau",	//general purpose serial ports (post v10)
910 						"cuaU",	//general purpose serial ports (UARduino Drv)
911 						"cuad",	//general purpose serial ports (pre v10)
912 						"ttyd",	//general purpose serial ports
913 
914 						//Historic <v8 - Not sure if drvs still work?
915 						"cuaa",	//dialout serial ports
916 						"ttyA",	//Specialix SI/XIO dialin ports
917 						"cuaA",	//Specialix SI/XIO dialout ports
918 						"ttyD",	//Digiboard - 16 dialin ports
919 						"cuaD",	//Digiboard - 16 dialout ports
920 						"ttyE",	//Stallion EasyIO (stl) dialin ports
921 						"cuaE",	//Stallion EasyIO (stl) dialout ports
922 						"ttyF",	//Stallion Brumby (stli) dialin ports
923 						"cuaF",	//Stallion Brumby (stli) dialout ports
924 						"ttyR",	//Rocketport dialin ports
925 						"cuaR",	//Rocketport dialout ports
926 						"stl"	//Stallion EasyIO board or Brumby N
927 					};
928 					CandidatePortPrefixes=Temp;
929 				}
930 				else if(osName.equals("NetBSD")) // FIXME this is probably wrong
931 				{
932 					String[] Temp = {
933 						"tty0"	// netbsd serial ports
934 					};
935 					CandidatePortPrefixes=Temp;
936 				}
937 				else if ( osName.equals("Solaris") || osName.equals("SunOS"))
938 				{
939 					String[] Temp = {
940 						"term/",
941 						"cua/"
942 					};
943 					CandidatePortPrefixes=Temp;
944 				}
945 				else if(osName.equals("HP-UX"))
946 				{
947 					String[] Temp = {
948 						"tty0p",	// HP-UX serial ports
949 						"tty1p"		// HP-UX serial ports
950 					};
951 					CandidatePortPrefixes=Temp;
952 				}
953 				else if(osName.equals("UnixWare") || osName.equals("OpenUNIX"))
954 				{
955 					String[] Temp = {
956 						"tty00s",	// UW7/OU8 serial ports
957 						"tty01s",
958 						"tty02s",
959 						"tty03s"
960 					};
961 					CandidatePortPrefixes=Temp;
962 				}
963 				else if	(osName.equals("OpenServer"))
964 				{
965 					String[] Temp = {
966 						"tty1A",	// OSR5 serial ports
967 						"tty2A",
968 						"tty3A",
969 						"tty4A",
970 						"tty5A",
971 						"tty6A",
972 						"tty7A",
973 						"tty8A",
974 						"tty9A",
975 						"tty10A",
976 						"tty11A",
977 						"tty12A",
978 						"tty13A",
979 						"tty14A",
980 						"tty15A",
981 						"tty16A",
982 						"ttyu1A",	// OSR5 USB-serial ports
983 						"ttyu2A",
984 						"ttyu3A",
985 						"ttyu4A",
986 						"ttyu5A",
987 						"ttyu6A",
988 						"ttyu7A",
989 						"ttyu8A",
990 						"ttyu9A",
991 						"ttyu10A",
992 						"ttyu11A",
993 						"ttyu12A",
994 						"ttyu13A",
995 						"ttyu14A",
996 						"ttyu15A",
997 						"ttyu16A"
998 					};
999 					CandidatePortPrefixes=Temp;
1000 				}
1001 				else if (osName.equals("Compaq's Digital UNIX") || osName.equals("OSF1"))
1002 				{
1003 					String[] Temp = {
1004 						"tty0"	// Digital Unix serial ports
1005 					};
1006 					CandidatePortPrefixes=Temp;
1007 				}
1008 					else if(osName.equals("BeOS"))
1009 				{
1010 					String[] Temp = {
1011 						"serial"	// BeOS serial ports
1012 					};
1013 					CandidatePortPrefixes=Temp;
1014 				}
1015 				else if(osName.equals("Mac OS X"))
1016 				{
1017 					String[] Temp = {
1018 						"cu.KeyUSA28X191.",		// Keyspan USA-28X adapter, USB port 1
1019 						"tty.KeyUSA28X191.",	// Keyspan USA-28X adapter, USB port 1
1020 						"cu.KeyUSA28X181.", 	// Keyspan USA-28X adapter, USB port 2
1021 						"tty.KeyUSA28X181.", 	// Keyspan USA-28X adapter, USB port 2
1022 						"cu.KeyUSA19181.", 		// Keyspan USA-19 adapter
1023 						"tty.KeyUSA19181." 		// Keyspan USA-19 adapter
1024 					};
1025 					CandidatePortPrefixes=Temp;
1026 				}
1027 				else if(osName.toLowerCase().indexOf("windows") != -1 )
1028 				{
1029 					String[] Temp = {
1030 						"COM"		// win32 serial ports
1031 						//"//./COM"	// win32 serial ports (piped)
1032 					};
1033 					CandidatePortPrefixes=Temp;
1034 				}
1035 				else
1036 				{
1037 					if (debug) System.out.println("No valid prefixes for serial ports have been entered for "+osName + " in RXTXCommDriver.java.  This may just be a typo in the method registerScanPorts().");
1038 				}
1039 
1040 				iFound = CandidateDeviceNames.length;
1041 				if (debug) System.out.println("Found " + iFound + " port prefixes on " + osName + " for port type " + PortType);
1042 				break;
1043 
1044 			case CommPortIdentifier.PORT_PARALLEL:
1045 
1046 				if (debug) System.out.println("scanning for parallel ports for os "+osName);
1047 
1048 				/**
1049 				*	Get the Parallel port prefixes for the running os
1050 				*	Holger Lehmann
1051 				*	July 12, 1999
1052 				*	IBM
1053 				**/
1054 
1055 				if(osName.equals("Linux")
1056 
1057 				/**
1058 				*	|| osName.equals("NetBSD") FIXME
1059 				*	|| osName.equals("HP-UX")  FIXME
1060 				*	|| osName.equals("Irix")   FIXME
1061 				*	|| osName.equals("BeOS")   FIXME
1062 				*	|| osName.equals("Compaq's Digital UNIX")   FIXME
1063 				**/
1064 
1065 				)
1066 				{
1067 					String[] temp={
1068 						"lp"	// linux printer port
1069 					};
1070 					CandidatePortPrefixes=temp;
1071 				}
1072 				else if(osName.equals("FreeBSD"))
1073 				{
1074 					String[] temp={
1075 						"lpt"
1076 					};
1077 					CandidatePortPrefixes=temp;
1078 				}
1079 				else if(osName.toLowerCase().indexOf("windows") != -1 )
1080 				{
1081 					String[] temp={
1082 						"LPT"
1083 					};
1084 					CandidatePortPrefixes=temp;
1085 				}
1086 				else  /* printer support is green */
1087 				{
1088 					String [] temp={};
1089 					CandidatePortPrefixes=temp;
1090 				}
1091 
1092 				iFound = CandidateDeviceNames.length;
1093 				if (debug) System.out.println("Found " + iFound + " port prefixes on " + osName + " for port type " + PortType);
1094 
1095 				break;
1096 
1097 			default:
1098 				if (debug) System.out.println(" Unknown PortType " + PortType + " passed to RXTXCommDriver.registerScannedPorts()");
1099 		}
1100 
1101 		registerValidPorts(
1102 			CandidateDeviceNames,
1103 			CandidatePortPrefixes,
1104 			PortType
1105 		);
1106 
1107 		if (debug) System.out.println("RXTXCommDriver:registerScannedPorts:Exit");
1108 
1109 	}
1110 
1111 
1112 	/**
1113 	* <p>From the NullDriver.java CommAPI sample.
1114 	*
1115 	*	@param PortName The name of the port the OS recognizes
1116 	*	@param PortType CommPortIdentifier.PORT_SERIAL or PORT_PARALLEL
1117 	*	@return CommPort
1118 	*	getCommPort() will be called by CommPortIdentifier from its
1119 	*	openPort() method. PortName is a string that was registered earlier
1120 	*	using the CommPortIdentifier.addPortName() method. getCommPort()
1121 	*	returns an object that extends either SerialPort or ParallelPort.
1122 	**/
1123 
getCommPort( String PortName, int PortType )1124 	public CommPort getCommPort(
1125 		String PortName,
1126 		int PortType
1127 	)
1128 	{
1129 		if (debug) System.out.println("RXTXCommDriver:getCommPort(" + PortName + "," + PortType + ")");
1130 		try
1131 		{
1132 			switch (PortType) {
1133 				case CommPortIdentifier.PORT_SERIAL:
1134 					if(osName.toLowerCase().indexOf("windows") == -1 )
1135 					{
1136 						return new RXTXPort( PortName );
1137 					}
1138 					else
1139 					{
1140 						return new RXTXPort( deviceDirectory + PortName );
1141 					}
1142 				case CommPortIdentifier.PORT_PARALLEL:
1143 					return new LPRPort( PortName );
1144 				default:
1145 					if (debug)
1146 						System.out.println(" Unknown PortType  "+PortType+" passed to RXTXCommDriver.getCommPort()");
1147 			}
1148 		}
1149 		catch( PortInUseException e )
1150 		{
1151 			if (debug) System.out.println(" Port "+PortName+" in use by another application");
1152 		}
1153 
1154 		if (debug) System.out.println("RXTXCommDriver:getCommPort:Exit");
1155 
1156 		return null;
1157 
1158 
1159 
1160 	}
1161 
1162 	/**
1163 	*	Yikes.
1164 	*	Trying to call println from C for odd reasons
1165 	**/
1166 
Report( String arg )1167 	public void Report(
1168 		String arg
1169 	)
1170 	{
1171 		System.out.println(arg);
1172 	}
1173 }
1174