PlaceLab Bluetooth Phone to PC Data Transfer HOWTO
Table of Contents
- Introduction
- Starting a
BluetoothServer
- Connecting to your
BluetoothServer
- Making a new
BluetoothService
As the PlaceLab team started development for Series60 phones it was clear that
some sort of transfer utility needed be created to get important data onto and
off of the phone. Along the path of developing application specific transfer
utilities we kept duplicating the same workarounds and handshaking. So we
rolled these transfer procedures into a reusable standardized user interface.
Each end of the transfer has it's own piece to run when establishing a
connection. On the PC side, BluetoothServer handles all incoming connections
from phones. On the phone side, there is more than one entry point, but the
user interface usually looks this:
NOTE: The Place Lab distribution uses Blue Cove for
javax.bluetooth support. The current Blue Cove release only works under
Windows XP Service Pack 2. Since Place Lab itself uses the standard Java
Bluetooth interface (JSR-82: javax.bluetooth), it should work on any platform
supporting this. Some of the instructions below are Blue Cove-specific.
Right now the Placelab distribution only supports BluetoothServer
on Windows XP Service Pack 2. If this is not the platform you are working with
then you might want to look into a javax.bluetooth for your
particular platform.
The BluetoothServer can be started by either running
org.placelab.midp.server.BluetoothServer from the placelab.jar or
simply running PlacelabPhone_BluetoothServer.jar in the phone distribution.
After it starts you should be able to see output that looks something like
this:
initialized bluetooth service.
Registering Log Upload Proxy
Registering Map Loader Proxy
Registering Activity Downloader
Registering GPS Time Downloader
Registering ESM Question Uploader (0)
Registering Bluetooth Console
Registering Place Downloader
listening...
If you have the Nokia PC Suite installed on your machine make sure mRouter (the
system tray item that looks like two disconnected plugs) is not configured to
listen on any Bluetooth ports. This can interfere with the connection process
between the PC and phone.
The final step is to make sure that the computer running the
BluetoothServer is discoverable. On Windows XP right-click on the
Bluetooth icon in the system tray. Select "Open Bluetooth Settings".
Go to the "Options" tab and select the "Turn discovery on"
checkbox.
If you get an error that looks like this:
java.lang.UnsatisfiedLinkError: no intelbth in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1517)
...
It usually means that you don't have BlueCove installed correctly. Make sure
BlueCove.jar is in your classpath and intelbth.dll is in a place the JVM can
find it (e.g. c:\windows\system32 or the directory the JVM is executed from).
Since there is no one utility for transfer data on the phone I'm going to use
the stumbler log uploading as an example. To access the log uploading, start
the Stumbler application on the phone. Select "Upload Stumble Logs"
from the Options menu. The screen should look something like this:
The phone keeps a cache of previous seen servers to connect to. If the
computer where your BluetoothServer is running is listed in the
"Hosts:" list then select it. If not, then select "More
Devices" from the Options menu. This should start a search of the current
environment for new servers to connect to.
If the computer running the BluetoothServer does not show up in
the list of hosts after a new search, then it is probably the case that your
computer is not set as discoverable in the Bluetooth Preferences. Look back at
the previous section as to how to do enable
discoverable.
After selecting the correct server, select "Connect" from the Options
menu. A bunch of status should start showing up where it used to say
"Ready." If all goes right then it should look something like this:
Common Errors
This error usually means the computer you were trying to connect to was not in
range. It is possible you are trying to connect to a stale entry in your
server cache. Try refreshing your device list by doing a "More
Devices".
This error usually means the computer you were trying to connect to was not
running the BluetoothServer. Make sure to follow the instructions
in the previous section.
It is pretty easy to create a new service that takes advantage of this
pre-existing BluetoothServer/BluetoothClient
codebase. All the following code references are in the
org.placelab.midp and org.placelab.midp.server
packages.
The first step to create a new service is adding a unique service type in the
BluetoothService interface. Just add another constant that is
different than the others listed there.
public interface BluetoothService {
...
public final static byte PLACE_UPLOAD_SERVICE = 7;
public final static byte EXAMPLE_SERVICE = 8;
...
}
Next, a server component needs to be created by implementing the
BluetoothService interface. The getServiceType()
method should return the constant that you just defined in the
BluetoothService interface. The getName() method is
just used as a human readable name of the service, and should return something
that is sensible. The final and most important method to implement is the
newClient(DataInputStream in, DataOuputStream out). In this
method, the actual details of the data transfer should be worked out. Be sure
to make use of the read<type>() and
write<type>(). Java is on both ends so this makes your life
considerably easier.
public class ExampleService implements BluetoothService {
public String getName() {
return "Example Service";
}
public byte getServiceType() {
return BluetoothService.EXAMPLE_SERVICE;
}
public void newClient(DataInputStream in, DataOutputStream out) {
out.writeUTF("hello");
out.flush();
if (!in.readUTF().equals("bye"))
System.err.println("Bad message!");
}
}
After creating the new BluetoothService class, it needs to be
registered with the BluetoothServer by calling
addService() in the main() method.
public class BluetoothServer {
...
public static void main(String args[]) {
...
bs.addService(new PlaceService());
bs.addService(new ExampleService());
...
}
}
A matching BluetoothClient needs to be created for the
human readable name. And the getServiceType() should return the
same exact constant as the matching BluetoothService. Instead of
a newClient() method, BluetoothClient has the
handleConnection(DataInputStream in, DataOutputStream out) method.
public class ExampleClient extends BluetoothClient {
public String getName() {
return "Example Client";
}
public byte getServiceType() {
return BluetoothService.EXAMPLE_SERVICE;
}
public void handleConnection(DataInputStream in, DataOutputStream out) {
if (in.readUTF.equals("hello"))
out.writeUTF("bye");
out.flush();
}
}
The final step is to integrate the new ExampleClient into your
existing MIDlet. To do this you must use the UIComponent
interface to define a pathway to show the ExampleClient and then
return back to the calling screen. Example:
public class SomeForm implements UIComponent {
public Display display;
public Form someForm;
...
public void showUI(UIComponent from) {
display.setCurrent(someForm);
}
public void showExampleClient() {
BluetoothClient client = new ExampleClient(display, this);
client.showUI(this);
}
}
This code can obviously be changed around to produce more clever behavior, but
it lays out the skeleton.
|