Package zephyropen.port.bluetooth

Source Code of zephyropen.port.bluetooth.Discovery$SearchThread

package zephyropen.port.bluetooth;

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

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DataElement;
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;

import zephyropen.api.ZephyrOpen;
import zephyropen.command.Command;

/**
* <p> Wrapper for the BT discovery process
*
* @author <a href="mailto:brad.zdanivsky@gmail.com">Brad Zdanivsky</a>
*/
public class Discovery implements DiscoveryListener {

  /** framework configuration, used fir logging only in this example */
  private static ZephyrOpen constants = ZephyrOpen.getReference();

  /** lock the search flags */
  private boolean deviceSearch = true;
  private boolean serviceSearch = true;

  /** local blue tooth device */
  private DiscoveryAgent agent = null;
  private LocalDevice local = null;

  /** list of devices found, and the service search requests */
  private Vector<RemoteDevice> devices;
 
  /** list of devices found, and the service search requests */
  private Vector<RemoteDevice> spp;

  /** needed to match request id's with remote devices */
  private Hashtable<Integer, RemoteDevice> requests = new Hashtable<Integer, RemoteDevice>();

  /** Constructor takes no arguments */
  public Discovery() {

    /** radio is on? */
    if (!LocalDevice.isPowerOn()) {
      constants.error("Blue Tooth Radio is powered down", this);
      return;
    }

    /** access our radio and agent */
    try {

      local = LocalDevice.getLocalDevice();
      agent = local.getDiscoveryAgent();

    } catch (BluetoothStateException b) {
      constants.error(b.getMessage(), this);
    }
  }

  /** */
  public String getLocalName() {
    return local.getFriendlyName();
  }

  /** */
  public String getLocalAddress() {
    return local.getBluetoothAddress();
  }

  /** Start looking for ALL Devices */
  private void startSearch() {

    try {

      /** get rid of past searches if any */
      agent.cancelInquiry(this);

      /** try to start new search */
      if (!agent.startInquiry(DiscoveryAgent.GIAC, this)) {
        constants.error("couldn't start search", this);
        constants.shutdown();
      }
    } catch (Exception e) {
      constants.shutdown(e);
    }
  }

  /** Look for a SPP on all known devices */
  private void startServiceService(RemoteDevice target) {

    /** Serial Port Profile UUID */
    int[] attributes = { 0x100 };
   
    UUID[] uuids = { com.intel.bluetooth.BluetoothConsts.RFCOMM_PROTOCOL_UUID };
    // UUID[] uuids = { new UUID("0000000300001000800000805F9B34FB", false)};

    /** start a requests for each device found */
    int serviceSearchID = 0;
    try {

      /** look for serial port service, get a request id */
      serviceSearchID = local.getDiscoveryAgent().searchServices(attributes, uuids, target, this);

      /** track this request via the ID */
      requests.put(new Integer(serviceSearchID), target);

    } catch (Exception e) {
      constants.error("startServiceService() : " + e.getMessage(), this);
    }
    constants.info("request started " + requests.toString(), this);
  }

  /** Called by the blue tooth control as devices are found */
  public void deviceDiscovered(RemoteDevice device, DeviceClass deviceClass) {
    // passkey(device);
    devices.add(device);
  }

  /**
  public void passkey(RemoteDevice device) {

    try {

      String name = device.getFriendlyName(false);
      constants.info(device + " address : " + device, this);

      if (device.isAuthenticated()) {

        constants.info(name + " is isAuthenticated ", this);

      } else {

        constants.info(name + " is NOT isAuthenticated ", this);

        // try to log in
        if (RemoteDeviceHelper.authenticate(device, "1234"))
          constants.info(name
              + "is now isAuthenticated with default passkey ",
              this);
        else
          constants.info(name + "default passkey rejected", this);

      }
    } catch (IOException e) {
      constants.info(e.getMessage(), this);
    }
  }*/

  /** This is called by the blue tooth control when the inquiry has completed */
  public void inquiryCompleted(int respCode) {

    switch (respCode) {
    case DiscoveryListener.INQUIRY_COMPLETED:
      constants.info("inquiryCompleted(): INQUIRY_COMPLETED", this);
      break;

    case DiscoveryListener.INQUIRY_TERMINATED:
      constants.info("inquiryCompleted(): INQUIRY_TERMINATED", this);
      break;

    case DiscoveryListener.INQUIRY_ERROR:
      constants.info("inquiryCompleted(): INQUIRY_ERROR", this);
      break;

    default:
      constants.info("inquiryCompleted(): Unknown Response Code", this);
      break;
    }

    deviceSearch = false;
  }

  /**
   * This method is called by the blue tooth control when service search has
   * completed
   */
  public void serviceSearchCompleted(int transID, int arg1) {

    /** done, so remove your request id */
    synchronized(requests){
     
      requests.remove(new Integer(transID));
   
      if( requests.isEmpty() ) {
     
        serviceSearch = false;
        constants.info( "no more requests", this);
     
      } else {
        constants.info( "requests now = " + requests, this);
      }
    }  
  }

