A Serial port example

What is this document about?

In this document you will find how to develop with our SDK an application which sends data through the serial port. More precisely this small program sends a GPRMC frame on the serial port each 5 seconds.

The JCPN file

In the java component file, we are going to declare several things. First we are going to use the provided interface to use the serial port. Then we are including some required interfaces. And then we will use some parameters.

The initial

First you need to create the initial file in which you are going to code your application.
Here you have to selected the singleton design pattern check box.

The provided interface

Add a new provided interface.

This interface will contains two methods. One will says if the serial port is connected or not. And the other one will send data to the serial port.

  • The method isConnected()

This method returns a boolean, which identifies whether the serial port is connected or not.

  • The method sendToSerialPort()

This method returns a boolean which confirm wether the data has been sent or not. It takes in argument the data you want to send to the serial port.

The required interfaces

In this example, you are going to use only three external interfaces.

  • At first, you need the debug interface to be able to print some debug messages in the log of your application.
  • Then you will need the modem interfaces to check if the modem of the device is on and get some information about the modem.
  • And finally you will use the GPS interface to have the GPRMC data.

The parameters

In this application, you are going to use two parameters.

  • The first one will be use to choose which serial port, you want to use because some of our devices have two serial ports.
  • And the second one will be use to set the baud rate of the serial port.

The implementation of the application.

All the codes you are going to produce will be in the initial file, you have created in the jcpn. If this file has not been generated, please be sure that you have saved the jcpn file.

At first you need to declare a set of variables. Those variables will be used to access component inside the methods of the project. This will make it very easy to use the Mobile Devices’ APIs.

	/**
	 * DO NOT ACCESS COMPONENTS INTERFACE IN STATIC CONSTRUCTOR.
	 */
	private static Component 	_cpn 		= null;
	private static Debug 		_dbg 		= null;
	private static Modem 		_modem 		= null;
	private static Gps 			_gps 		= null;

	private static Connection 	_connection 	= null;
	private static InputStream 	_iStream 		= null;
	private static OutputStream	_oStream 		= null;

	private static boolean 		_isConnected 	= false;
	private static boolean 		_exit 			= false;

The method start()

This method is the first one to be executed by the software. It is in this function that you are going to launch the different threads you are using.
Here there are two thread, one to write the data and the other one to read the data.
As mentionned earlier, the first step is to initialize the objects, that have been created before. Then the threads are started.

public void start() 
	{
		/**
		 * Initialize objects
		 */
		_cpn = Component.getInstance();
		_dbg = _cpn.getDebug();
		_modem = _cpn.getModem();
		_gps = _cpn.getGps();

		_dbg.init(0);

		/**
		 * Start run() function to write data
		 */
		new Thread(this).start();
		/**
		 * Start another thread to read data
		 */
		new Thread(new InAgent()).start();
	}    

Implementation of the provided interface

In the jcpn a provided interface has been declared, so it needs to be implemented.
Here is, first, the isConnected() method. This method simply returns a variable that is updated in the other methods of the project.
Then the method sendToSerialPort() follows. This function writes the data you want on the serial port byte by byte.

	/**
	 * Entry point for others functions to check if the serial port has been opened
	 */
	public boolean isConnected() 
	{
		return _isConnected;
	}

	/**
	 * Entry point for others functions to send data
	 */
	public boolean sendToSerialPort(BuffRef data) 
	{
		try {
			if (data != null)
				_oStream.write(data.getBytes());
			return true;
		} catch (Exception e) {
			_dbg.error("Can not send data to serial port");
			return false;
		}
	}

Management of the connection.

  • Open the connection

