BluetoothSerialServer.java :  » Plugin » microlog4eclipse » pl » polidea » lab » microlog4e » btserver » Android Open Source

Android Open Source » Plugin » microlog4eclipse 
microlog4eclipse » pl » polidea » lab » microlog4e » btserver » BluetoothSerialServer.java
/*
 * Copyright 2008 The Microlog project @sourceforge.net
 * Licensed 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.
 */

package pl.polidea.lab.microlog4e.btserver;

import java.io.IOException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;


/**
 * The <code>BluetoothSerialServerThread</code> is used for receiving data from
 * a <code>BluetoothSerialAppender</code>. It is intended to be used for servers
 * implemented both in Java & in Java ME (CLDC). When a client connects it will
 * create a new <code>BluetoothStreamReaderThreadImpl</code> object, so each
 * client has its own thread.
 * 
 * @author Johan Karlsson (johan.karlsson@jayway.se)
 * @author Jarle Hansen (hansjar@gmail.com)
 * @since 0.9
 */
public class BluetoothSerialServer implements Runnable {

  private static final String DEFAULT_BT_UUID_STRING = "80d41dda939840c41b605d69043dab6";
  
  private final Executor executor = Executors.newCachedThreadPool();
  
  private Thread serverThread = null;
  private boolean mRun = false;
  
  private final LocalDevice local;
  private BluetoothServerListener serverListener = new DefaultServerListener();

  /**
   * Create a <code>BluetoothSerialServerThread</code> object.
   */
  public BluetoothSerialServer() {
    local = getDiscoverableLocalDevice();
  }
  
  public String getLocalBtAddress() {
    return local.getBluetoothAddress();
  }

  /**
   * Try to make the device discoverable. If not the clients can still connect
   * using the service search method.
   * 
   * @return the Bluetooth local device.
   * @throws BluetoothStateException
   */
  private LocalDevice getDiscoverableLocalDevice() {
    LocalDevice local;

    try {
      local = LocalDevice.getLocalDevice();
      if (!local.setDiscoverable(DiscoveryAgent.GIAC)) {
        System.out.println("Failed to change to the " + "discoverable mode");
      }
    } 
    catch (BluetoothStateException bse) {
      throw new IllegalStateException("Failed to init the Bluetooth connection. " + bse);
    }

    return local;
  }

  /**
   * Set the <code>BluetoothMessageReceiver</code> that is notified every time
   * a message is received from the client.
   * 
   * @param serverListener
   *            the serverListner to be notified.
   */
  public void setServerListener(BluetoothServerListener serverListener) {
    if (serverListener != null) {
      this.serverListener = serverListener;
    }
  }

  public void start() {
    mRun = true;
    
    serverThread = new Thread(this);
    
    serverThread.start();
  }
  
  public void stop() {
    mRun = false;
    
    try {
      serverThread.join();
    } 
    catch (InterruptedException e) {}
  }
  
  
  
  
  /**
   * Implementation of the <code>Runnable</code> interface. The acceptAndOpen
   * will block until a new client is connected. Each new connection will
   * start a new thread.
   */
  public void run() {
    
    while (mRun) {
      StreamConnectionNotifier notifier = null;
      StreamConnection connection = null;
      
      try {
        notifier = createNotifier();
        notifyListenerServerStarted(notifier);

        // Blocking call
        connection = notifier.acceptAndOpen();
        final RemoteDevice remoteDevice = RemoteDevice.getRemoteDevice(connection);
        BluetoothStreamReaderThread bluetoothConnection = new BluetoothStreamReaderThread(serverListener, connection.openDataInputStream(),remoteDevice);
        BluetoothConnectionHandler.instance().addConnection(bluetoothConnection);

        executor.execute(bluetoothConnection);
      } 
      catch (IOException io) {
        System.err.println("Unable to start service: " + io);
      } 
      finally {
        try {
          if (notifier != null) {
            notifier.close();
          }
          if (connection != null) {
            connection.close();
          }
        } 
        catch (IOException io) {
          System.err.println("Failed to close: " + io);
        }
      }
    }
  }

  /**
   * Opens the StreamConnectionNotifier.
   * 
   * @return Server connection opened for clients.
   * @throws IOException
   */
  private StreamConnectionNotifier createNotifier() throws IOException {
    return (StreamConnectionNotifier) Connector.open("btspp://localhost:" + DEFAULT_BT_UUID_STRING);
  }

  /**
   * Notifies the BluetoothServerListener that the server has started with the
   * connection url that the clients can connect to.
   * 
   * @param notifier
   */
  private void notifyListenerServerStarted(
      final StreamConnectionNotifier notifier) {
    final ServiceRecord serviceRecord = local.getRecord(notifier);

    serverListener.serverStarted(serviceRecord.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false));
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.