240 likes | 359 Views
Programming of Handheld and Mobile Devices. Lecture 20 Bluetooth for MIDlets Rob Pooley rjp@macs.hw.ac.uk. Wireless Ethernet (IEEE 802.11b). Based upon time-tested Ethernet standards. Operates in same unlicensed 2.4GHz band as Bluetooth and HomeRF.
E N D
Programming of Handheld and Mobile Devices Lecture 20 Bluetooth for MIDlets Rob Pooley rjp@macs.hw.ac.uk Programming Handheld and Mobile devices
Wireless Ethernet (IEEE 802.11b) • Based upon time-tested Ethernet standards. • Operates in same unlicensed 2.4GHz band as Bluetooth and HomeRF. • Optimized for data transmission up to 100 meters within office, campus LANs • Waits, retransmits in response to interference (good for data, bad for voice). • Wireless Ethernet Compatibility Alliance: • www.weca.net Programming Handheld and Mobile devices
Bluetooth • Set of hardware and software standards specifying how devices can communicate wirelessly in unlicensed 2.4GHz band. • Optimized for 30 meters or less, Personal Area Networks (PANs). • Based upon master-slave relationships in networks of up to eight devices, piconets. • Bluetooth Special Interest Group homepage at: • www.bluetooth.com • Java APIs for Bluetooth effort: • java.sun.com/jcp/jsr/jsr_082_bluetooth.html Programming Handheld and Mobile devices
What is Bluetooth? • The Bluetooth wireless technology was created to solve a simple problem: • replace the cables used on mobile devices with radio frequency waves. • The technology encompasses a simple low-cost, low-power, global radio system for integration into mobile devices. • Such devices can form a quick ad-hoc secure "piconet" and communicate among the connected devices. • This technology creates many useful mobile usage models because the connections can occur while mobile devices are being carried in pockets and briefcases Programming Handheld and Mobile devices
Usage model • Bluetooth ∗ usage model is based on connecting devices together, • It is focused on three broad categories: • voice/data access points, • peripheral interconnects, and • Personal Area Networking (PAN). Programming Handheld and Mobile devices
Voice/Data Access Points • Voice/data access points is one of the key initial usage models and involves connecting a computing device to a communicating device via a secure wireless link . • For example, a mobile computer equipped with Bluetooth technology could link to a mobile phone that uses Bluetooth technology to connect to the Internet to access e-mail. • The mobile phone acts as a personal access point. • Even better, the notebook can connect to the Internet while the cell phone is being carried in a briefcase or purse. • The Bluetooth usage model also envisages public data access points in the future. Programming Handheld and Mobile devices
Peripheral Interconnects • peripheral interconnects involve connecting other devices together as shown Programming Handheld and Mobile devices
Personal Area Networking (PAN), focuses on the ad-hoc formation and breakdown of personal networks. Imagine meeting someone in an airport and quickly and securely exchanging documents by establishing a private piconet. Personal Area Networking Programming Handheld and Mobile devices
javax.bluetooth Interfaces DiscoveryListener L2CAPConnectionL2CAPConnectionNotifierServiceRecord Classes DataElement DeviceClass DiscoveryAgent LocalDevice RemoteDevice UUID Exceptions BluetoothConnectionException BluetoothStateException ServiceRegistrationException javax.obex Interfaces AuthenticatorClientSessionHeaderSetOperationSessionNotifier Classes PasswordAuthentication ResponseCodes ServerRequestHandler Bluetooth on MIDlets Programming Handheld and Mobile devices
The DiscoveryListener interface allows an application to receive device discovery and service discovery events. This interface provides four methods, two for discovering devices and two for discovering services. void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) Called when a device is found during an inquiry. void inquiryCompleted(int discType) Called when an inquiry is completed. void servicesDiscovered(int transID, ServiceRecord[] servRecord) Called when service(s) are found during a service search. void serviceSearchCompleted(int transID, int respCode) Called when a service search is completed or was terminated because of an error. DiscoveryListener Programming Handheld and Mobile devices
Field Summary • static int INQUIRY_COMPLETED Indicates the normal completion of device discovery. • static int INQUIRY_ERROR Indicates that the inquiry request failed to complete normally, but was not cancelled. • static int INQUIRY_TERMINATED Indicates device discovery has been canceled by the application and did not complete. • static int SERVICE_SEARCH_COMPLETED Indicates the normal completion of service discovery. • static int SERVICE_SEARCH_DEVICE_NOT_REACHABLE Indicates the service search could not be completed because the remote device provided to DiscoveryAgent.searchServices() could not be reached. • static int SERVICE_SEARCH_ERROR Indicates the service search terminated with an error. • static int SERVICE_SEARCH_NO_RECORDS Indicates the service search has completed with no service records found on the device. • static int SERVICE_SEARCH_TERMINATED Indicates the service search has been canceled by the application and did not complete. Programming Handheld and Mobile devices
class DiscoveryAgent • The DiscoveryAgent class provides methods to perform device and service discovery. • A local device must have only one DiscoveryAgent object. • This object must be retrieved by a call to getDiscoveryAgent() on the LocalDevice object. Programming Handheld and Mobile devices
Device Discovery • There are two ways to discover devices. • First, an application may use startInquiry() to start an inquiry to find devices in proximity to the local device. • Discovered devices are returned via the deviceDiscovered() method of the interface DiscoveryListener. • The second way is via the retrieveDevices() method. • This method will return devices that have been discovered via a previous inquiry or devices that are classified as pre-known. • (Pre-known devices are those devices that are defined in the Bluetooth Control Center as devices this device frequently contacts.) • The retrieveDevices() method does not perform an inquiry, but provides a quick way to get a list of devices that may be in the area. Programming Handheld and Mobile devices
Service Discovery • The DiscoveryAgent class also encapsulates the functionality provided by the service discovery application profile. • The class provides an interface for an application to search and retrieve attributes for a particular service. • There are two ways to search for services. • To search for a service on a single device, the searchServices() method should be used. • If you don't care which device a service is on, the selectService() method does a service search on a set of remote devices. Programming Handheld and Mobile devices
General structureSee: http://wireless.klings.org/main.php/Bluetooth/ import javax.bluetooth.DiscoveryListener; import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener; import javax.microedition.lcdui.Displayable; import javax.microedition.midlet.MIDlet; public class yourMidlet extends MIDlet implements CommandListener, DiscoveryListener { public void startApp() { } public void pauseApp() { } public void destroyApp() { } public void commandAction(Command c, Displayable d) { } public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass deviceClass) { } public void inquiryCompleted(int param) { } public void serviceSearchCompleted(int param, int param1) { } public void servicesDiscovered(int param, ServiceRecord[] serviceRecord) { } } Programming Handheld and Mobile devices
Device Discovery • To use any Bluetooth related methods you need to obtain a reference to the LocalDevice object. • This is done with a call to LocalDevice.getLocalDevice(). LocalDevice gives you access to Bluetooth properties for the device, such as Bluetooth address, friendly name and discovery mode. • We will use LocalDevice to obtain a DiscoveryAgent. • The DiscoveryAgent object gives you access to device discovery and service search Programming Handheld and Mobile devices
import javax.bluetooth.BluetoothStateException; import javax.bluetooth.DeviceClass; import javax.bluetooth.DiscoveryAgent; import javax.bluetooth.DiscoveryListener; import javax.bluetooth.LocalDevice; import javax.bluetooth.RemoteDevice; import javax.bluetooth.ServiceRecord; import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener; import javax.microedition.lcdui.Displayable; import javax.microedition.midlet.MIDlet; public class yourMIDlet extends MIDlet implements CommandListener, DiscoveryListener { private LocalDevice local = null; private DiscoveryAgent agent = null; private Vector devicesFound = null; public void startApp() { /* Add your MIDlet specific code here. * You probably want to show the user * a welcome screen. * The call to doDeviceDiscovery() is * here for the example's sake. You * should call doDeviceDiscovery() when * the user actively asks for it. */ doDeviceDiscovery(); } private void doDeviceDiscovery() { try { local = LocalDevice.getLocalDevice(); } catch (BluetoothStateException bse) { // Error handling code here } agent = local.getDiscoveryAgent(); devicesFound = new Vector(); try { if(!agent.startInquiry(DiscoveryAgent.GIAC,this)) { //Inquiry not started, error handling code here } } catch(BluetoothStateException bse) { //Error handling code here } } } Programming Handheld and Mobile devices
What happens • Device discovery is started using the LocalDevice and DiscoveryAgent objects. Searching with the General Inquiry Access Code (GIAC) parameter will find devices which are general discoverable. The DiscoveryListener parameter is this, meaning our MIDlet. When devices are discovered or the search is complete, events will be delivered to our MIDlet. • Then the deviceDiscovered() and inquiryCompleted() methods come into play. When a device is discovered the deviceDiscovered() method of the object this will be called. The parameter remoteDevice will be the discovered device, it is up to us to decide what to do with it. We do not know how many devices will be discovered. A Vector will therefore be an appropriate data structure to save discovered devices. • The inquiryCompleted() method is called when the inquiry ends. You should check the status code supplied in the parameter param. Programming Handheld and Mobile devices
public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass deviceClass) { devicesFound.addElement(remoteDevice); } public void inquiryCompleted(int param) { /* We should give the user an alert based on the inquiry status code */ switch (param) { case DiscoveryListener.INQUIRY_COMPLETED: // Inquiry completed normally, add appropriate code here. break; case DiscoveryListener.INQUIRY_ERROR: // Error during inquiry, add appropriate code here. break; case DiscoveryListener.INQUIRY_TERMINATED: /*Inquiry terminated, caused by agent.cancelInquiry() * Add appropriate code here. */ break; } } Programming Handheld and Mobile devices
And so… • We now keep discovered devices in the foundDevices Vector by adding them as they are discovered. • When our search ends, we check if everything went as expected and can alert the user by adding appropriate code in our switch-statement. Programming Handheld and Mobile devices
Service Search • When device discovery is completed it is time to find out which services are offered by the devices. This is accomplished by a service search on the device of interest.The servicesDiscovered() and serviceSearchCompleted() methods must be implemented. • They will handle the events occuring when services are found or the service search completes. • In addition, code has been added to the doServiceSearch() method. This method will start a service search on the RemoteDevice supplied as parameter. Programming Handheld and Mobile devices
public void serviceSearchCompleted(int transID, int respCode) { switch(respCode) { case DiscoveryListener.SERVICE_SEARCH_COMPLETED: /* * Service search completed successfully * Add appropriate code here */ break; case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE: // device not reachable, add appropriate code here break; case DiscoveryListener.SERVICE_SEARCH_ERROR: // Error during service search, add appropriate code here break; case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS: // No records found, add appropriate code here break; case DiscoveryListener.SERVICE_SEARCH_TERMINATED: /* * Search terminated, caused by agent.cancelServiceSearch(..) * Add appropriate code here */ break; } } Programming Handheld and Mobile devices
public void servicesDiscovered(int transID, ServiceRecord[] serviceRecord) { //Services discovered, keep a reference // to the ServiceRecord array servicesFound = serviceRecord; } Programming Handheld and Mobile devices
private void doServiceSearch(RemoteDevice device) { /* * Service search will always give the default attributes: ServiceRecordHandle (0x0000), ServiceClassIDList (0x0001), ServiceRecordState (0x0002), ServiceID (0x0003) and * ProtocolDescriptorList (0x004). * * We want additional attributes, ServiceName (0x100), * ServiceDescription (0x101) and ProviderName (0x102). * * These hex-values must be supplied through an int array */ int[] attributes = {0x100,0x101,0x102}; /* * Supplying UUIDs in an UUID array enables searching for specific * services. PublicBrowseRoot (0x1002) is used in this example. This will return any services that are public browsable. When searching * for a specific service, the service's UUID should be supplied here. */ UUID[] uuids = new UUID[1]; uuids[0] = new UUID(0x1002); try { agent.searchServices(attributes,u uids,device,this); } catch (BluetoothStateException e) { // Error handling code here } } } Programming Handheld and Mobile devices