This method is used to open a communication socket on the serial port. This method uses both of the parameters that have been created in the jcpn file, the first to manage the port that the application is using and the other to set the baud rate. Then it creates a new connection with the correct settings or returns an error if the connection has not been made.

	/**
	 * Open the serial connection.
	 * The way this methods opens the serial port depends of your communicator type.
	 *
	 * @return true when opening connection was successful.
	 *         false when opening the connection failed.
	 */
	private boolean openConnection() 
	{
		// Build comport initialization string
		String init = "comm:" + _cpn.param_port() // on C4D must be 1 for black port and 3 for grey port
		+ ";baudrate="+ _cpn.param_baudrate()
		+ ";bitsperchar=8;stopbits=1;parity=none;autocts=off;autorts=off;blocking=off;";

		// Open connection
		try {
			_dbg.print("open serial port: " + init);
			_connection = Connector.open(init);
			_iStream = ((InputConnection) _connection).openDataInputStream();
			_oStream = ((OutputConnection) _connection).openDataOutputStream();
		} catch (Exception e) {
			_dbg.error("serial port "+_cpn.param_port()+" could not be opened !");
			e.printStackTrace();
			_isConnected = false;
			return false;
		}
		_isConnected = true;
		return true;
	}	
  • Close connection

With this method the connection that has been opened on the serial port, is closed properly.

	/**
	 * Close all elements, flush its and set elements to null
	 * @return true if all elements are closed with success
	 *         false otherwise
	 */
	private boolean closeConnection() 
	{
		try {
			if (_iStream != null) {
				_iStream.close();
				_iStream = null;
			}
			if (_oStream != null) {
				_oStream.flush();
				_oStream.close();
				_oStream = null;
			}
			if (_connection != null) {
				_connection.close();
				_connection = null;
			}
		} catch (Exception e) {return false;}
		return true;
	}

The first thread (write).

This method is the main function of the project. It is here that all the information needed are retrieved and then sent to the serial port.
So the function is using two “BuffRef”, which are similar to a buffer, to save the information regarding the modem and the GPS data, that are going to be sent to the serial port.
Once the data has been saved, the method opens a connection with the serial port and if the serial port is open then it sends the data.

	/**
	 * Main function
	 */
	public void run()
	{
		BuffRef frame = new BuffRef(100);
		BuffRef imei = new BuffRef(15);
		_modem.getIMEI(imei);

		/**
		 * Try to open serial port COM1
		 */
		if (!openConnection()) {
			_dbg.error("Cannot open serial port");
			return;
		}

		/**
		 * Send data on serial port : IMEI modem and GPS frame ($GPRMC)
		 */
		while (!_exit) {
			_gps.getFrame(1, frame, false);
			if (sendToSerialPort(imei))
				if (sendToSerialPort(frame))
					_dbg.print("Data sent !!!");
				else
					_dbg.print("No data sent");
			try {Thread.sleep(5000);} catch (Exception e) {}
		}

		/**
		 * Close connection
		 */
		closeConnection();

		/**
		 * MANDATORY : DO NOT LEAVE THE THREAD.
		 */
		_dbg.print("Leave main loop");
		while (true) {
			try { Thread.sleep(10000); }
			catch (Throwable e) {}
		}		
	}

The second thread (read)

This second thread checks if there is some data to read on the serial port and print some debug lines in the log.

	class InAgent implements Runnable 
	{
		public void run() 
		{
			int size = 0;
			int nbread = 0;
			int bufLen = 2048;
			byte buf[] = new byte

	class InAgent implements Runnable 
{
public void run()
{
int size = 0;
int nbread = 0;
int bufLen = 2048;
byte buf[] = new byte[bufLen];

// checks it is possible to read on the port
while (!_isConnected)
{
nbread++;
try {Thread.sleep(1000);} catch (Throwable e){}
if (nbread%10 == 1)
_dbg.debug("wait for connection");
}

if (_iStream == null) {
_dbg.print("OutputStream is null, exit reading thread !");
return;
}

while (!_exit)
{
try {
if ((size = _iStream.available()) > 0) {
nbread = _iStream.read(buf, 0, size);
_dbg.print("READ (" nbread ")" new String(buf, 0, nbread));
if (nbread != size) {
_dbg.warn("Mismatched read");
}
}
} catch (Exception e) {
_dbg.print("Error reading message from server : " e);
}

try {Thread.sleep(1000);} catch (Throwable e) {}
}
}
}

You can down load the project here