www.pudn.com > Bluegammon蓝牙的应用编程.rar > BluetoothFacade.java
// Copyright (c) 2005 Sony Ericsson Mobile Communications AB // // This software is provided "AS IS," without a warranty of any kind. // ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, // INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A // PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. // // THIS SOFTWARE IS COMPLEMENTARY OF JAYWAY AB (www.jayway.se) package bluegammon.io; import java.io.IOException; import java.util.Hashtable; import java.util.Vector; 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.bluetooth.UUID; import javax.microedition.io.Connector; import javax.microedition.io.StreamConnection; import javax.microedition.io.StreamConnectionNotifier; /** * Facade for JSR82, connecting via thebtsppprotocol. * @author Peter Andersson */ public class BluetoothFacade implements DiscoveryListener { /** Protocol */ public static final String BT_PROTOCOL = "btspp"; /** service id / server instance map */ protected Hashtable m_servers = new Hashtable(); /** Device Discovery lock */ protected final Object DEVICE_LOCK = new Object(); /** Service Discovery lock */ protected final Object SERVICE_LOCK = new Object(); /** Device lookup result */ protected Vector m_devices = new Vector(); /** Service lookup result */ protected ServiceRecord m_record = null; /** * Returns all devices nearby. This method * blocks until discovery is finished. * @return a Vector ofRemoteDevices. */ public Vector findDevices() throws IOException { synchronized(DEVICE_LOCK) { m_devices.removeAllElements(); DiscoveryAgent discoveryAgent = LocalDevice.getLocalDevice().getDiscoveryAgent(); discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this); try { DEVICE_LOCK.wait(); } catch (InterruptedException e) {} return m_devices; } } /** * Returns a client StreamConnection for specified * device and service number. This method searches for bluetooth * services on specified device. If no service with specified service number * is found, null is returned. * * @param serviceNumber The ID for the provided service * @param device The device to connect to * @return A streamconnection or null if service not provided by device * @throws IOException */ public StreamConnection connect(String serviceNumber, RemoteDevice device) throws IOException { ServiceRecord record = null; synchronized(SERVICE_LOCK) { m_record = null; UUID[] filter = { new UUID(serviceNumber, false) }; DiscoveryAgent discoveryAgent = LocalDevice.getLocalDevice().getDiscoveryAgent(); int trans = discoveryAgent.searchServices(null, filter, device, this); try { SERVICE_LOCK.wait(); } catch (InterruptedException e) {} record = m_record; m_record = null; } if (record != null) { return connect(record); } else { return null; } } /** * Returns a client StreamConnection for specified * service record. * * @param record The service record * @return A streamconnection * @throws IOException */ public StreamConnection connect(ServiceRecord record) throws IOException { int security = ServiceRecord.NOAUTHENTICATE_NOENCRYPT; String conURL = record.getConnectionURL(security, false); if (!conURL.startsWith(BT_PROTOCOL)) { throw new IOException("Protocol mismatch, expected " + BT_PROTOCOL); } StreamConnection conn = (StreamConnection)Connector.open(conURL); return conn; } /** * Setups a server if needed and returns a client. This method blocks until a * client is connected. If multiple clients are allowed to be connected, * simply call this method multiple times. * * @param serviceNumber The ID for the provided service * @return A streamconnection * @throws IOException */ public StreamConnection waitForClient(String serviceNumber) throws IOException { // Set BT device to general discoverable mode LocalDevice.getLocalDevice().setDiscoverable(DiscoveryAgent.GIAC); // Accept a client StreamConnectionNotifier server = (StreamConnectionNotifier) m_servers.get(serviceNumber); if (server == null) { server = (StreamConnectionNotifier)Connector.open( BT_PROTOCOL + "://localhost:" + serviceNumber); m_servers.put(serviceNumber, server); } StreamConnection clientConnection = server.acceptAndOpen(); return clientConnection; } /** * Closes the server setup for specified service ID. * * @param serviceNumber The ID for the provided service * @throws IOException */ public void closeServer(String serviceNumber) throws IOException { StreamConnectionNotifier server = (StreamConnectionNotifier) m_servers.get(serviceNumber); if (server != null) { server.close(); m_servers.remove(serviceNumber); server = null; } } // DiscoveryListener implementation // See interface javadoc public void servicesDiscovered(int transID, ServiceRecord[] records) { for (int i = 0; i < records.length; i++) { String conURL = records[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); if (conURL.startsWith(BT_PROTOCOL)) { synchronized (SERVICE_LOCK) { m_record = records[i]; SERVICE_LOCK.notifyAll(); } break; } } } // See interface javadoc public void serviceSearchCompleted(int transID, int respCode) { synchronized (SERVICE_LOCK) { SERVICE_LOCK.notifyAll(); } } // See interface javadoc public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) { synchronized(DEVICE_LOCK) { m_devices.addElement(btDevice); } } // See interface javadoc public void inquiryCompleted(int discType) { synchronized(DEVICE_LOCK) { DEVICE_LOCK.notifyAll(); } } }