Klings.NoWires.Code()

Home

J2ME CDC CLDC MIDP 1.0 MIDP 2.0 MIDlets JABWT

Bluetooth

BTBrowser BTBenchmark KlingsLib

Code Structure Inquiry Service
search
RFCOMM Pitfalls Service record usage Service record manipulation

Devices Developers

Tools Rococo IDEs WTK NDS Antenna

How-To Bluez OBEX Eclipse NetBeans JBuilder WAP

About me

RFCOMM links with the JABWT

This document describes how to setup communication links with the JABWT. Communication should be done in a seperate thread in order to not freeze the user interface of a MIDlet. Developers should have this in mind when developing MIDlets in order to spare not only themselves, but also the users from a slow responding MIDlet. The interested reader will find explanations and detailed information on how this can be done in the following two documents:

http://developers.sun.com/techtopics/mobility/midp/articles/threading/
http://developers.sun.com/techtopics/mobility/midp/articles/threading2/

L2CAP links are the basis for all communication through the JABWT. An L2CAP link can be set up by supplying a "btl2cap://hostname:[PSM | UUID];parameters" type of URL as parameter to the Connector.open() method. Care must be taken by the developer when using L2CAP links. The developer must keep track of the receive MTU (Maximum Transfer Unit) and transmit MTU and divide data into chunks such that they may be sent in packages with appropriate payload size. These concerns increase the complexity of Bluetooth application development.

Fortunately, the Bluetooth Serial Port Profile (SPP) is implemented and available through the JABWT. The SPP is based on the RFCOMM protocol, providing RS-232 serial port emulation for Bluetooth links. The RFCOMM protocol is again based on L2CAP, so it is actually an L2CAP link used for data transfer. Setting up an RFCOMM connection is just as easy as setting up an L2CAP connection. The URL supplied as parameter to the Connector.open() is on the form: "btspp://hostname:[channel | UUID];parameters."

RFCOMM takes care of all the important details, like receive MTU and transmit MTU and dividing data into chunks so the MTU's are not violated. RFCOMM should therefore be the preferred link type for most developers.

Communication is usually a blocking operation and should therefore be done in a separate thread in the MIDlets.

Check out "Pitfalls" for tips on using RFCOMM links.

RFCOMM server

Setting up an RFCOMM server is fairly easy, as shown by the following code:

	LocalDevice local = null;
	StreamConnectionNotifier server = null;
	StreamConnection conn = null;
	
	String connectionURL = "btspp://localhost:393a84ee7cd111d89527000bdb544cb1;"
			+ "authenticate=false;encrypt=false;name=RFCOMM Server";
		
	/*
	 * Make sure the device is discoverable, else clients cannot find
	 * our service
	 */

	try {
		local = LocalDevice.getLocalDevice();
		local.setDiscoverable(DiscoveryAgent.GIAC);
	} catch (BluetoothStateException e) {

		// Error handling code here

	}
	
	/*
	 * First get a StreamConnectionNotifier. It can be used to get
	 * the service record created for us, so we can manipulate the 
	 * service record.
	 */
	
	try {
		server = (StreamConnectionNotifier) Connector.open(connectionURL);
	} catch (IOException e1) {

		// Error handling code here
	
	}
	
	/*
	 * Calling acceptAndOpen() will register the service record in the
	 * Bluetooth SDDB and block until a client connects to this service.
	 */

	try {
		conn = server.acceptAndOpen();
	} catch (IOException e2) {

		// Error handling code here
	
	}

This is actually all the code needed to create a service record with UUID: 393a84ee7cd111d89527000bdb544cb1 and support for RFCOMM links. Additional parameters have been specified, neither authentication or encryption is enforced. The service will have service name RFCOMM Server, this will be added in attribute id 0x100 in the service record. All other attributes are set automatic by the implementation.

When a client connects to the service, input and output streams can be obtained from the StreamConnection object conn. Communication can then begin.

RFCOMM client

Clients will typically do an inquiry and service search before connecting to a server. The example service above can be found by specifying "393a84ee7cd111d89527000bdb544cb1" as the UUID to search for during service search.

When the desired service is found, a connection can be created with very little effort:

	/*
	 * The service we want to connect to has been found earlier
	 * (by service search) and a reference to the service record is
	 * through the object named: service (which is of type ServiceRecord)
	 */
	
	StreamConnection conn = null;
	
	/*
	 * The connection URL is extracted from the service record.
	 * Authentication and encryption is disables. The client does not 
	 * require to be the master of the connection (the false parameter)
	 */
	
	String connectionURL = service.getConnectionURL(
				ServiceRecord.NOAUTHENTICATE_NOENCRYPT,false);
	
	/*
	 * A StreamConnection is obtained from the connection URL
	 */
	
	try {
		conn = (StreamConnection) Connector.open(connectionURL);
	} catch (IOException e) {
		// Error handling code here
		
	}
	
	/*
	 * The conn object is now a working StreamConnection, from wich input
	 * and output streams can be obtained, enabling communication.
	 */

The sample code shows just how little code is needed to set up a client connection. To see how this fits into a complete MIDlet you should check out the sourcecode for my benchmark MIDlet. It will be available soon, it needs some documentation and minor code cleanup.



This page was last updated 14. Jul. 2006

Comments and feedback are highly appreciated.

You can reach me at: klings (at) nowires (dot) org