  /** This method is called by the blue tooth control when search has completed */
  public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {

    RemoteDevice rd = null;
    String serviceName = "no service";

    try {

      /** look up this request id and get a remote device */
      rd = requests.get(new Integer(transID));
      if (rd == null) return;

      for (int i = 0; i < servRecord.length; i++) {
       
         DataElement nameElement = (DataElement)servRecord[i].getAttributeValue(0x100);
         if ((nameElement != null) && (nameElement.getDataType() == DataElement.STRING)) {

                    /** retrieve the name of the service */
                  serviceName = (String)nameElement.getValue();
                 
                  constants.info(rd + " service name was = " + serviceName, this)
                 
                  /** add serial devices if found */
                  if (serviceName.equals("Bluetooth Serial Port"))
                    spp.add(rd);
        
      }
    } catch (Exception e) {
      constants.error("servicesDiscovered(): " + e.getMessage(), this);
    }
  }

  /** not used */
  public void servicesDiscovered() {}

  /** get results */
  public Vector<RemoteDevice> getDevices() {
   
    /** reset flag and clear the list */
    deviceSearch = true;
    devices = new Vector<RemoteDevice>();
   
    /** new search thread */
    Thread runner = new Thread() {
      public void run() {   
        startSearch()
      }
    };
    runner.start();
   
    /** blocking on search results */
    try {
     
      while(deviceSearch)
        runner.join();
     
    } catch (InterruptedException e) {
      constants.error( "getDevices() :" + e.getMessage(), this);
    }
   
    /** send back results */
    return devices;
  }

  /** get results */
  public Vector<RemoteDevice> getSPPDevices() {
   
    /** blocking call */
    final Vector<RemoteDevice> discovered = getDevices();
    spp = new Vector<RemoteDevice>();
   
    /** sanity test, don't bother starting threads */
    if( discovered.isEmpty()) return spp;
   
    /** new search thread, see if these are SPP devices*/
    serviceSearch = true;
    for(int i = 0 ; i < discovered.size() ; i++ )
      new SearchThread(discovered.get(i));
     
    /** blocking on search results */   
    while(serviceSearch){
      try {
        Thread.sleep(1000);
      } catch (InterruptedException e) {
        constants.error( "getDevices() :" + e.getMessage(), this);
      }
    }

    /** send back the results */
    return spp;
  }
 
  /** inner class for threaded search */
  public class SearchThread implements Runnable {
    private Thread runner = new Thread(this);
    private RemoteDevice device = null;
   
    SearchThread(RemoteDevice dev){
      device = dev;
      runner.setDaemon(true);
      runner.start()
    }
   
    public void run() {
      startServiceService( device );
    }
  }

  /** print results */
  public static void printResults(Vector<RemoteDevice> results) {

    if (results.isEmpty()) {
      System.out.println("no devices found");
      return;
    }

    RemoteDevice target = null;
    Enumeration<RemoteDevice> list = results.elements();
    while (list.hasMoreElements()) {

      target = list.nextElement();
      try {

        System.out.println(target.getBluetoothAddress() + " : "
            + target.getFriendlyName(false));

      } catch (Exception e) {
        constants.error(e.getMessage());
        e.printStackTrace();
      }
    }
  }
 
  /** print results */
  public void sendXML() {

    Vector<RemoteDevice> results = getDevices();
    if (results.isEmpty()) {
      constants.info("no devices found");
      return;
    }

    Command devs = new Command(ZephyrOpen.discovery);
    devs.add(ZephyrOpen.address, local.getBluetoothAddress());
    devs.add(ZephyrOpen.deviceName, local.getFriendlyName());
   
    RemoteDevice target = null;
    Enumeration<RemoteDevice> list = results.elements();
    while (list.hasMoreElements()) {

      target = list.nextElement();
      try {

        devs.add(target.getFriendlyName(false), target.getBluetoothAddress());

      } catch (Exception e) {
        constants.error(e.getMessage());
      }
    }
   
    // share to group
    devs.send();
    constants.info( devs.toXML(), this);
  }
 
  /*
  public static void sendStatus(String string) {
    Command status = new Command();
    status.add(ZephyrOpen.status, string);
    status.add(ZephyrOpen.action, ZephyrOpen.status);
    status.send();
  }  **/
 
  /** test for this class -- no args needed
  public static void main(String[] args) {
   
    constants.init();
     
    Discovery discovery = new Discovery();
    for( int i = 1 ;; i++ ){
   
      constants.info(" +++ " + discovery.getLocalName() + " is searching for devices.. ");
      sendStatus(discovery.getLocalName() + " is searching for devices.. ");
      Long start = System.currentTimeMillis();
     
      discovery.sendXML();
     
      constants.info(" --- search took " + (System.currentTimeMillis() - start)/1000 + " seconds");
      constants.info( "sleeping " + i);
     
      sendStatus("search took " + (System.currentTimeMillis() - start)/1000 + " seconds");
      Utils.delay(ZephyrOpen.ONE_MINUTE);
     
    }
  }*/
}
TOP

Related Classes of zephyropen.port.bluetooth.Discovery$SearchThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.