Implementing the OBEX server connection

To implement the OBEX server connection:

  1. Create the ExchangerCommImpl.java class file.

  2. 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;
  3. Set ExchangerCommImpl to extend ServerRequestHandler to serve OBEX requests.

    public class ExchangerCommImpl extends ServerRequestHandler
            implements ExchangerStateParent, ExchangerComm, Runnable {
  4. 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;
    
  5. 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
            }
        }
  6. 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;
                }
            }
        }
  7. 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.