Aspire :: OSGi Bundles :: Bluetooth Server
Goal
This bundle provides a multi-client bluetooth server.
It provides a BluetoothServerService service when activated, and must be configured before being the server really starts.
It uses the
Bluecove JSR82 implementation, so all the device configuration may be done by setting Java system properties (see
the bluecove documentation).
The server waits for a new client via a blocking call, so run it in a specific thread.
Each client is run in a thread, due to blocking InputStream calls.
Sample usage
How to start the server
// Read properties and threads
BluetoothServerService m_server = new BluetoothServerImpl();// Set the device discoverable
m_server.prepareServer();// Start listening in a special thread
m_server.startServer();
How to stop the server
How to configure the server
The server can be configured via a property XML file, given as an InputStream parameter to the prepareServer() method.
Sample : Read a configuration XML file embedded in the bundle JAR file.
m_server.prepareServer(getClass().getResourceAsStream("/bluetoothConfig.xml"));
Parameters :
Key | Type | Description | Default |
---|
uuid | String | Server's "Universally" Unique IDentifier | |
serviceName | String | Server's name | |
authenticate | boolean | Server needs client authentification | false |
encrypt | boolean | Communication must be encrypted | false |
inquiryMode | int | Type of inquiries to respond to (GIAC or LIAC) (see http://bluecove.org/bluecove/apidocs/javax/bluetooth/DiscoveryAgent.html) | GIAC |
debug | boolean | Verbose mode | false |
readingMode | BYTE, CHAR or UTF | Which DataInputStream reading method must be used (readByte, readChar or readUTF) | CHAR |
max_threads | int | Maximum number of communication threads (not used) | |
How to read data from devices
This bundle use a listener model : each class who needs to read communication data must implement the CommunicationListener interface.
This interface provides three functions :
- commBegin(String logicalName) : Called when a client has just connected the server, logicalName is UUID generated by the server to identify a connection
- commEnd(String logicalName) : Called when a client has ended the connection, or when the server stops.
- commRead(String logicalName, String data) : Called when the server read a line from the client.
The logical name is the client unique identifier, based on its Bluetooth address and its friendly name (if present).
class BluetoothComm implements CommunicationListener {
private BluetoothServerService m_server; public BluetoothComm()
m_server = new BluetoothServerImpl();
m_server.prepareServer(getClass().getResourceAsStream("/bluetoothConfig.xml"));
m_server.startServer();
m_server.addCommunicationListener(this);
} public void commBegin(String logicalName) {
System.out.println("Client connected : " + logicalName);
} public void commEnd(String logicalName) {
System.out.println("Client gone : " + logicalName);
} public void commRead(String logicalName, String data) {
System.out.println("Read '" + data + "' from " + logicalName); // Write some data in response
try {
m_server.getCommunication(logicalName).writeData("ACKn");
}
catch (IOException e) {
// Error occurred during write process
}
}
}
Issues under Linux
License issue
- For latest versions BlueZ (v4 and higher), this bundle needs bluecove-gpl library to work, under GPL.
- For older versions, it may be possible to use bluecove-bluez instead, under Apache License 2.0 (not tested).
Rights issue
This bundle needs to have root rights in order to set the device discoverable.
A solution to bypass this problem is to set the device discoverable in system wide configuration.
(It can be done with user rights with gnome-bluetooth, for example).
Test
Operating systems
- Windows
- Windows 7, 32 bits version
- Linux
- Fedora 13, 64 bits version, with bluecove-gpl
Dongles
- Built-in AsusTEK bluetooth device, with generic drivers
Hints for future improvements
- Control the number of client threads, by aggregating them in a thread pool.