/* * XCTrack - XContest Live Tracking client for J2ME devices * Copyright (C) 2009 Petr Chromec <petr@xcontest.org> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package org.xcontest.xctrack.gps; 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 org.xcontest.xctrack.util.Log; class Scanner implements DiscoveryListener { private GpsDriver _driver; private Vector _addresses; private Vector _devices; private boolean _scanning; public Scanner(GpsDriver driver) { _driver = driver; _addresses = new Vector(); _devices = new Vector(); } public GpsDeviceInfo[] getAllDevices() { GpsDeviceInfo[] arr = new GpsDeviceInfo[_devices.size()]; for (int i = 0; i < _devices.size(); i ++) arr[i] = (GpsDeviceInfo)_devices.elementAt(i); return arr; } public synchronized void scan() throws InterruptedException,BluetoothStateException { LocalDevice dev = LocalDevice.getLocalDevice(); DiscoveryAgent agent = dev.getDiscoveryAgent(); /* // append cached&preknown devices RemoteDevice[] devs; devs = agent.retrieveDevices(DiscoveryAgent.CACHED); if (devs != null) for (int i = 0; i < devs.length; i ++) addDevice(devs[i]); devs = agent.retrieveDevices(DiscoveryAgent.PREKNOWN); if (devs != null) for (int i = 0; i < devs.length; i ++) addDevice(devs[i]); */ Log.debug("BluetoothGps: scanning..."); _scanning = true; agent.startInquiry(DiscoveryAgent.GIAC, this); while (_scanning) { wait(); } Log.debug("BluetoothGps: scan finished: found "+_devices.size()+" devices"); } public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass deviceClass) { Log.debug("BluetoothGps::deviceDiscovered()"); addDevice(remoteDevice); } private void addDevice(RemoteDevice remoteDevice) { String address = remoteDevice.getBluetoothAddress(); // same device may be found several times during single search if (_addresses.indexOf(address) == -1) { String name = null; try { name = remoteDevice.getFriendlyName(false); } catch (IOException e) { name = address; } if (name != null) name = name.trim(); if (name == null || name.length() == 0) name = address; _addresses.addElement(address); _devices.addElement(new GpsDeviceInfo(_driver,name,"btspp://"+address+":1")); } } public void servicesDiscovered(int transID, ServiceRecord[] servRecord) { } public synchronized void serviceSearchCompleted(int transID, int respCode) { } public synchronized void inquiryCompleted(int discType) { /* if (discType == INQUIRY_COMPLETED) { Util.showInfo("Inquiry completed"); } else if (discType == INQUIRY_ERROR) { Util.showInfo("Inquiry error!"); } else if (discType == INQUIRY_TERMINATED) { Util.showInfo("Inquiry terminated"); } else { Util.showInfo("Inquiry completed: "+discType); } */ _scanning = false; notifyAll(); } } public class BluetoothGps extends NMEADriver { public BluetoothGps() { } /* public static boolean x() { return System.getProperty("bluetooth.api.version") != null; } */ public String getDriverId() { return "BLUETOOTH"; } public String getName() { return "Bluetooth GPS"; } public GpsDeviceInfo[] scanDevices() throws InterruptedException { Scanner s = new Scanner(this); try { s.scan(); } catch (BluetoothStateException e) { Log.error("Error searching for Bluetooth devices",e); } return s.getAllDevices(); } public boolean hasFastScan() { return false; } }