First example: RFCommBrowser, a Bluetooth sniffer (J2SE)
Purpose: When developing Bluetooth applications, it is important to know which Bluetooth devices are reachable, what are their addresses and Bluetooth friendly names and which services they expose. What you need is a utility called a Bluetooth enumerator, Bluetooth sniffer or Bluetooth browser. Some of them are available on the Internet, but with the ch.aplu.bluetooth package it is easy to write your own application best adapted to your needs.
Often only the services concerning the serial emulator, called RFComm, are if interest. In the following example we restrict the service search to the UUID that corresponds to RFComm (0x0003), but it's up to you to extend the service search.
To extend the search for other UUIDs, just add the UUIDs you need in the uuids array, e.g for OBEX:
int uuid_RFCOMM = 0x0003;
int uuid_OBEX = 0x0008;
int[] uuids = {uuid_RFCOMM, uuid_OBEX};
For the sake of simplicity the GUI consists of a simple console from the class ch.aplu.util. You may download the package from here. If you don't like it, implement your own GUI.
// RFCommBrowser.java
import javax.bluetooth.*;
import java.util.*;
import ch.aplu.bluetooth.*;
import ch.aplu.util.*;
public class RFCommBrowser implements BluetoothResponder
{
private Console c = new Console();
private BluetoothFinder btf;
public RFCommBrowser()
{
int uuid_RFCOMM = 0x0003;
int[] uuids = {uuid_RFCOMM};
c.println("Searching for Bluetooth devices. Please wait...");
btf = new BluetoothFinder(uuids, false, this);
}
public void notifyBluetoothDeviceSearch(Vector deviceTable)
{
// Vector elements: DeviceInfo {RemoteDevice, DeviceClass}
c.println("\nDevice report:");
if (deviceTable.size() > 0)
{
for (int i = 0; i < deviceTable.size(); i++)
{
BtDeviceInfo di = (BtDeviceInfo)deviceTable.elementAt(i);
RemoteDevice dev = di.getRemoteDevice();
String deviceName = btf.getDeviceName(dev);
DeviceClass dc = di.getDeviceClass();
int majorDC = dc.getMajorDeviceClass();
int minorDC = dc.getMinorDeviceClass();
c.println("Device found. Name: " + deviceName);
c.println(" Major Device Class: " + majorDC);
c.println(" Minor Device Class: " + minorDC);
}
c.println("\nSearching for RFCOMM services. Please wait...");
}
else
c.println("No devices found");
}
public void notifyBluetoothServiceSearch(Vector serviceTable)
{
// Vector elements: ServiceInfo {RemoteDevice, ServiceRecord}
c.println("\nService report:");
if (serviceTable.size() > 0)
{
for (int i = 0; i < serviceTable.size(); i++)
{
BtServiceInfo si = (BtServiceInfo)serviceTable.elementAt(i);
RemoteDevice dev = si.getRemoteDevice();
ServiceRecord sr = si.getServiceRecord();
// Show host name
String deviceName = btf.getDeviceName(dev);
c.println("Service of host: " + deviceName);
// Show service name
String serviceName;
DataElement de = sr.getAttributeValue(0x0100);
if (de != null)
serviceName = (String)de.getValue();
else
serviceName = "not found";
c.println(" Service name: " + serviceName);
// Show connection URL
String serviceUrl = sr.getConnectionURL(0, false);
c.println(" Connection URL: " + serviceUrl);
c.println();
}
c.println("\nAll done");
}
else
c.println("No services found");
}
public static void main(String[] args)
{
new RFCommBrowser();
}
}
Execute RFCommBrowser using WebStart
(Widcomm compatible Bluetooth device needed)
Download RFCommBrowser standalone version
Discussion: The constructor of the class BluetoothFinder starts the device and service search. The results are reported by the callback methods notifyBluetoothDeviceSearch() and notifyBluetoothServiceSearch() that are declared in the interface BluetoothResponder. All information about detected devices and their services can be retrieved from the parameters deviceTable and serviceTable respectively. The package documentation gives you further information. You may also consult the documentation of the Bluecove library.
Second example: RFCommBrowser for mobile phones
Purpose:One of the design aims of the Bluetooth package was the easy migration from desktop applications to MIDlet applications running on a mobile phone. Using the Gidlet framework it is straightforward to port the J2SE application to J2ME: Derive the application class from Gidlet and move the code from the Constructor to the method void main().
// RFCommBrowser.java
import java.util.*;
import javax.bluetooth.*;
import ch.aplu.gidlet.*;
import ch.aplu.bluetooth.*;
public class RFCommBrowser extends Gidlet
implements BluetoothResponder
{
private MConsole c = new MConsole(0, BLUE, WHITE, 1);
private BluetoothFinder btf;
public void main()
{
int uuid_RFCOMM = 0x0003;
int[] uuids = {uuid_RFCOMM};
c.println("Searching RFCOMM services...");
btf = new BluetoothFinder(uuids, null, this);
}
public void notifyBluetoothDeviceSearch(Vector deviceTable)
{
// Vector elements: DeviceInfo {RemoteDevice, DeviceClass}
c.println("Device report:");
if (deviceTable.size() > 0)
{
for (int i = 0; i < deviceTable.size(); i++)
{
BtDeviceInfo di = (BtDeviceInfo)deviceTable.elementAt(i);
RemoteDevice dev = di.getRemoteDevice();
String deviceName = btf.getDeviceName(dev);
DeviceClass dc = di.getDeviceClass();
int majorDC = dc.getMajorDeviceClass();
int minorDC = dc.getMinorDeviceClass();
c.println("Device found. Name: " + deviceName);
c.println(" Major Device Class: " + majorDC);
c.println(" Minor Device Class: " + minorDC);
}
c.println("\nSearching services...");
}
else
c.println("No devices found");
}
public void notifyBluetoothServiceSearch(Vector serviceTable)
{
// Vector elements: ServiceInfo {RemoteDevice, ServiceRecord}
c.println("Service report:");
if (serviceTable.size() > 0)
{
for (int i = 0; i < serviceTable.size(); i++)
{
BtServiceInfo si = (BtServiceInfo)serviceTable.elementAt(i);
RemoteDevice dev = si.getRemoteDevice();
ServiceRecord sr = si.getServiceRecord();
// Show host name
String deviceName = btf.getDeviceName(dev);
c.println("\nServices of host: " + deviceName);
// Show service name
String serviceName;
DataElement de = sr.getAttributeValue(0x0100);
if (de != null)
serviceName = (String)de.getValue();
else
serviceName = "not found";
c.println("Service name: " + serviceName);
// Show connection URL
String serviceUrl = sr.getConnectionURL(0, false);
c.println("Connection URL: " + serviceUrl);
}
}
else
c.println("No services found");
}
}
Download JAR/JAD files for installation on mobile phone. (You can install it directly on your mobile phone from http://www.aplu.ch/g.)
Discussion: It is very convenient to use MConsole to report the results, because the display behaves almost the same as a standard console window (println-methods, horizontal and vertical scrolling).
|