001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026: package com.sun.kvem.jsr082.bluetooth;
027:
028: import javax.bluetooth.BluetoothStateException;
029: import javax.bluetooth.DeviceClass;
030: import javax.bluetooth.DiscoveryAgent;
031: import javax.bluetooth.DiscoveryListener;
032: import javax.bluetooth.RemoteDevice;
033: import javax.bluetooth.ServiceRecord;
034: import javax.bluetooth.UUID;
035: import java.util.Hashtable;
036: import java.util.Vector;
037:
038: /**
039: * This class represents the module which is used by
040: * DiscoveryAgent#selectService method implementation.
041: *
042: */
043: final class SelectServiceHandler implements DiscoveryListener {
044:
045: /** Set to false in RR version - then the javac skip the code. */
046: private static final boolean DEBUG = false;
047:
048: private Vector btDevs;
049: private Hashtable btDevsHash;
050: private Object btDevsLock = new Object();
051: private boolean selectDevDisStarted;
052: private boolean selectDevDisStopped;
053: private DiscoveryAgentImpl agent;
054:
055: /**
056: * Constructs <code>SelectServiceHandler</code> for
057: * <code>DiscoveryAgentImpl</code> given.
058: *
059: * @param agent the discovery agent to create instance for.
060: */
061: SelectServiceHandler(DiscoveryAgentImpl agent) {
062: this .agent = agent;
063: }
064:
065: public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
066:
067: // if this bloototh device was found in preknown or
068: // cached devices skips it now.
069: if (btDevsHash.put(btDevice, btDevice) == null) {
070: btDevs.addElement(btDevice);
071: }
072: }
073:
074: public void inquiryCompleted(int discType) {
075: synchronized (btDevsLock) {
076: selectDevDisStopped = true;
077: btDevsLock.notify();
078: }
079: }
080:
081: public void servicesDiscovered(int transID,
082: ServiceRecord[] servRecord) {
083: throw new RuntimeException("unexpected call");
084: }
085:
086: public void serviceSearchCompleted(int transID, int respCode) {
087: throw new RuntimeException("unexpected call");
088: }
089:
090: String selectService(UUID uuid, int security, boolean master)
091: throws BluetoothStateException {
092: if (DEBUG) {
093: System.out.println("selectService:");
094: System.out.println("\tuuid=" + uuid);
095: }
096: Vector disDevsVector = null;
097: Hashtable disDevsHash = new Hashtable();
098:
099: if (uuid == null) {
100: throw new NullPointerException("uuid is null");
101: }
102:
103: // check in CACHED and PREKNOWN devices
104: String url = selectFromDevicesList(agent
105: .retrieveDevices(DiscoveryAgent.PREKNOWN), uuid,
106: security, master, disDevsHash);
107:
108: if (url != null) {
109: return url;
110: }
111: url = selectFromDevicesList(agent
112: .retrieveDevices(DiscoveryAgent.CACHED), uuid,
113: security, master, disDevsHash);
114:
115: if (url != null) {
116: return url;
117: }
118:
119: // start own device discovery now
120: synchronized (btDevsLock) {
121: if (selectDevDisStarted) {
122: throw new BluetoothStateException(
123: "The previous device discovery is running...");
124: }
125: selectDevDisStarted = true;
126: btDevs = new Vector();
127: btDevsHash = disDevsHash;
128: }
129:
130: try {
131: agent.startInquiry(DiscoveryAgent.GIAC, this );
132: } catch (BluetoothStateException btse) {
133: synchronized (btDevsLock) {
134: selectDevDisStarted = false;
135: btDevs = null;
136: btDevsHash = null;
137: }
138: throw btse;
139: }
140:
141: synchronized (btDevsLock) {
142: if (!selectDevDisStopped) {
143: try {
144: btDevsLock.wait();
145: } catch (InterruptedException ie) {
146: // ignore (breake waiting)
147: }
148: disDevsVector = btDevs;
149: btDevs = null;
150: btDevsHash = null;
151: selectDevDisStarted = false;
152: selectDevDisStopped = false;
153: }
154: }
155:
156: for (int i = 0; i < disDevsVector.size(); i++) {
157: RemoteDevice btDev = (RemoteDevice) disDevsVector
158: .elementAt(i);
159: url = selectService(btDev, uuid, security, master);
160:
161: if (url != null) {
162: if (DEBUG) {
163: System.out.println("\turl=" + url);
164: }
165: return url;
166: }
167: }
168: if (DEBUG) {
169: System.out.println("\turl=null");
170: }
171: return null;
172: }
173:
174: private String selectFromDevicesList(RemoteDevice[] devs,
175: UUID uuid, int security, boolean master,
176: Hashtable disDevsHash) {
177: if (devs == null) {
178: return null;
179: }
180:
181: for (int i = 0; i < devs.length; i++) {
182: if (disDevsHash.put(devs[i], devs[i]) != null) {
183: continue;
184: }
185: String url = selectService(devs[i], uuid, security, master);
186:
187: if (url != null) {
188: if (DEBUG) {
189: System.out.println("\turl=" + url);
190: }
191: return url;
192: }
193: }
194: return null;
195: }
196:
197: private String selectService(RemoteDevice btDev, UUID uuid,
198: int security, boolean master) {
199: UUID[] uuidSet = new UUID[] { uuid };
200: ServiceSelector selector = new ServiceSelector(null, uuidSet,
201: btDev);
202: ServiceRecord serRec = selector.getServiceRecord();
203:
204: if (serRec == null) {
205: return null;
206: } else {
207: return serRec.getConnectionURL(security, master);
208: }
209: }
210: } // end of class 'SelectServiceHandler' definition
|