To implement the OBEX server connection:
Create the ExchangerCommImpl.java class file.
Import the required classes.
import java.io.IOException; import javax.bluetooth.DiscoveryAgent; import javax.bluetooth.LocalDevice; import javax.microedition.io.Connection; import javax.microedition.io.Connector; import javax.obex.HeaderSet; import javax.obex.Operation; import javax.obex.ServerRequestHandler; import javax.obex.SessionNotifier;
Set ExchangerCommImpl to extend ServerRequestHandler to serve OBEX requests.
public class ExchangerCommImpl extends ServerRequestHandler implements ExchangerStateParent, ExchangerComm, Runnable {
Create the required variables. You must identify the btgoep protocol, the server URL, and the service UUID. They are used when the MIDlet calls the Connector.open method.
// Instance variables final private String uuid = "ed495afe28ed11da94d900e08161165f"; final private String serverURL = "btgoep://localhost:" + uuid; private boolean cancelWaitingInvoked = false; // becomes true if // cancelWaiting() is // called private Thread waitingThread; private ExchangeListener listener; private ExchangerState currentState; private SessionNotifier notifier = null; private Connection con = null;
Create the ExchangerCommImpl class constructor, set a listener for the module event communication, and create methods for handling sending and waiting.
public ExchangerCommImpl(ExchangeListener _listener) { listener = _listener; startWaiting(); setState(new IdleState(this)); } public void setState(ExchangerState state) { currentState = state; } public ExchangeListener getListener() { return listener; } public ExchangerState getState() { return currentState; } public void startSending(int oper) throws Exception { getState().startSending(oper); } public void startSending() throws Exception { getState().startSending(0); } public void cancelSending() { getState().cancelSending(); } public void startWaiting() { cancelWaitingInvoked = false; waitingThread = new Thread(this); waitingThread.start(); } public void cancelWaiting() { cancelWaitingInvoked = true; try { notifier.close(); // indicate to acceptAndOpen that it is // canceled } catch (IOException e) { // Ignore, we're closing anyways } }
Use the run method to initialize the stack.
Make the device discoverable by using the setDiscoverable method of the LocalDevice class. Call the Connector.open method to return a SessionNotifier object. Use the SessionNotifier.acceptAndOpen method to start waiting for incoming transport layer connections. After the transport layer connection is established, call the acceptAndOpen method to return a Connection object, which represents the connection to a single client.
The server communicates with the remote peer by two means: the Connection object and the ServerRequestHandler callback methods that are called on incoming OBEX requests.
public synchronized void run() { // initialize stack and make the device discoverable try { LocalDevice local = LocalDevice.getLocalDevice(); local.setDiscoverable(DiscoveryAgent.GIAC); } catch (Exception e) { // catching notifier exception listener.onServerError(); return; } try { notifier = (SessionNotifier) Connector.open(serverURL); } catch (IOException e) { } // the cycle stops only if cancelWaiting() was called while (!cancelWaitingInvoked) { try { con = notifier.acceptAndOpen(this); wait(); // wait until the remote peer disconnects try { con.close(); } catch (IOException e) { } } catch (Exception e) { listener.onServerError(); return; } } }
The ServerRequestHandler.onGet and ServerRequestHandler.onPut methods are called when a GET or PUT method is received. These methods receive an Operation object as a parameter. The MIDlet uses the Operation object to read and write data. After the request is handled, the method must return a response code (defined in the ResponseCodes class).
/* * This method is related to OBEX server functionality. This method * is delegating this execution to the current state * * @see javax.obex.ServerRequestHandler#onGet() */ public int onGet(Operation op) { return getState().onGet(op); } /* * This method is related to OBEX server functionality. This method * is delegating this execution to the current state * * @see javax.obex.ServerRequestHandler#onPut() */ public int onPut(Operation op) { return getState().onPut(op); } /* * This method is related to OBEX server functionality. This method * handles OBEX DISCONNECT command from the remote device. * * @see javax.obex.ServerRequestHandler#onDisconnect() */ public synchronized void onDisconnect(HeaderSet request, HeaderSet reply) { super.onDisconnect(request, reply); notify();// stops waiting in run() } public String getUUID() { return uuid; } }
Now that you have implemented the OBEX server connection, implement the idle state.