/*
*
*
* Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
package com.sun.kvem.jsr082.bluetooth;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import java.util.Hashtable;
import java.util.Vector;
/**
* This class represents the module which is used by
* DiscoveryAgent#selectService method implementation.
*
*/
final class SelectServiceHandler implements DiscoveryListener {
/** Set to false in RR version - then the javac skip the code. */
private static final boolean DEBUG = false;
private Vector btDevs;
private Hashtable btDevsHash;
private Object btDevsLock = new Object();
private boolean selectDevDisStarted;
private boolean selectDevDisStopped;
private DiscoveryAgentImpl agent;
/**
* Constructs <code>SelectServiceHandler</code> for
* <code>DiscoveryAgentImpl</code> given.
*
* @param agent the discovery agent to create instance for.
*/
SelectServiceHandler(DiscoveryAgentImpl agent) {
this.agent = agent;
}
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
// if this bloototh device was found in preknown or
// cached devices skips it now.
if (btDevsHash.put(btDevice, btDevice) == null) {
btDevs.addElement(btDevice);
}
}
public void inquiryCompleted(int discType) {
synchronized (btDevsLock) {
selectDevDisStopped = true;
btDevsLock.notify();
}
}
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
throw new RuntimeException("unexpected call");
}
public void serviceSearchCompleted(int transID, int respCode) {
throw new RuntimeException("unexpected call");
}
String selectService(UUID uuid, int security, boolean master)
throws BluetoothStateException {
if (DEBUG) {
System.out.println("selectService:");
System.out.println("\tuuid=" + uuid);
}
Vector disDevsVector = null;
Hashtable disDevsHash = new Hashtable();
if (uuid == null) {
throw new NullPointerException("uuid is null");
}
// check in CACHED and PREKNOWN devices
String url = selectFromDevicesList(agent.retrieveDevices(
DiscoveryAgent.PREKNOWN), uuid, security, master, disDevsHash);
if (url != null) {
return url;
}
url = selectFromDevicesList(agent.retrieveDevices(
DiscoveryAgent.CACHED), uuid, security, master, disDevsHash);
if (url != null) {
return url;
}
// start own device discovery now
synchronized (btDevsLock) {
if (selectDevDisStarted) {
throw new BluetoothStateException(
"The previous device discovery is running...");
}
selectDevDisStarted = true;
btDevs = new Vector();
btDevsHash = disDevsHash;
}
try {
agent.startInquiry(DiscoveryAgent.GIAC, this);
} catch (BluetoothStateException btse) {
synchronized (btDevsLock) {
selectDevDisStarted = false;
btDevs = null;
btDevsHash = null;
}
throw btse;
}
synchronized (btDevsLock) {
if (!selectDevDisStopped) {
try {
btDevsLock.wait();
} catch (InterruptedException ie) {
// ignore (breake waiting)
}
disDevsVector = btDevs;
btDevs = null;
btDevsHash = null;
selectDevDisStarted = false;
selectDevDisStopped = false;
}
}
for (int i = 0; i < disDevsVector.size(); i++) {
RemoteDevice btDev = (RemoteDevice) disDevsVector.elementAt(i);
url = selectService(btDev, uuid, security, master);
if (url != null) {
if (DEBUG) {
System.out.println("\turl=" + url);
}
return url;
}
}
if (DEBUG) {
System.out.println("\turl=null");
}
return null;
}
private String selectFromDevicesList(RemoteDevice[] devs, UUID uuid,
int security, boolean master, Hashtable disDevsHash) {
if (devs == null) {
return null;
}
for (int i = 0; i < devs.length; i++) {
if (disDevsHash.put(devs[i], devs[i]) != null) {
continue;
}
String url = selectService(devs[i], uuid, security, master);
if (url != null) {
if (DEBUG) {
System.out.println("\turl=" + url);
}
return url;
}
}
return null;
}
private String selectService(RemoteDevice btDev, UUID uuid, int security,
boolean master) {
UUID[] uuidSet = new UUID[] {uuid};
ServiceSelector selector = new ServiceSelector(null, uuidSet, btDev);
ServiceRecord serRec = selector.getServiceRecord();
if (serRec == null) {
return null;
} else {
return serRec.getConnectionURL(security, master);
}
}
} // end of class 'SelectServiceHandler' definition
|