All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intel.bluetooth.SelectServiceHandler Maven / Gradle / Ivy

/**
 *  BlueCove - Java library for Bluetooth
 *  Copyright (C) 2006-2008 Vlad Skarzhevskyy
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  @version $Id: SelectServiceHandler.java 1972 2008-04-05 19:08:04Z skarzhevskyy $
 */
package com.intel.bluetooth;

import java.util.Hashtable;
import java.util.Vector;

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;

/**
 * Implementation of DiscoveryAgent.selectService().
 * 
 * 

* Your application should not use this class directly. * * @author vlads * */ public class SelectServiceHandler implements DiscoveryListener { private DiscoveryAgent agent; private Object inquiryCompletedEvent = new Object(); private boolean inquiryCompleted; private Object serviceSearchCompletedEvent = new Object(); private boolean serviceSearchCompleted; private Hashtable devicesProcessed = new Hashtable(); private Vector serviceSearchDeviceQueue = new Vector(); private ServiceRecord servRecordDiscovered; private static int threadNumber; private static synchronized int nextThreadNum() { return threadNumber++; } public SelectServiceHandler(DiscoveryAgent agent) { this.agent = agent; } /** * Attempts to locate a service that contains uuid in the * ServiceClassIDList of its service record. This method will return a * string that may be used in Connector.open() to establish a * connection to the service. How the service is selected if there are * multiple services with uuid and which devices to search is * implementation dependent. * * @see ServiceRecord#NOAUTHENTICATE_NOENCRYPT * @see ServiceRecord#AUTHENTICATE_NOENCRYPT * @see ServiceRecord#AUTHENTICATE_ENCRYPT * * @param uuid * the UUID to search for in the ServiceClassIDList * * @param security * specifies the security requirements for a connection to this * service; must be one of * ServiceRecord.NOAUTHENTICATE_NOENCRYPT, * ServiceRecord.AUTHENTICATE_NOENCRYPT, or * ServiceRecord.AUTHENTICATE_ENCRYPT * * @param master * determines if this client must be the master of the * connection; true if the client must be the * master; false if the client can be the master * or the slave * * @return the connection string used to connect to the service with a UUID * of uuid; or null if no service * could be found with a UUID of uuid in the * ServiceClassIDList * * @exception BluetoothStateException * if the Bluetooth system cannot start the request due to * the current state of the Bluetooth system * * @exception NullPointerException * if uuid is null * * @exception IllegalArgumentException * if security is not * ServiceRecord.NOAUTHENTICATE_NOENCRYPT, * ServiceRecord.AUTHENTICATE_NOENCRYPT, or * ServiceRecord.AUTHENTICATE_ENCRYPT */ public String selectService(UUID uuid, int security, boolean master) throws BluetoothStateException { if (uuid == null) { throw new NullPointerException("uuid is null"); } switch (security) { case ServiceRecord.NOAUTHENTICATE_NOENCRYPT: case ServiceRecord.AUTHENTICATE_NOENCRYPT: case ServiceRecord.AUTHENTICATE_ENCRYPT: break; default: throw new IllegalArgumentException(); } RemoteDevice[] devs = agent.retrieveDevices(DiscoveryAgent.PREKNOWN); for (int i = 0; (devs != null) && (i < devs.length); i++) { ServiceRecord sr = findServiceOnDevice(uuid, devs[i]); if (sr != null) { return sr.getConnectionURL(security, master); } } devs = agent.retrieveDevices(DiscoveryAgent.CACHED); for (int i = 0; (devs != null) && (i < devs.length); i++) { ServiceRecord sr = findServiceOnDevice(uuid, devs[i]); if (sr != null) { return sr.getConnectionURL(security, master); } } ParallelSearchServicesThread t = new ParallelSearchServicesThread(uuid); t.start(); synchronized (inquiryCompletedEvent) { if (!agent.startInquiry(DiscoveryAgent.GIAC, this)) { return null; } while (!inquiryCompleted) { try { inquiryCompletedEvent.wait(); } catch (InterruptedException e) { return null; } } agent.cancelInquiry(this); } if ((servRecordDiscovered == null) && (!t.processedAll())) { synchronized (serviceSearchDeviceQueue) { serviceSearchDeviceQueue.notifyAll(); } try { t.join(); } catch (InterruptedException e) { return null; } } t.interrupt(); if (servRecordDiscovered != null) { return servRecordDiscovered.getConnectionURL(security, master); } return null; } private class ParallelSearchServicesThread extends Thread { private boolean stoped = false; private int processedNext = 0; private int processedSize = 0; private UUID uuid; ParallelSearchServicesThread(UUID uuid) { super("SelectServiceThread-" + nextThreadNum()); this.uuid = uuid; } boolean processedAll() { return (processedNext == serviceSearchDeviceQueue.size()); } public void interrupt() { stoped = true; synchronized (serviceSearchDeviceQueue) { serviceSearchDeviceQueue.notifyAll(); } super.interrupt(); } public void run() { mainLoop: while ((!stoped) && (servRecordDiscovered == null)) { synchronized (serviceSearchDeviceQueue) { if ((inquiryCompleted) && (processedSize == serviceSearchDeviceQueue.size())) { return; } if (processedSize == serviceSearchDeviceQueue.size()) { try { serviceSearchDeviceQueue.wait(); } catch (InterruptedException e) { return; } } processedSize = serviceSearchDeviceQueue.size(); } for (int i = processedNext; i < processedSize; i++) { RemoteDevice btDevice = (RemoteDevice) serviceSearchDeviceQueue.elementAt(i); if (findServiceOnDevice(uuid, btDevice) != null) { break mainLoop; } } processedNext = processedSize + 1; } } } private ServiceRecord findServiceOnDevice(UUID uuid, RemoteDevice device) { if (devicesProcessed.containsKey(device)) { return null; } devicesProcessed.put(device, device); DebugLog.debug("searchServices on ", device); synchronized (serviceSearchCompletedEvent) { try { serviceSearchCompleted = false; agent.searchServices(null, new UUID[] { uuid }, device, this); } catch (BluetoothStateException e) { DebugLog.error("searchServices", e); return null; } while (!serviceSearchCompleted) { try { serviceSearchCompletedEvent.wait(); } catch (InterruptedException e) { return null; } } } return servRecordDiscovered; } public void deviceDiscovered(final RemoteDevice btDevice, DeviceClass cod) { if (devicesProcessed.containsKey(btDevice)) { return; } synchronized (serviceSearchDeviceQueue) { serviceSearchDeviceQueue.addElement(btDevice); serviceSearchDeviceQueue.notifyAll(); } } public void inquiryCompleted(int discType) { synchronized (inquiryCompletedEvent) { inquiryCompleted = true; inquiryCompletedEvent.notifyAll(); } } public void serviceSearchCompleted(int transID, int respCode) { synchronized (serviceSearchCompletedEvent) { serviceSearchCompleted = true; serviceSearchCompletedEvent.notifyAll(); } } public void servicesDiscovered(int transID, ServiceRecord[] servRecord) { if ((servRecord.length > 0) && (servRecordDiscovered == null)) { servRecordDiscovered = servRecord[0]; synchronized (serviceSearchCompletedEvent) { serviceSearchCompleted = true; serviceSearchCompletedEvent.notifyAll(); } synchronized (inquiryCompletedEvent) { inquiryCompleted = true; inquiryCompletedEvent.notifyAll(); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy