|
|
YOUR FEEDBACK
Did you read today's front page stories & breaking news?
SOA World Conference
Virtualization Conference $200 Savings Expire May 16, 2008... – Register Today!
SYS-CON.TV |
TOP THREE LINKS YOU MUST CLICK ON Java in the Realworld
Go Wild Wirelessly with Bluetooth and Java
Developing portable Bluetooth apps
By: Ben Hui
Digg This!
As a frequent visitor to J2ME and Bluetooth developer forums, I've noticed that one of the most frequently asked questions is "How do I get started with Bluetooth?" Despite its introduction in 1998 and a highly hyped year in 2001, Bluetooth application development remains hideous and challenging for lots of developers. Many experienced developers are looking for material that goes beyond a basic introduction and covers various aspects of real-life Bluetooth application development. This article will take you to the next step of Bluetooth development and look at a newly developed specification that can assist Bluetooth developers in building applications rapidly. I'll discuss some important concepts of this specification and provide a walkthrough of a real Bluetooth application, BlueChat, that will cover some important design and implementation elements of a typical Bluetooth application. For those readers who have little or no experience with Bluetooth, the resources listed at the end of this article provide additional information. To compile and execute the BlueChat example application, you need to obtain the J2ME Wireless Toolkit 1.0.4 and the Rococo Impronto Simulator. Refer to the resources section for the download location. Bluetooth Concept The functionality of Bluetooth is governed by a public and royalty-free specification and defined by the Bluetooth Special Interest Group. The Bluetooth specification defines both hardware and software layers. Traditionally, Bluetooth module manufacturers provide the necessary SDK to interface with their modules. One of the complexities of Bluetooth development is the fragmentation of these SDKs and APIs. Vendor-specific SDKs force developers to adopt proprietary APIs for their respective Bluetooth chip sets. Bluetooth applications built on top of these APIs are not portable across devices and platforms. But isn't Bluetooth a standardized specification? The Bluetooth specification as defined by Bluetooth SIG is a functional specification of the technology. It describes how proper Bluetooth devices behave, and how they interoperate with each other (via Profiles). It does not describe how Bluetooth devices can be programmed nor how applications exercise a Bluetooth device's functions and utilize communication channels. The need for a standardized API arises in order to develop Bluetooth applications in a platform-independent manner. Java Bluetooth API (JSR-82) The benefits of JABWT nevertheless come with a cost. The Bluetooth specification is designed to cover a diverse range of devices and usage scenarios. To complement this diversity the scope of JABWT took the lowest common denominator approach. Only the most commonly used profiles and functions are included in JABWT. In particular, Generic Access Profile, Service Discovery Profile, Serial Port Profile, Generic Object Exchange Profile, and their respective protocols are supported. These profiles allow JABWT applications to perform the following functionalities:
Design of a Bluetooth Application - A Bluetooth Chat Room For this article we make some assumptions to simplify the application in order to focus on Bluetooth implementation topics:
Like many other network protocols, the Bluetooth connection model employs a client/server architecture. Our BlueChat application, on the other hand, operates in a peer-to-peer manner. Each running instance of BlueChat (or a node) can serve as a client and a server at the same time. It behaves as a client when BlueChat starts up; it searches and connects to existing running BlueChat devices. Once connected, it makes itself available for future clients to connect to. In such cases, it serves as a server for future client connections. Figure 1 represents the network relationship between three BlueChat applications. To logically represent an active BlueChat node, we use the concept of endpoint to encapsulate all the connectivity attributes of a node. An endpoint represents a unique message delivery destination and source regardless of whether it is a server or a client.
![]() A Bluetooth connection differs from a regular socket connection by its unique device and service discovery processes. Bluetooth applications typically start the device discovery process to identify connectable devices, which is followed by a service discovery process to obtain a reference (URL) to suitable services. To hide these complexities from the Graphical User Interface (GUI) elements, a network layer is introduced to serve as a façade to the Bluetooth API. This design is comparable to the Model-Viewer-Controller model where the Viewer component is decoupled from the Model component. The GUI can access Bluetooth connectivity via a simplified interface, which does all the discovery and connection establishment behind the scenes. This network layer also provides the functionality to send messages to and receive messages from other endpoints. A call back interface is in place to report any network activity back to the GUI. Figure 2 illustrates the relationship between various layers and components in BlueChat.
![]() The communication channel between each connected BlueChat endpoint is a structured data stream connection. We put together a simple protocol to coordinate the activity between each endpoint. This protocol includes the following features:
![]() Implementation Consideration
After a server connection is created, the service is not yet available to external clients (it is not discoverable). What has happened is that JABWT created a corresponding ServiceRecord for this service. A ServiceRecord is a collection of attributes that describes our service, and these attributes are searchable by clients. We can use localDevice.getRecord( server ) to retrieve the newly created ServiceRecord. You may notice that the ServiceRecord is not empty at this point; it is already populated with some default values that are assigned by the JABWT implementation based on the connection string and the implementation configuration when we perform Connector.open(). The server.acceptAndOpen() method notifies the Bluetooth implementation that the application is ready to accept incoming connections and make the service available. This also instructs the underlying implementation to store the ServiceRecord object in the SDDB, which occurs when server.acceptAndOpen() is first invoked. Notice that only the attributes stored in the SDDB can be seen and queried by other Bluetooth clients. Any subsequent change to the ServiceRecord must be reflected in the SDDB by using localDevice.updateRecord(). Now our BlueChat application is ready to accept a connection. But what if your friends are already chatting prior to the start of your BlueChat? If there is an existing chat room available, BlueChat should join the existing network by searching for other BlueChat services on each individual device and connecting to their services. Three steps must be taken to perform this action.
There are two other options for retrieving connectable devices, a cached devices list and a preknown devices list. Cached devices are remote devices that have been discovered in a previous inquiry. Preknown are remote devices that are preconfigured in BCC. In our example, we choose to ignore both cached and preknown devices. We want to retrieve the most up-to-date list of active BlueChat devices at the moment BlueChat is launched. Therefore, our BlueChat application always initiates a new search for all surrounding devices. Devices can be searchable in two modes, General Inquiry Access Code (GIAC) and Limited Inquiry Access Code (LIAC). When a device is set to GIAC, it basically means "I want to be discovered all the time." Devices that provide public and permanent services fall into this category. Printers and fax machines are examples of GIAC devices. On the other hand, LIAC discovery mode means "I want to be discovered for a short period of time, as requested by my user." Devices that provide on-demand connectivity will fall into this category. Examples are multiple player game consoles, mobile modems, and our BlueChat program. The device discovery and service discovery processes are performed in an asynchronous manner. A Bluetooth application must provide a callback object for the JABWT implementation to notify when devices or services are found. This callback object (the NetLayer$Listener inner class object in our case) implements the DiscoveryListener interface. When a device is found, the deviceDiscovered() method is invoked. We do some basic filtering (using the Major Service Class flag) to narrow down the candidate devices for our BlueChat application and ignore other unrelated devices (see Listing 3). When all candidate devices are discovered, the device search is completed and the searchCompleted() method is invoked. We initiate the service discovery process using DiscoveryAgent .searchServices(). This is where the ServiceRecord attributes become useful. ServiceRecord is not only a description of the services, but also a query of constraints during service discovery. The second parameter of searchServices() allows us to specify which attributes and values the services must have in order for us to discover them. We can provide the UUID for the service that we registered earlier and it narrows down the exact matching candidate services on a remote device. This mechanism not only improves the performance of the discovery process, but also reduces the possibility of conflict. Once the desired service (BlueChat service) is found, we can retrieve the corresponding connection URL and establish the physical connection (see Listing 4). To further validate that the connected service is indeed a BlueChat service, we immediately perform a handshake with the other party by sending a handshake signal (SIGNAL_HANDSHAKE) and exchanging the user screen name. Receiving parties must respond with an acknowledgment (SIGNAL_HANDSHAKE_ACK) to confirm the request (see Listing 5). To logically represent all the parties in the chat room, we introduce class EndPoint. From the application-level perspective, an endpoint encapsulates information for each actively connected BlueChat user and device. BlueChat uses EndPoint to identify which user to send a message to, and from which user a message is received. This abstraction allows us to hide the JABWT complexity from the GUI application. Endpoints are created when a connection is established between two BlueChat devices. Once created, we attach a reading thread and sending thread to the endpoint to manage the traffic between two endpoints. From this point on, two endpoints exchange user-entered messages (using SIGNAL_MESSAGE) until a termination signal is received. Implementation of this protocol can be found in the Reader and Sender classes. When a user exits BlueChat, the application sends the last message - a termination token (SIGNAL_TERMINATE) - to all connected parties. This token signals that the endpoint is no longer active. All receiving parties must return an acknowledgment (SIGNAL_TERMINATE_ACK) and remove the leaving endpoint from the active endpoint list. An endpoint can also be removed when the connectivity is dropped, which suggests the user has left the chat room without an explicit exit command (possibly due to a user's walking away from the Bluetooth effective range). Our GUI, based on the MIDP LCDUI API, provides a simple interface to send and receive messages. All received messages from all connected users are displayed sequentially on the screen, which creates a virtual chat room environment. When there are more messages to display than can fit onto one screen, older messages will roll off the upper edge. In this example application, users are not able to scroll back to see the past messages. Pressing the "Write" command takes users to a message-editing mode. Pressing the "Send" command sends the currently entered message to the chat room; all other connected users are able to see the message. To quit the chat room, pressing the "Exit" command sends a termination token to all other parties. Conclusion One aspect of Bluetooth development not touched upon in this article is Bluetooth security. Bluetooth provides basic security features for authenticating and authorizing access to devices and services. I recommend reading Chapter 8 of the JABWT specification for details on how to build a secure Bluetooth application.
LATEST JAVA STORIES & POSTS
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK BREAKING JAVA NEWS
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||