In Part 1 we went over the basics of Bluetooth technology and some possible development opportunities Bluetooth gives us. Part 2 of this article goes into a little more detail how to create a Bluetooth server and client.
About the Example
In keeping things simplistic as possible proper handling of multiple slaves/clients is not implemented essentially it only works with one server and one client. As well the sample is just that sample code, it is coded from the perspective of getting the two nodes to communicate with each without any real effort in “proper” coding technique/design. Remember the focus is to get you started with the actual Java Bluetooth API.
Before we continue you should download the JSR 82 Java Doc API from http://jcp.org/aboutJava/communityprocess/final/jsr082/ . Familiarize yourself with the available classes and get feel where things are. We won’t go into every single class or explain every single detail mainly because the Java Doc does a good job of this already.
This demo includes three source files / classes:
This example uses RFCOMM for transferring data the other two options are L2CAP and OBEX. In short RFCOMM is used for streaming data, L2CAP is for packet data and OBEX is for object data.
Client Overview
Let us start with the client, the first thing we need to do is to determine what Bluetooth devices and services are there around us. First get the local device and obtain the discovery agent.
LocalDevice localDevice = LocalDevice.getLocalDevice();
discoveryAgent = localDevice.getDiscoveryAgent();
Now to start searching for Bluetooth devices within the area use the startInquiry method from the DiscoveryAgent class.
discoveryAgent.startInquiry(DiscoveryAgent.GIAC,this);
DiscorveryAgent.GIAC stands for “The inquiry access code for General/Unlimited Inquiry Access Code” refer to the Java Docs for the other inquiry access code definitions.
Now with the use of the Discovery Listener you have available to you 4 call back methods. As defined in the Java Doc they are:
That is it for the discovery part! It really is that simple. Now with these calls being triggered you can obtain device information, service information and with that make the appropriate data transmission/communication with the Bluetooth server. (see source code)
In the deviceDiscovered method we obtain some device info which are more or less self-explanatory. Except for the Major and Minor classification, these two attributes let you know what type of device it is. The following is an incomplete sample of the Major and Minor definitions, for a complete list visit www.bluetooth.org . When you run the program you will notice it outputs Major 512 and Minor 4, according to the chart it is a Phone / Celluar.
In the servicesDeiscovered method you can obtain the respective URL needed to open a connection to the available service(s).
for(int i=0;i
Now that you have the url, you can send data through the standard Generic Connector.
String msg = "Say Hello World";
conn = (StreamConnection)Connector.open(serviceUrl);
OutputStream output = conn.openOutputStream();
output.write(msg.length());
output.write(msg.getBytes());
output.close();
Server Overview
In the server class we need to initialize once again but this time instead of searching for devices we need to setup a server
private static String serverUrl = "btspp://localhost:" +
BluetoothEchoDemo.RFCOMM_UUID + ";name=rfcommtest;authorize=true";
.
.
.
conn = null;
localDevice = LocalDevice.getLocalDevice();
localDevice.setDiscoverable( DiscoveryAgent.GIAC );
notifier = (StreamConnectionNotifier)Connector.open(serverUrl);
.
.
.
Now make a connection with the same Generic Connector you use when making HTTP calls. The url definition is as follows:
scheme://host:port;parameters
Now wait for a client response, this pauses the thread until it receives something.
conn = notifier.acceptAndOpen();
Once a client responds read the data in and send back a message
// Read Data Transmission
String msg = BluetoothEchoDemo.readData(conn);
System.out.println("Received Message from Client: " + msg);
// Send Back a Message
msg = "Hello Back from Server";
output = conn.openOutputStream();
output.write(msg.length()); // length is 1 byte
output.write(msg.getBytes());
output.close();
Running the Example
Download the source and compile from here.
You will need to invoke the Sun WTK twice because the outputs are displayed in the consoles. Start one instance and select Server, then start a second instance and select Client (Yes you need to start 2 instances of the WTK not just simply hit the "run" button twice on the same instance because the console of the first instance will not show). Like HTTP calls you may need to answer yes for connections being made.
In the end you will see the following in the server console:
Starting Echo Server
Server Running...
Received Message from Client: Say Hello World
In the client console you will see:
Device Discovered
Major Device Class: 512 Minor Device Class: 4
Bluetooth Address: 000060854FBF
Bluetooth Friendly Name: WirelessToolkit
InquiryCompleted
ServicesDiscovered
SERVICE_SEARCH_COMPLETED
Service URL: btspp://000060854FBF:1;master=false;encrypt=false;authenticate=false
Hello Back from Server
Summary and What is Missing
You should be able to make a basic RFCOMM communication between a Bluetooth client and server. However, even though we went through a lot detail there are still details that were left out or not mentioned. Now that you have a better understanding of Bluetooth with J2ME you need to dive deeper into the following:
As a recap the example in this article the primary goal is to give you an introduction to setting up the communication between a master and slave. Rather then jumping into a full example and getting over whelmed this sample code layouts out the bare bones. Along with more research into the APIs and review of more complete samples of Bluetooth you will be on your way to making some exciting new Bluetooth games/aplications. More complete examples are available with developments kits such as:
Source Code
Download Source to Bluetooth Example (Click Here)
Development Kits
http://java.sun.com (Wireless Toolkit 2.2 Beta includes JSR 82)
http://forum.nokia.com (Nokia Developer Suite 2.2 includes JSR 82)
http://developer.sonyericsson.com (J2ME SDK 2.1.4 Beta includes JSR 82)
http://www.atinav.com
http://www.rococosoft.com
http://www.esmertec.com
http://www.smartnd.com
http://www.oi-us.com
Resources
http://jcp.org/aboutJava/communityprocess/final/jsr082/
http://www.bluetooth.com
http://www.bluetooth.org
http://opensource.nus.edu.sg/projects/bluetooth/
http://bluez.sourceforge.net/
http://benhui.net
Jason is a wireless and open source developer enthusiast who enjoys creating synergy and sharing knowledge in the software development world. To learn more about him visit his personal site at http://www.jasonlam604.com/