/** * BlueCove - Java library for Bluetooth * Copyright (C) 2006-2009 Vlad Skarzhevskyy * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * * @author vlads * @version $Id$ */ package net.sf.bluecove.obex; import java.io.IOException; import java.util.Vector; 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.bluetooth.UUID; /** * */ public class BluetoothInquirer implements DiscoveryListener { public static final int MAJOR_COMPUTER = 0x0100; public static final int MAJOR_PHONE = 0x0200; public final UUID L2CAP = new UUID(0x0100); public final UUID RFCOMM = new UUID(0x0003); public final UUID OBEX = new UUID(0x0008); public final UUID OBEX_OBJECT_PUSH = new UUID(0x1105); public final UUID OBEX_FILE_TRANSFER = new UUID(0x1106); private Main mainInstance; boolean inquiring; int servicesSearchTransID = 0; Vector devices; String serviceURL; String serviceSearchOn; BluetoothInquirer(Main main) { mainInstance = main; devices = new Vector(); } public boolean startInquiry() { devices.removeAllElements(); inquiring = false; try { inquiring = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, this); } catch (Throwable e) { Logger.error(e); mainInstance.setStatus("Cannot start inquiry " + e.getMessage()); return false; } if (!inquiring) { mainInstance.setStatus("Cannot start inquiry"); } return inquiring; } public boolean startServiceSearch(RemoteDevice device, UUID obexUUID) { serviceURL = null; try { UUID[] searchUuidSet = new UUID[] { /* L2CAP, RFCOMM, */obexUUID }; int[] attrIDs = new int[] { 0x0100 // Service name }; serviceSearchOn = getFriendlyName(device); servicesSearchTransID = LocalDevice.getLocalDevice().getDiscoveryAgent().searchServices(attrIDs, searchUuidSet, device, this); } catch (Throwable e) { Logger.error(e); mainInstance.setStatus("Cannot start inquiry " + e.getMessage()); return false; } return servicesSearchTransID != 0; } static String getFriendlyName(RemoteDevice device) { try { String name = device.getFriendlyName(false); if ((name == null) || (name.length() == 0)) { return device.getBluetoothAddress(); } else { return name; } } catch (IOException e) { return device.getBluetoothAddress(); } } public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) { if ((cod.getMajorDeviceClass() != MAJOR_COMPUTER) && (cod.getMajorDeviceClass() != MAJOR_PHONE)) { return; } devices.add(btDevice); try { String name = btDevice.getFriendlyName(false); mainInstance.setStatus("Found " + name + " " + btDevice.getBluetoothAddress()); } catch (IOException ioe) { mainInstance.setStatus("Found " + btDevice.getBluetoothAddress()); } } public void inquiryCompleted(int discType) { inquiring = false; } public void servicesDiscovered(int transID, ServiceRecord[] servRecord) { for (int i = 0; i < servRecord.length; i++) { String url = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); if (url == null) { continue; } serviceURL = url; mainInstance.setStatus("found service on " + serviceSearchOn); } } public void serviceSearchCompleted(int transID, int respCode) { switch (respCode) { case SERVICE_SEARCH_ERROR: // log.info(" -> Error occurred while processing the service // search"); mainInstance.setStatus("Error on " + serviceSearchOn); break; case SERVICE_SEARCH_TERMINATED: break; case SERVICE_SEARCH_DEVICE_NOT_REACHABLE: // log.info(" -> Device not reachable"); mainInstance.setStatus(serviceSearchOn + " not reachable"); break; default: if (serviceURL == null) { // log.info(" -> OBEX Object Push service not found"); mainInstance.setStatus(serviceSearchOn + " no services"); } } servicesSearchTransID = 0; } public boolean searching() { return servicesSearchTransID != 0; } public String findOBEX(String btAddress) { RemoteDevice device = new RemoteDeviceExt(btAddress); this.serviceURL = null; if (!startServiceSearch(device, OBEX_OBJECT_PUSH)) { mainInstance.setStatus("Cannot start inquiry"); } else { while (searching()) { try { Thread.sleep(1000); } catch (Exception e) { } } } if (this.serviceURL == null) { if (!startServiceSearch(device, OBEX_FILE_TRANSFER)) { mainInstance.setStatus("Cannot start inquiry"); } else { while (searching()) { try { Thread.sleep(1000); } catch (Exception e) { } } } } return this.serviceURL; } /** * */ public void shutdown() { try { if (inquiring) { LocalDevice.getLocalDevice().getDiscoveryAgent().cancelInquiry(this); } } catch (BluetoothStateException ignore) { } } }