diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..d0e5041
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,41 @@
+// OBEX library
+package {
+  default_applicable_licenses: ["obex_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+  name: "obex_license",
+  visibility: [":__subpackages__"],
+  license_kinds: [
+    "SPDX-license-identifier-Apache-2.0",
+    "SPDX-license-identifier-BSD",
+  ],
+  license_text: [
+    "LICENSE",
+  ],
+}
+
+java_library {
+  name: "obex",
+
+  srcs: ["**/*.java"],
+  apex_available: [
+        "com.android.bluetooth",
+  ],
+  sdk_version: "module_current",
+  min_sdk_version: "Tiramisu",
+}
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..9c00551
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,6 @@
+# Owners for OBEX library
+
+rahulsabnis@google.com
+sattiraju@google.com
+siyuanh@google.com
+zachoverflow@google.com
diff --git a/javax/obex/ApplicationParameter.java b/javax/obex/ApplicationParameter.java
new file mode 100644
index 0000000..c2f14c6
--- /dev/null
+++ b/javax/obex/ApplicationParameter.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+/**
+ * Represents an Application Parameter header for OBEX as defined by the IrDA specification.
+ */
+public final class ApplicationParameter {
+
+    private byte[] mArray;
+
+    private int mLength;
+
+    private int mMaxLength = 1000;
+
+    /**
+     * Possible values for the tag field in the Application Parameter header.
+     */
+    public static class TRIPLET_TAGID {
+        public static final byte ORDER_TAGID = 0x01;
+
+        public static final byte SEARCH_VALUE_TAGID = 0x02;
+
+        public static final byte SEARCH_ATTRIBUTE_TAGID = 0x03;
+
+        // if equals to "0", PSE only reply number of contacts
+        public static final byte MAXLISTCOUNT_TAGID = 0x04;
+
+        public static final byte LISTSTARTOFFSET_TAGID = 0x05;
+
+        public static final byte PROPERTY_SELECTOR_TAGID = 0x06;
+
+        public static final byte FORMAT_TAGID = 0x07;
+
+        // only used if max list count = 0
+        public static final byte PHONEBOOKSIZE_TAGID = 0x08;
+
+        // only used in "mch" in response
+        public static final byte NEWMISSEDCALLS_TAGID = 0x09;
+
+        public static final byte SUPPORTEDFEATURE_TAGID = 0x10;
+
+        public static final byte PRIMARYVERSIONCOUNTER_TAGID = 0x0A;
+
+        public static final byte SECONDARYVERSIONCOUNTER_TAGID = 0x0B;
+
+        public static final byte VCARDSELECTOR_TAGID = 0x0C;
+
+        public static final byte DATABASEIDENTIFIER_TAGID = 0x0D;
+
+        public static final byte VCARDSELECTOROPERATOR_TAGID = 0x0E;
+
+        public static final byte RESET_NEW_MISSED_CALLS_TAGID = 0x0F;
+    }
+
+    /**
+     * Possible values for the value field in the Application Parameter header.
+     */
+    public static class TRIPLET_VALUE {
+        public static class ORDER {
+            public static final byte ORDER_BY_INDEX = 0x00;
+
+            public static final byte ORDER_BY_ALPHANUMERIC = 0x01;
+
+            public static final byte ORDER_BY_PHONETIC = 0x02;
+        }
+
+        public static class SEARCHATTRIBUTE {
+            public static final byte SEARCH_BY_NAME = 0x00;
+
+            public static final byte SEARCH_BY_NUMBER = 0x01;
+
+            public static final byte SEARCH_BY_SOUND = 0x02;
+        }
+
+        public static class FORMAT {
+            public static final byte VCARD_VERSION_21 = 0x00;
+
+            public static final byte VCARD_VERSION_30 = 0x01;
+        }
+    }
+
+    /**
+     * Possible values for the length field in the Application Parameter header.
+     */
+    public static class TRIPLET_LENGTH {
+        public static final byte ORDER_LENGTH = 1;
+
+        public static final byte SEARCH_ATTRIBUTE_LENGTH = 1;
+
+        public static final byte MAXLISTCOUNT_LENGTH = 2;
+
+        public static final byte LISTSTARTOFFSET_LENGTH = 2;
+
+        public static final byte PROPERTY_SELECTOR_LENGTH = 8;
+
+        public static final byte FORMAT_LENGTH = 1;
+
+        public static final byte PHONEBOOKSIZE_LENGTH = 2;
+
+        public static final byte NEWMISSEDCALLS_LENGTH = 1;
+
+        public static final byte SUPPORTEDFEATURE_LENGTH = 4;
+
+        public static final byte PRIMARYVERSIONCOUNTER_LENGTH = 16;
+
+        public static final byte SECONDARYVERSIONCOUNTER_LENGTH = 16;
+
+        public static final byte VCARDSELECTOR_LENGTH = 8;
+
+        public static final byte DATABASEIDENTIFIER_LENGTH = 16;
+
+        public static final byte VCARDSELECTOROPERATOR_LENGTH = 1;
+
+        public static final byte RESETNEWMISSEDCALLS_LENGTH = 1;
+    }
+
+    /**
+     * Constructs an ApplicationParameter header
+     */
+    public ApplicationParameter() {
+        mArray = new byte[mMaxLength];
+        mLength = 0;
+    }
+
+    /**
+     * Adds a triplet of tag, length, and value to this application parameter header as per the
+     * IrDA specifications.
+     *
+     * @param tag one of {@link TRIPLET_TAGID}
+     * @param len one of {@link TRIPLET_LENGTH}
+     * @param value is the value required for the supplied tag
+     */
+    public void addTriplet(byte tag, byte len, byte[] value) {
+        if ((mLength + len + 2) > mMaxLength) {
+            byte[] array_tmp = new byte[mLength + 4 * len];
+            System.arraycopy(mArray, 0, array_tmp, 0, mLength);
+            mArray = array_tmp;
+            mMaxLength = mLength + 4 * len;
+        }
+        mArray[mLength++] = tag;
+        mArray[mLength++] = len;
+        System.arraycopy(value, 0, mArray, mLength, len);
+        mLength += len;
+    }
+
+    /**
+     * Gets the application parameter header as a byte array.
+     *
+     * @return a byte array representing the application parameter header
+     */
+    public byte[] getHeader() {
+        byte[] para = new byte[mLength];
+        System.arraycopy(mArray, 0, para, 0, mLength);
+        return para;
+    }
+}
diff --git a/javax/obex/Authenticator.java b/javax/obex/Authenticator.java
new file mode 100644
index 0000000..12ef47f
--- /dev/null
+++ b/javax/obex/Authenticator.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+/**
+ * This interface provides a way to respond to authentication challenge and
+ * authentication response headers. When a client or server receives an
+ * authentication challenge or authentication response header, the
+ * <code>onAuthenticationChallenge()</code> or
+ * <code>onAuthenticationResponse()</code> will be called, respectively, by the
+ * implementation.
+ * <P>
+ * For more information on how the authentication procedure works in OBEX,
+ * please review the IrOBEX specification at <A
+ * HREF="http://www.irda.org">http://www.irda.org</A>.
+ * <P>
+ * <STRONG>Authentication Challenges</STRONG>
+ * <P>
+ * When a client or server receives an authentication challenge header, the
+ * <code>onAuthenticationChallenge()</code> method will be invoked by the OBEX
+ * API implementation. The application will then return the user name (if
+ * needed) and password via a <code>PasswordAuthentication</code> object. The
+ * password in this object is not sent in the authentication response. Instead,
+ * the 16-byte challenge received in the authentication challenge is combined
+ * with the password returned from the <code>onAuthenticationChallenge()</code>
+ * method and passed through the MD5 hash algorithm. The resulting value is sent
+ * in the authentication response along with the user name if it was provided.
+ * <P>
+ * <STRONG>Authentication Responses</STRONG>
+ * <P>
+ * When a client or server receives an authentication response header, the
+ * <code>onAuthenticationResponse()</code> method is invoked by the API
+ * implementation with the user name received in the authentication response
+ * header. (The user name will be <code>null</code> if no user name was provided
+ * in the authentication response header.) The application must determine the
+ * correct password. This value should be returned from the
+ * <code>onAuthenticationResponse()</code> method. If the authentication request
+ * should fail without the implementation checking the password,
+ * <code>null</code> should be returned by the application. (This is needed for
+ * reasons like not recognizing the user name, etc.) If the returned value is
+ * not <code>null</code>, the OBEX API implementation will combine the password
+ * returned from the <code>onAuthenticationResponse()</code> method and
+ * challenge sent via the authentication challenge, apply the MD5 hash
+ * algorithm, and compare the result to the response hash received in the
+ * authentication response header. If the values are not equal, an
+ * <code>IOException</code> will be thrown if the client requested
+ * authentication. If the server requested authentication, the
+ * <code>onAuthenticationFailure()</code> method will be called on the
+ * <code>ServerRequestHandler</code> that failed authentication. The connection
+ * is <B>not</B> closed if authentication failed.
+ */
+public interface Authenticator {
+
+    /**
+     * Called when a client or a server receives an authentication challenge
+     * header. It should respond to the challenge with a
+     * <code>PasswordAuthentication</code> that contains the correct user name
+     * and password for the challenge.
+     * @param description the description of which user name and password should
+     *        be used; if no description is provided in the authentication
+     *        challenge or the description is encoded in an encoding scheme that
+     *        is not supported, an empty string will be provided
+     * @param isUserIdRequired <code>true</code> if the user ID is required;
+     *        <code>false</code> if the user ID is not required
+     * @param isFullAccess <code>true</code> if full access to the server will
+     *        be granted; <code>false</code> if read only access will be granted
+     * @return a <code>PasswordAuthentication</code> object containing the user
+     *         name and password used for authentication
+     */
+    PasswordAuthentication onAuthenticationChallenge(String description, boolean isUserIdRequired,
+            boolean isFullAccess);
+
+    /**
+     * Called when a client or server receives an authentication response
+     * header. This method will provide the user name and expect the correct
+     * password to be returned.
+     * @param userName the user name provided in the authentication response; may
+     *        be <code>null</code>
+     * @return the correct password for the user name provided; if
+     *         <code>null</code> is returned then the authentication request
+     *         failed
+     */
+    byte[] onAuthenticationResponse(byte[] userName);
+}
diff --git a/javax/obex/BaseStream.java b/javax/obex/BaseStream.java
new file mode 100644
index 0000000..440e060
--- /dev/null
+++ b/javax/obex/BaseStream.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import java.io.IOException;
+
+/**
+ * This interface defines the methods needed by a parent that uses the
+ * PrivateInputStream and PrivateOutputStream objects defined in this package.
+ */
+public interface BaseStream {
+
+    /**
+     * Verifies that this object is still open.
+     * @throws IOException if the object is closed
+     */
+    void ensureOpen() throws IOException;
+
+    /**
+     * Verifies that additional information may be sent. In other words, the
+     * operation is not done.
+     * @throws IOException if the operation is completed
+     */
+    void ensureNotDone() throws IOException;
+
+    /**
+     * Continues the operation since there is no data to read.
+     * @param sendEmpty <code>true</code> if the operation should send an empty
+     *        packet or not send anything if there is no data to send
+     * @param inStream <code>true</code> if the stream is input stream or is
+     *        output stream
+     * @return <code>true</code> if the operation was completed;
+     *         <code>false</code> if no operation took place
+     * @throws IOException if an IO error occurs
+     */
+    boolean continueOperation(boolean sendEmpty, boolean inStream) throws IOException;
+
+    /**
+     * Called when the output or input stream is closed.
+     * @param inStream <code>true</code> if the input stream is closed;
+     *        <code>false</code> if the output stream is closed
+     * @throws IOException if an IO error occurs
+     */
+    void streamClosed(boolean inStream) throws IOException;
+}
diff --git a/javax/obex/ClientOperation.java b/javax/obex/ClientOperation.java
new file mode 100644
index 0000000..d5387d1
--- /dev/null
+++ b/javax/obex/ClientOperation.java
@@ -0,0 +1,819 @@
+/*
+ * Copyright (c) 2015 The Android Open Source Project
+ * Copyright (C) 2015 Samsung LSI
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * This class implements the {@link Operation} interface. It will read and write data via puts and
+ * gets.
+ */
+public final class ClientOperation implements Operation, BaseStream {
+
+    private static final String TAG = "ClientOperation";
+
+    private static final boolean V = ObexHelper.VDBG;
+
+    private ClientSession mParent;
+
+    private boolean mInputOpen;
+
+    private PrivateInputStream mPrivateInput;
+
+    private boolean mPrivateInputOpen;
+
+    private PrivateOutputStream mPrivateOutput;
+
+    private boolean mPrivateOutputOpen;
+
+    private String mExceptionMessage;
+
+    private int mMaxPacketSize;
+
+    private boolean mOperationDone;
+
+    private boolean mGetOperation;
+
+    private boolean mGetFinalFlag;
+
+    private HeaderSet mRequestHeader;
+
+    private HeaderSet mReplyHeader;
+
+    private boolean mEndOfBodySent;
+
+    private boolean mSendBodyHeader = true;
+    // A latch - when triggered, there is not way back ;-)
+    private boolean mSrmActive = false;
+
+    // Assume SRM disabled - until support is confirmed
+    // by the server
+    private boolean mSrmEnabled = false;
+    // keep waiting until final-bit is received in request
+    // to handle the case where the SRM enable header is in
+    // a different OBEX packet than the SRMP header.
+    private boolean mSrmWaitingForRemote = true;
+
+
+    /**
+     * Creates new OperationImpl to read and write data to a server.
+     *
+     * @param maxSize the maximum packet size
+     * @param p the parent to this object
+     * @param type <code>true</code> if this is a get request;
+     *        <code>false</code>. if this is a put request
+     * @param header the header to set in the initial request
+     * @throws IOException if an IO error occurred
+     */
+    ClientOperation(int maxSize, ClientSession p, HeaderSet header, boolean type)
+            throws IOException {
+
+        mParent = p;
+        mEndOfBodySent = false;
+        mInputOpen = true;
+        mOperationDone = false;
+        mMaxPacketSize = maxSize;
+        mGetOperation = type;
+        mGetFinalFlag = false;
+
+        mPrivateInputOpen = false;
+        mPrivateOutputOpen = false;
+        mPrivateInput = null;
+        mPrivateOutput = null;
+
+        mReplyHeader = new HeaderSet();
+
+        mRequestHeader = new HeaderSet();
+
+        int[] headerList = header.getHeaderList();
+
+        if (headerList != null) {
+
+            for (int i = 0; i < headerList.length; i++) {
+                mRequestHeader.setHeader(headerList[i], header.getHeader(headerList[i]));
+            }
+        }
+
+        if ((header).mAuthChall != null) {
+            mRequestHeader.mAuthChall = new byte[(header).mAuthChall.length];
+            System.arraycopy((header).mAuthChall, 0, mRequestHeader.mAuthChall, 0,
+                    (header).mAuthChall.length);
+        }
+
+        if ((header).mAuthResp != null) {
+            mRequestHeader.mAuthResp = new byte[(header).mAuthResp.length];
+            System.arraycopy((header).mAuthResp, 0, mRequestHeader.mAuthResp, 0,
+                    (header).mAuthResp.length);
+
+        }
+
+        if ((header).mConnectionID != null) {
+            mRequestHeader.mConnectionID = new byte[4];
+            System.arraycopy((header).mConnectionID, 0, mRequestHeader.mConnectionID, 0,
+                    4);
+
+        }
+    }
+
+    /**
+     * Allows setting the flag which will force GET to always be sent as single packet request with
+     * the final flag set. This is to improve compatibility with some profiles, i.e. PBAP which
+     * require requests to be sent this way.
+     *
+     * @param flag true if the final flag should be set in the packet, false if it should not
+     */
+    public void setGetFinalFlag(boolean flag) {
+        mGetFinalFlag = flag;
+    }
+
+    /**
+     * Sends an ABORT message to the server. By calling this method, the corresponding input and
+     * output streams will be closed along with this object.
+     *
+     * @throws IOException if the transaction has already ended or if an OBEX server called this
+     *                     method
+     */
+    public synchronized void abort() throws IOException {
+        ensureOpen();
+        //no compatible with sun-ri
+        if ((mOperationDone) && (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE)) {
+            throw new IOException("Operation has already ended");
+        }
+
+        mExceptionMessage = "Operation aborted";
+        if ((!mOperationDone) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
+            mOperationDone = true;
+            /*
+             * Since we are not sending any headers or returning any headers then
+             * we just need to write and read the same bytes
+             */
+            mParent.sendRequest(ObexHelper.OBEX_OPCODE_ABORT, null, mReplyHeader, null, false);
+
+            if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_OK) {
+                throw new IOException("Invalid response code from server");
+            }
+
+            mExceptionMessage = null;
+        }
+
+        close();
+    }
+
+    /**
+     * Retrieves the response code retrieved from the server. Response codes are
+     * defined in the <code>ResponseCodes</code> interface.
+     * @return the response code retrieved from the server
+     * @throws IOException if an error occurred in the transport layer during
+     *         the transaction; if this method is called on a
+     *         <code>HeaderSet</code> object created by calling
+     *         <code>createHeaderSet</code> in a <code>ClientSession</code>
+     *         object
+     */
+    public synchronized int getResponseCode() throws IOException {
+        if ((mReplyHeader.responseCode == -1)
+                || (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
+            validateConnection();
+        }
+
+        return mReplyHeader.responseCode;
+    }
+
+    /**
+     * Open and return an input stream for a connection.
+     * @return an input stream
+     * @throws IOException if an I/O error occurs
+     */
+    public InputStream openInputStream() throws IOException {
+
+        ensureOpen();
+
+        if (mPrivateInputOpen)
+            throw new IOException("no more input streams available");
+        if (mGetOperation) {
+            // send the GET request here
+            validateConnection();
+        } else {
+            if (mPrivateInput == null) {
+                mPrivateInput = new PrivateInputStream(this);
+            }
+        }
+
+        mPrivateInputOpen = true;
+
+        return mPrivateInput;
+    }
+
+    /**
+     * Open and return a data input stream for a connection.
+     * @return an input stream
+     * @throws IOException if an I/O error occurs
+     *
+     * @hide
+     */
+    public DataInputStream openDataInputStream() throws IOException {
+        return new DataInputStream(openInputStream());
+    }
+
+    /**
+     * Open and return an output stream for a connection.
+     * @return an output stream
+     * @throws IOException if an I/O error occurs
+     */
+    public OutputStream openOutputStream() throws IOException {
+
+        ensureOpen();
+        ensureNotDone();
+
+        if (mPrivateOutputOpen)
+            throw new IOException("no more output streams available");
+
+        if (mPrivateOutput == null) {
+            // there are 3 bytes operation headers and 3 bytes body headers //
+            mPrivateOutput = new PrivateOutputStream(this, getMaxPacketSize());
+        }
+
+        mPrivateOutputOpen = true;
+
+        return mPrivateOutput;
+    }
+
+    public int getMaxPacketSize() {
+        return mMaxPacketSize - 6 - getHeaderLength();
+    }
+
+    /** @hide */
+    public int getHeaderLength() {
+        // OPP may need it
+        byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false);
+        return headerArray.length;
+    }
+
+    /**
+     * Open and return a data output stream for a connection.
+     * @return an output stream
+     * @throws IOException if an I/O error occurs
+     */
+    public DataOutputStream openDataOutputStream() throws IOException {
+        return new DataOutputStream(openOutputStream());
+    }
+
+    /**
+     * Closes the connection and ends the transaction
+     * @throws IOException if the operation has already ended or is closed
+     */
+    public void close() throws IOException {
+        mInputOpen = false;
+        mPrivateInputOpen = false;
+        mPrivateOutputOpen = false;
+        mParent.setRequestInactive();
+    }
+
+    /**
+     * Returns the headers that have been received during the operation.
+     * Modifying the object returned has no effect on the headers that are sent
+     * or retrieved.
+     * @return the headers received during this <code>Operation</code>
+     * @throws IOException if this <code>Operation</code> has been closed
+     */
+    public HeaderSet getReceivedHeader() throws IOException {
+        ensureOpen();
+
+        return mReplyHeader;
+    }
+
+    /**
+     * Specifies the headers that should be sent in the next OBEX message that
+     * is sent.
+     * @param headers the headers to send in the next message
+     * @throws IOException if this <code>Operation</code> has been closed or the
+     *         transaction has ended and no further messages will be exchanged
+     * @throws IllegalArgumentException if <code>headers</code> was not created
+     *         by a call to <code>ServerRequestHandler.createHeaderSet()</code>
+     * @throws NullPointerException if <code>headers</code> is <code>null</code>
+     *
+     * @hide
+     */
+    public void sendHeaders(HeaderSet headers) throws IOException {
+        ensureOpen();
+        if (mOperationDone) {
+            throw new IOException("Operation has already exchanged all data");
+        }
+
+        if (headers == null) {
+            throw new IOException("Headers may not be null");
+        }
+
+        int[] headerList = headers.getHeaderList();
+        if (headerList != null) {
+            for (int i = 0; i < headerList.length; i++) {
+                mRequestHeader.setHeader(headerList[i], headers.getHeader(headerList[i]));
+            }
+        }
+    }
+
+    /**
+     * Verifies that additional information may be sent. In other words, the
+     * operation is not done.
+     * @throws IOException if the operation is completed
+     *
+     * @hide
+     */
+    public void ensureNotDone() throws IOException {
+        if (mOperationDone) {
+            throw new IOException("Operation has completed");
+        }
+    }
+
+    /**
+     * Verifies that the connection is open and no exceptions should be thrown.
+     * @throws IOException if an exception needs to be thrown
+     *
+     * @hide
+     */
+    public void ensureOpen() throws IOException {
+        mParent.ensureOpen();
+
+        if (mExceptionMessage != null) {
+            throw new IOException(mExceptionMessage);
+        }
+        if (!mInputOpen) {
+            throw new IOException("Operation has already ended");
+        }
+    }
+
+    /**
+     * Verifies that the connection is open and the proper data has been read.
+     * @throws IOException if an IO error occurs
+     */
+    private void validateConnection() throws IOException {
+        ensureOpen();
+
+        // Make sure that a response has been received from remote
+        // before continuing
+        if (mPrivateInput == null || mReplyHeader.responseCode == -1) {
+            startProcessing();
+        }
+    }
+
+    /**
+     * Sends a request to the client of the specified type.
+     * This function will enable SRM and set SRM active if the server
+     * response allows this.
+     * @param opCode the request code to send to the client
+     * @return <code>true</code> if there is more data to send;
+     *         <code>false</code> if there is no more data to send
+     * @throws IOException if an IO error occurs
+     */
+    private boolean sendRequest(int opCode) throws IOException {
+        boolean returnValue = false;
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        int bodyLength = -1;
+        byte[] headerArray = ObexHelper.createHeader(mRequestHeader, true);
+        if (mPrivateOutput != null) {
+            bodyLength = mPrivateOutput.size();
+        }
+
+        /*
+         * Determine if there is space to add a body request.  At present
+         * this method checks to see if there is room for at least a 17
+         * byte body header.  This number needs to be at least 6 so that
+         * there is room for the header ID and length and the reply ID and
+         * length, but it is a waste of resources if we can't send much of
+         * the body.
+         */
+        final int MINIMUM_BODY_LENGTH = 3;
+        if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length + MINIMUM_BODY_LENGTH)
+                > mMaxPacketSize) {
+            int end = 0;
+            int start = 0;
+            // split & send the headerArray in multiple packets.
+
+            while (end != headerArray.length) {
+                //split the headerArray
+
+                end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketSize
+                        - ObexHelper.BASE_PACKET_LENGTH);
+                // can not split
+                if (end == -1) {
+                    mOperationDone = true;
+                    abort();
+                    mExceptionMessage = "Header larger then can be sent in a packet";
+                    mInputOpen = false;
+
+                    if (mPrivateInput != null) {
+                        mPrivateInput.close();
+                    }
+
+                    if (mPrivateOutput != null) {
+                        mPrivateOutput.close();
+                    }
+                    throw new IOException("OBEX Packet exceeds max packet size");
+                }
+
+                byte[] sendHeader = new byte[end - start];
+                System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length);
+                if (!mParent.sendRequest(opCode, sendHeader, mReplyHeader, mPrivateInput, false)) {
+                    return false;
+                }
+
+                if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
+                    return false;
+                }
+
+                start = end;
+            }
+
+            // Enable SRM if it should be enabled
+            checkForSrm();
+
+            if (bodyLength > 0) {
+                return true;
+            } else {
+                return false;
+            }
+        } else {
+            /* All headers will fit into a single package */
+            if(mSendBodyHeader == false) {
+                /* As we are not to send any body data, set the FINAL_BIT */
+                opCode |= ObexHelper.OBEX_OPCODE_FINAL_BIT_MASK;
+            }
+            out.write(headerArray);
+        }
+
+        if (bodyLength > 0) {
+            /*
+             * Determine if we can send the whole body or just part of
+             * the body.  Remember that there is the 3 bytes for the
+             * response message and 3 bytes for the header ID and length
+             */
+            if (bodyLength > (mMaxPacketSize - headerArray.length - 6)) {
+                returnValue = true;
+
+                bodyLength = mMaxPacketSize - headerArray.length - 6;
+            }
+
+            byte[] body = mPrivateOutput.readBytes(bodyLength);
+
+            /*
+             * Since this is a put request if the final bit is set or
+             * the output stream is closed we need to send the 0x49
+             * (End of Body) otherwise, we need to send 0x48 (Body)
+             */
+            if ((mPrivateOutput.isClosed()) && (!returnValue) && (!mEndOfBodySent)
+                    && ((opCode & ObexHelper.OBEX_OPCODE_FINAL_BIT_MASK) != 0)) {
+                out.write(HeaderSet.END_OF_BODY);
+                mEndOfBodySent = true;
+            } else {
+                out.write(HeaderSet.BODY);
+            }
+
+            bodyLength += 3;
+            out.write((byte)(bodyLength >> 8));
+            out.write((byte)bodyLength);
+
+            if (body != null) {
+                out.write(body);
+            }
+        }
+
+        if (mPrivateOutputOpen && bodyLength <= 0 && !mEndOfBodySent) {
+            // only 0x82 or 0x83 can send 0x49
+            if ((opCode & ObexHelper.OBEX_OPCODE_FINAL_BIT_MASK) == 0) {
+                out.write(HeaderSet.BODY);
+            } else {
+                out.write(HeaderSet.END_OF_BODY);
+                mEndOfBodySent = true;
+            }
+
+            bodyLength = 3;
+            out.write((byte)(bodyLength >> 8));
+            out.write((byte)bodyLength);
+        }
+
+        if (out.size() == 0) {
+            if (!mParent.sendRequest(opCode, null, mReplyHeader, mPrivateInput, mSrmActive)) {
+                return false;
+            }
+            // Enable SRM if it should be enabled
+            checkForSrm();
+            return returnValue;
+        }
+        if ((out.size() > 0)
+                && (!mParent.sendRequest(opCode, out.toByteArray(),
+                        mReplyHeader, mPrivateInput, mSrmActive))) {
+            return false;
+        }
+        // Enable SRM if it should be enabled
+        checkForSrm();
+
+        // send all of the output data in 0x48,
+        // send 0x49 with empty body
+        if ((mPrivateOutput != null) && (mPrivateOutput.size() > 0))
+            returnValue = true;
+
+        return returnValue;
+    }
+
+    private void checkForSrm() throws IOException {
+        Byte srmMode = (Byte)mReplyHeader.getHeader(HeaderSet.SINGLE_RESPONSE_MODE);
+        if(mParent.isSrmSupported() == true && srmMode != null
+                && srmMode == ObexHelper.OBEX_SRM_ENABLE) {
+            mSrmEnabled = true;
+        }
+        /**
+         * Call this only when a complete obex packet have been received.
+         * (This is not optimal, but the current design is not really suited to
+         * the way SRM is specified.)
+         * The BT usage of SRM is not really safe - it assumes that the SRMP will fit
+         * into every OBEX packet, hence if another header occupies the entire packet,
+         * the scheme will not work - unlikely though.
+         */
+        if(mSrmEnabled) {
+            mSrmWaitingForRemote = false;
+            Byte srmp = (Byte)mReplyHeader.getHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
+            if(srmp != null && srmp == ObexHelper.OBEX_SRMP_WAIT) {
+                mSrmWaitingForRemote = true;
+                // Clear the wait header, as the absence of the header in the next packet
+                // indicates don't wait anymore.
+                mReplyHeader.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, null);
+            }
+        }
+        if((mSrmWaitingForRemote == false) && (mSrmEnabled == true)) {
+            mSrmActive = true;
+        }
+    }
+
+    /**
+     * This method starts the processing thread results. It will send the
+     * initial request. If the response takes more than one packet, a thread
+     * will be started to handle additional requests
+     * @throws IOException if an IO error occurs
+     */
+    private synchronized void startProcessing() throws IOException {
+
+        if (mPrivateInput == null) {
+            mPrivateInput = new PrivateInputStream(this);
+        }
+        boolean more = true;
+
+        if (mGetOperation) {
+            if (!mOperationDone) {
+                if (!mGetFinalFlag) {
+                    mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
+                    while ((more) && (mReplyHeader.responseCode ==
+                            ResponseCodes.OBEX_HTTP_CONTINUE)) {
+                        more = sendRequest(ObexHelper.OBEX_OPCODE_GET);
+                    }
+                    // For GET we need to loop until all headers have been sent,
+                    // And then we wait for the first continue package with the
+                    // reply.
+                    if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
+                        mParent.sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL,
+                                null, mReplyHeader, mPrivateInput, mSrmActive);
+                    }
+                    if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
+                        mOperationDone = true;
+                    } else {
+                        checkForSrm();
+                    }
+                } else {
+                    more = sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL);
+
+                    if (more) {
+                        throw new IOException("FINAL_GET forced, data didn't fit into one packet");
+                    }
+
+                    mOperationDone = true;
+                }
+            }
+        } else {
+            // PUT operation
+            if (!mOperationDone) {
+                mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
+                while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
+                    more = sendRequest(ObexHelper.OBEX_OPCODE_PUT);
+                }
+            }
+
+            if (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
+                mParent.sendRequest(ObexHelper.OBEX_OPCODE_PUT_FINAL,
+                        null, mReplyHeader, mPrivateInput, mSrmActive);
+            }
+
+            if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
+                mOperationDone = true;
+            }
+        }
+    }
+
+    /**
+     * Continues the operation since there is no data to read.
+     * @param sendEmpty <code>true</code> if the operation should send an empty
+     *        packet or not send anything if there is no data to send
+     * @param inStream <code>true</code> if the stream is input stream or is
+     *        output stream
+     * @throws IOException if an IO error occurs
+     */
+    public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream)
+            throws IOException {
+
+        // One path to the first put operation - the other one does not need to
+        // handle SRM, as all will fit into one packet.
+
+        if (mGetOperation) {
+            if ((inStream) && (!mOperationDone)) {
+                // to deal with inputstream in get operation
+                mParent.sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL,
+                        null, mReplyHeader, mPrivateInput, mSrmActive);
+                /*
+                  * Determine if that was not the last packet in the operation
+                  */
+                if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
+                    mOperationDone = true;
+                } else {
+                    checkForSrm();
+                }
+
+                return true;
+
+            } else if ((!inStream) && (!mOperationDone)) {
+                // to deal with outputstream in get operation
+
+                if (mPrivateInput == null) {
+                    mPrivateInput = new PrivateInputStream(this);
+                }
+
+                if (!mGetFinalFlag) {
+                    sendRequest(ObexHelper.OBEX_OPCODE_GET);
+                } else {
+                    sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL);
+                }
+                if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
+                    mOperationDone = true;
+                }
+                return true;
+
+            } else if (mOperationDone) {
+                return false;
+            }
+
+        } else {
+            // PUT operation
+            if ((!inStream) && (!mOperationDone)) {
+                // to deal with outputstream in put operation
+                if (mReplyHeader.responseCode == -1) {
+                    mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
+                }
+                sendRequest(ObexHelper.OBEX_OPCODE_PUT);
+                return true;
+            } else if ((inStream) && (!mOperationDone)) {
+                // How to deal with inputstream  in put operation ?
+                return false;
+
+            } else if (mOperationDone) {
+                return false;
+            }
+
+        }
+        return false;
+    }
+
+    /**
+     * Called when the output or input stream is closed.
+     * @param inStream <code>true</code> if the input stream is closed;
+     *        <code>false</code> if the output stream is closed
+     * @throws IOException if an IO error occurs
+     *
+     * @hide
+     */
+    public void streamClosed(boolean inStream) throws IOException {
+        if (!mGetOperation) {
+            if ((!inStream) && (!mOperationDone)) {
+                // to deal with outputstream in put operation
+
+                boolean more = true;
+
+                if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0)) {
+                    byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false);
+                    if (headerArray.length <= 0)
+                        more = false;
+                }
+                // If have not sent any data so send  all now
+                if (mReplyHeader.responseCode == -1) {
+                    mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
+                }
+
+                while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
+                    more = sendRequest(ObexHelper.OBEX_OPCODE_PUT);
+                }
+
+                /*
+                 * According to the IrOBEX specification, after the final put, you
+                 * only have a single reply to send.  so we don't need the while
+                 * loop.
+                 */
+                while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE) {
+
+                    sendRequest(ObexHelper.OBEX_OPCODE_PUT_FINAL);
+                }
+                mOperationDone = true;
+            } else if ((inStream) && (mOperationDone)) {
+                // how to deal with input stream in put stream ?
+                mOperationDone = true;
+            }
+        } else {
+            if ((inStream) && (!mOperationDone)) {
+
+                // to deal with inputstream in get operation
+                // Have not sent any data so send it all now
+
+                if (mReplyHeader.responseCode == -1) {
+                    mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
+                }
+
+                while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE
+                        && !mOperationDone) {
+                    if (!sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL)) {
+                        break;
+                    }
+                }
+                while (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE
+                        && !mOperationDone) {
+                    mParent.sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL, null,
+                            mReplyHeader, mPrivateInput, false);
+                    // Regardless of the SRM state, wait for the response.
+                }
+                mOperationDone = true;
+            } else if ((!inStream) && (!mOperationDone)) {
+                // to deal with outputstream in get operation
+                // part of the data may have been sent in continueOperation.
+
+                boolean more = true;
+
+                if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0)) {
+                    byte[] headerArray = ObexHelper.createHeader(mRequestHeader, false);
+                    if (headerArray.length <= 0)
+                        more = false;
+                }
+
+                if (mPrivateInput == null) {
+                    mPrivateInput = new PrivateInputStream(this);
+                }
+                if ((mPrivateOutput != null) && (mPrivateOutput.size() <= 0))
+                    more = false;
+
+                mReplyHeader.responseCode = ResponseCodes.OBEX_HTTP_CONTINUE;
+                while ((more) && (mReplyHeader.responseCode == ResponseCodes.OBEX_HTTP_CONTINUE)) {
+                    more = sendRequest(ObexHelper.OBEX_OPCODE_GET);
+                }
+                sendRequest(ObexHelper.OBEX_OPCODE_GET_FINAL);
+                //                parent.sendRequest(0x83, null, replyHeaders, privateInput);
+                if (mReplyHeader.responseCode != ResponseCodes.OBEX_HTTP_CONTINUE) {
+                    mOperationDone = true;
+                }
+            }
+        }
+    }
+
+    /** @hide */
+    public void noBodyHeader(){
+        mSendBodyHeader = false;
+    }
+}
diff --git a/javax/obex/ClientSession.java b/javax/obex/ClientSession.java
new file mode 100644
index 0000000..fcdc2c7
--- /dev/null
+++ b/javax/obex/ClientSession.java
@@ -0,0 +1,637 @@
+/*
+ * Copyright (c) 2015 The Android Open Source Project
+ * Copyright (C) 2015 Samsung LSI
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * This class in an implementation of the OBEX ClientSession.
+ */
+public final class ClientSession extends ObexSession {
+
+    private static final String TAG = "ClientSession";
+
+    private boolean mOpen;
+
+    // Determines if an OBEX layer connection has been established
+    private boolean mObexConnected;
+
+    private byte[] mConnectionId = null;
+
+    /*
+     * The max Packet size must be at least 255 according to the OBEX
+     * specification.
+     */
+    private int mMaxTxPacketSize = ObexHelper.LOWER_LIMIT_MAX_PACKET_SIZE;
+
+    private boolean mRequestActive;
+
+    private final InputStream mInput;
+
+    private final OutputStream mOutput;
+
+    private final boolean mLocalSrmSupported;
+
+    private final ObexTransport mTransport;
+
+    /**
+     * Creates a ClientSession.
+     *
+     * @param transport the transport to use for OBEX transactions
+     * @throws IOException if it occurs while opening the transport streams
+     */
+    public ClientSession(final ObexTransport transport) throws IOException {
+        mInput = transport.openInputStream();
+        mOutput = transport.openOutputStream();
+        mOpen = true;
+        mRequestActive = false;
+        mLocalSrmSupported = transport.isSrmSupported();
+        mTransport = transport;
+    }
+
+    /**
+     * Create a ClientSession.
+     *
+     * @param transport the transport to use for OBEX transactions
+     * @param supportsSrm true if Single Response Mode should be used e.g. if the
+     *        supplied transport is a TCP or l2cap channel
+     * @throws IOException if it occurs while opening the transport streams
+     *
+     * @hide
+     */
+    public ClientSession(final ObexTransport transport, final boolean supportsSrm)
+            throws IOException {
+        mInput = transport.openInputStream();
+        mOutput = transport.openOutputStream();
+        mOpen = true;
+        mRequestActive = false;
+        mLocalSrmSupported = supportsSrm;
+        mTransport = transport;
+    }
+
+    public HeaderSet connect(final HeaderSet header) throws IOException {
+        ensureOpen();
+        if (mObexConnected) {
+            throw new IOException("Already connected to server");
+        }
+        setRequestActive();
+
+        int totalLength = 4;
+        byte[] head = null;
+
+        // Determine the header byte array
+        if (header != null) {
+            if (header.nonce != null) {
+                mChallengeDigest = new byte[16];
+                System.arraycopy(header.nonce, 0, mChallengeDigest, 0, 16);
+            }
+            head = ObexHelper.createHeader(header, false);
+            totalLength += head.length;
+        }
+        /*
+        * Write the OBEX CONNECT packet to the server.
+        * Byte 0: 0x80
+        * Byte 1&2: Connect Packet Length
+        * Byte 3: OBEX Version Number (Presently, 0x10)
+        * Byte 4: Flags (For TCP 0x00)
+        * Byte 5&6: Max OBEX Packet Length (Defined in MAX_PACKET_SIZE)
+        * Byte 7 to n: headers
+        */
+        byte[] requestPacket = new byte[totalLength];
+        int maxRxPacketSize = ObexHelper.getMaxRxPacketSize(mTransport);
+        // We just need to start at  byte 3 since the sendRequest() method will
+        // handle the length and 0x80.
+        requestPacket[0] = (byte)0x10;
+        requestPacket[1] = (byte)0x00;
+        requestPacket[2] = (byte)(maxRxPacketSize >> 8);
+        requestPacket[3] = (byte)(maxRxPacketSize & 0xFF);
+        if (head != null) {
+            System.arraycopy(head, 0, requestPacket, 4, head.length);
+        }
+
+        // Since we are not yet connected, the peer max packet size is unknown,
+        // hence we are only guaranteed the server will use the first 7 bytes.
+        if ((requestPacket.length + 3) > ObexHelper.MAX_PACKET_SIZE_INT) {
+            throw new IOException("Packet size exceeds max packet size for connect");
+        }
+
+        HeaderSet returnHeaderSet = new HeaderSet();
+        sendRequest(ObexHelper.OBEX_OPCODE_CONNECT, requestPacket, returnHeaderSet, null, false);
+
+        /*
+        * Read the response from the OBEX server.
+        * Byte 0: Response Code (If successful then OBEX_HTTP_OK)
+        * Byte 1&2: Packet Length
+        * Byte 3: OBEX Version Number
+        * Byte 4: Flags3
+        * Byte 5&6: Max OBEX packet Length
+        * Byte 7 to n: Optional HeaderSet
+        */
+        if (returnHeaderSet.responseCode == ResponseCodes.OBEX_HTTP_OK) {
+            mObexConnected = true;
+        }
+        setRequestInactive();
+
+        return returnHeaderSet;
+    }
+
+    public Operation get(HeaderSet header) throws IOException {
+
+        if (!mObexConnected) {
+            throw new IOException("Not connected to the server");
+        }
+        setRequestActive();
+
+        ensureOpen();
+
+        HeaderSet head;
+        if (header == null) {
+            head = new HeaderSet();
+        } else {
+            head = header;
+            if (head.nonce != null) {
+                mChallengeDigest = new byte[16];
+                System.arraycopy(head.nonce, 0, mChallengeDigest, 0, 16);
+            }
+        }
+        // Add the connection ID if one exists
+        if (mConnectionId != null) {
+            head.mConnectionID = new byte[4];
+            System.arraycopy(mConnectionId, 0, head.mConnectionID, 0, 4);
+        }
+
+        if(mLocalSrmSupported) {
+            head.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, ObexHelper.OBEX_SRM_ENABLE);
+            /* TODO: Consider creating an interface to get the wait state.
+             * On an android system, I cannot see when this is to be used.
+             * except perhaps if we are to wait for user accept on a push message.
+            if(getLocalWaitState()) {
+                head.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, ObexHelper.OBEX_SRMP_WAIT);
+            }
+            */
+        }
+
+        return new ClientOperation(mMaxTxPacketSize, this, head, true);
+    }
+
+    /**
+     * 0xCB Connection Id an identifier used for OBEX connection multiplexing
+     *
+     * @hide
+     */
+    public void setConnectionID(long id) {
+        if ((id < 0) || (id > 0xFFFFFFFFL)) {
+            throw new IllegalArgumentException("Connection ID is not in a valid range");
+        }
+        mConnectionId = ObexHelper.convertToByteArray(id);
+    }
+
+    /** @hide */
+    public HeaderSet delete(HeaderSet header) throws IOException {
+
+        Operation op = put(header);
+        op.getResponseCode();
+        HeaderSet returnValue = op.getReceivedHeader();
+        op.close();
+
+        return returnValue;
+    }
+
+    public HeaderSet disconnect(HeaderSet header) throws IOException {
+        if (!mObexConnected) {
+            throw new IOException("Not connected to the server");
+        }
+        setRequestActive();
+
+        ensureOpen();
+        // Determine the header byte array
+        byte[] head = null;
+        if (header != null) {
+            if (header.nonce != null) {
+                mChallengeDigest = new byte[16];
+                System.arraycopy(header.nonce, 0, mChallengeDigest, 0, 16);
+            }
+            // Add the connection ID if one exists
+            if (mConnectionId != null) {
+                header.mConnectionID = new byte[4];
+                System.arraycopy(mConnectionId, 0, header.mConnectionID, 0, 4);
+            }
+            head = ObexHelper.createHeader(header, false);
+
+            if ((head.length + 3) > mMaxTxPacketSize) {
+                throw new IOException("Packet size exceeds max packet size");
+            }
+        } else {
+            // Add the connection ID if one exists
+            if (mConnectionId != null) {
+                head = new byte[5];
+                head[0] = (byte)HeaderSet.CONNECTION_ID;
+                System.arraycopy(mConnectionId, 0, head, 1, 4);
+            }
+        }
+
+        HeaderSet returnHeaderSet = new HeaderSet();
+        sendRequest(ObexHelper.OBEX_OPCODE_DISCONNECT, head, returnHeaderSet, null, false);
+
+        /*
+         * An OBEX DISCONNECT reply from the server:
+         * Byte 1: Response code
+         * Bytes 2 & 3: packet size
+         * Bytes 4 & up: headers
+         */
+
+        /*
+         * response code , and header are ignored
+         */
+
+        synchronized (this) {
+            mObexConnected = false;
+            setRequestInactive();
+        }
+
+        return returnHeaderSet;
+    }
+
+    /** @hide */
+    public long getConnectionID() {
+
+        if (mConnectionId == null) {
+            return -1;
+        }
+        return ObexHelper.convertToLong(mConnectionId);
+    }
+
+    public Operation put(HeaderSet header) throws IOException {
+        if (!mObexConnected) {
+            throw new IOException("Not connected to the server");
+        }
+        setRequestActive();
+
+        ensureOpen();
+        HeaderSet head;
+        if (header == null) {
+            head = new HeaderSet();
+        } else {
+            head = header;
+            // when auth is initiated by client ,save the digest
+            if (head.nonce != null) {
+                mChallengeDigest = new byte[16];
+                System.arraycopy(head.nonce, 0, mChallengeDigest, 0, 16);
+            }
+        }
+
+        // Add the connection ID if one exists
+        if (mConnectionId != null) {
+
+            head.mConnectionID = new byte[4];
+            System.arraycopy(mConnectionId, 0, head.mConnectionID, 0, 4);
+        }
+
+        if(mLocalSrmSupported) {
+            head.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, ObexHelper.OBEX_SRM_ENABLE);
+            /* TODO: Consider creating an interface to get the wait state.
+             * On an android system, I cannot see when this is to be used.
+            if(getLocalWaitState()) {
+                head.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, ObexHelper.OBEX_SRMP_WAIT);
+            }
+             */
+        }
+        return new ClientOperation(mMaxTxPacketSize, this, head, false);
+    }
+
+    /** @hide */
+    public void setAuthenticator(Authenticator auth) throws IOException {
+        if (auth == null) {
+            throw new IOException("Authenticator may not be null");
+        }
+        mAuthenticator = auth;
+    }
+
+    public HeaderSet setPath(HeaderSet header, boolean backup, boolean create) throws IOException {
+        if (!mObexConnected) {
+            throw new IOException("Not connected to the server");
+        }
+        setRequestActive();
+        ensureOpen();
+
+        int totalLength = 2;
+        byte[] head = null;
+        HeaderSet headset;
+        if (header == null) {
+            headset = new HeaderSet();
+        } else {
+            headset = header;
+            if (headset.nonce != null) {
+                mChallengeDigest = new byte[16];
+                System.arraycopy(headset.nonce, 0, mChallengeDigest, 0, 16);
+            }
+        }
+
+        // when auth is initiated by client ,save the digest
+        if (headset.nonce != null) {
+            mChallengeDigest = new byte[16];
+            System.arraycopy(headset.nonce, 0, mChallengeDigest, 0, 16);
+        }
+
+        // Add the connection ID if one exists
+        if (mConnectionId != null) {
+            headset.mConnectionID = new byte[4];
+            System.arraycopy(mConnectionId, 0, headset.mConnectionID, 0, 4);
+        }
+
+        head = ObexHelper.createHeader(headset, false);
+        totalLength += head.length;
+
+        if (totalLength > mMaxTxPacketSize) {
+            throw new IOException("Packet size exceeds max packet size");
+        }
+
+        int flags = 0;
+        /*
+         * The backup flag bit is bit 0 so if we add 1, this will set that bit
+         */
+        if (backup) {
+            flags++;
+        }
+        /*
+         * The create bit is bit 1 so if we or with 2 the bit will be set.
+         */
+        if (!create) {
+            flags |= 2;
+        }
+
+        /*
+         * An OBEX SETPATH packet to the server:
+         * Byte 1: 0x85
+         * Byte 2 & 3: packet size
+         * Byte 4: flags
+         * Byte 5: constants
+         * Byte 6 & up: headers
+         */
+        byte[] packet = new byte[totalLength];
+        packet[0] = (byte)flags;
+        packet[1] = (byte)0x00;
+        if (headset != null) {
+            System.arraycopy(head, 0, packet, 2, head.length);
+        }
+
+        HeaderSet returnHeaderSet = new HeaderSet();
+        sendRequest(ObexHelper.OBEX_OPCODE_SETPATH, packet, returnHeaderSet, null, false);
+
+        /*
+         * An OBEX SETPATH reply from the server:
+         * Byte 1: Response code
+         * Bytes 2 & 3: packet size
+         * Bytes 4 & up: headers
+         */
+
+        setRequestInactive();
+
+        return returnHeaderSet;
+    }
+
+    /**
+     * Verifies that the connection is open.
+     * @throws IOException if the connection is closed
+     *
+     * @hide
+     */
+    public synchronized void ensureOpen() throws IOException {
+        if (!mOpen) {
+            throw new IOException("Connection closed");
+        }
+    }
+
+    /**
+     * Set request inactive. Allows Put and get operation objects to tell this
+     * object when they are done.
+     */
+    /*package*/synchronized void setRequestInactive() {
+        mRequestActive = false;
+    }
+
+    /**
+     * Set request to active.
+     * @throws IOException if already active
+     */
+    private synchronized void setRequestActive() throws IOException {
+        if (mRequestActive) {
+            throw new IOException("OBEX request is already being performed");
+        }
+        mRequestActive = true;
+    }
+
+    /**
+     * Sends a standard request to the client. It will then wait for the reply
+     * and update the header set object provided. If any authentication headers
+     * (i.e. authentication challenge or authentication response) are received,
+     * they will be processed.
+     * @param opCode the type of request to send to the client
+     * @param head the headers to send to the client
+     * @param header the header object to update with the response
+     * @param privateInput the input stream used by the Operation object; null
+     *        if this is called on a CONNECT, SETPATH or DISCONNECT
+     * @return
+     *        <code>true</code> if the operation completed successfully;
+     *        <code>false</code> if an authentication response failed to pass
+     * @throws IOException if an IO error occurs
+     *
+     * @hide
+     */
+    public boolean sendRequest(int opCode, byte[] head, HeaderSet header,
+            PrivateInputStream privateInput, boolean srmActive) throws IOException {
+        //check header length with local max size
+        if (head != null) {
+            if ((head.length + 3) > ObexHelper.MAX_PACKET_SIZE_INT) {
+                // TODO: This is an implementation limit - not a specification requirement.
+                throw new IOException("header too large ");
+            }
+        }
+
+        boolean skipSend = false;
+        boolean skipReceive = false;
+        if (srmActive == true) {
+            if (opCode == ObexHelper.OBEX_OPCODE_PUT) {
+                // we are in the middle of a SRM PUT operation, don't expect a continue.
+                skipReceive = true;
+            } else if (opCode == ObexHelper.OBEX_OPCODE_GET) {
+                // We are still sending the get request, send, but don't expect continue
+                // until the request is transferred (the final bit is set)
+                skipReceive = true;
+            } else if (opCode == ObexHelper.OBEX_OPCODE_GET_FINAL) {
+                // All done sending the request, expect data from the server, without
+                // sending continue.
+                skipSend = true;
+            }
+
+        }
+
+        int bytesReceived;
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        out.write((byte)opCode);
+
+        // Determine if there are any headers to send
+        if (head == null) {
+            out.write(0x00);
+            out.write(0x03);
+        } else {
+            out.write((byte)((head.length + 3) >> 8));
+            out.write((byte)(head.length + 3));
+            out.write(head);
+        }
+
+        if (!skipSend) {
+            // Write the request to the output stream and flush the stream
+            mOutput.write(out.toByteArray());
+            // TODO: is this really needed? if this flush is implemented
+            //       correctly, we will get a gap between each obex packet.
+            //       which is kind of the idea behind SRM to avoid.
+            //  Consider offloading to another thread (async action)
+            mOutput.flush();
+        }
+
+        if (!skipReceive) {
+            header.responseCode = mInput.read();
+
+            int length = ((mInput.read() << 8) | (mInput.read()));
+
+            if (length > ObexHelper.getMaxRxPacketSize(mTransport)) {
+                throw new IOException("Packet received exceeds packet size limit");
+            }
+            if (length > ObexHelper.BASE_PACKET_LENGTH) {
+                byte[] data = null;
+                if (opCode == ObexHelper.OBEX_OPCODE_CONNECT) {
+                    @SuppressWarnings("unused")
+                    int version = mInput.read();
+                    @SuppressWarnings("unused")
+                    int flags = mInput.read();
+                    mMaxTxPacketSize = (mInput.read() << 8) + mInput.read();
+
+                    //check with local max size
+                    if (mMaxTxPacketSize > ObexHelper.MAX_CLIENT_PACKET_SIZE) {
+                        mMaxTxPacketSize = ObexHelper.MAX_CLIENT_PACKET_SIZE;
+                    }
+
+                    // check with transport maximum size
+                    if(mMaxTxPacketSize > ObexHelper.getMaxTxPacketSize(mTransport)) {
+                        // To increase this size, increase the buffer size in L2CAP layer
+                        // in Bluedroid.
+                        Log.w(TAG, "An OBEX packet size of " + mMaxTxPacketSize + "was"
+                                + " requested. Transport only allows: "
+                                + ObexHelper.getMaxTxPacketSize(mTransport)
+                                + " Lowering limit to this value.");
+                        mMaxTxPacketSize = ObexHelper.getMaxTxPacketSize(mTransport);
+                    }
+
+                    if (length > 7) {
+                        data = new byte[length - 7];
+
+                        bytesReceived = mInput.read(data);
+                        while (bytesReceived != (length - 7)) {
+                            bytesReceived += mInput.read(data, bytesReceived, data.length
+                                    - bytesReceived);
+                        }
+                    } else {
+                        return true;
+                    }
+                } else {
+                    data = new byte[length - 3];
+                    bytesReceived = mInput.read(data);
+
+                    while (bytesReceived != (length - 3)) {
+                        bytesReceived += mInput.read(data, bytesReceived,
+                                data.length - bytesReceived);
+                    }
+                    if (opCode == ObexHelper.OBEX_OPCODE_ABORT) {
+                        return true;
+                    }
+                }
+
+                byte[] body = ObexHelper.updateHeaderSet(header, data);
+                if ((privateInput != null) && (body != null)) {
+                    privateInput.writeBytes(body, 1);
+                }
+
+                if (header.mConnectionID != null) {
+                    mConnectionId = new byte[4];
+                    System.arraycopy(header.mConnectionID, 0, mConnectionId, 0, 4);
+                }
+
+                if (header.mAuthResp != null) {
+                    if (!handleAuthResp(header.mAuthResp)) {
+                        setRequestInactive();
+                        throw new IOException("Authentication Failed");
+                    }
+                }
+
+                if ((header.responseCode == ResponseCodes.OBEX_HTTP_UNAUTHORIZED)
+                        && (header.mAuthChall != null)) {
+
+                    if (handleAuthChall(header)) {
+                        out.write((byte)HeaderSet.AUTH_RESPONSE);
+                        out.write((byte)((header.mAuthResp.length + 3) >> 8));
+                        out.write((byte)(header.mAuthResp.length + 3));
+                        out.write(header.mAuthResp);
+                        header.mAuthChall = null;
+                        header.mAuthResp = null;
+
+                        byte[] sendHeaders = new byte[out.size() - 3];
+                        System.arraycopy(out.toByteArray(), 3, sendHeaders, 0, sendHeaders.length);
+
+                        return sendRequest(opCode, sendHeaders, header, privateInput, false);
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+    public void close() throws IOException {
+        mOpen = false;
+        mInput.close();
+        mOutput.close();
+    }
+
+    /** @hide */
+    public boolean isSrmSupported() {
+        return mLocalSrmSupported;
+    }
+}
diff --git a/javax/obex/HeaderSet.java b/javax/obex/HeaderSet.java
new file mode 100644
index 0000000..8ce8d5f
--- /dev/null
+++ b/javax/obex/HeaderSet.java
@@ -0,0 +1,728 @@
+/*
+ * Copyright (c) 2014 The Android Open Source Project
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.Calendar;
+
+/**
+ * This class implements the javax.obex.HeaderSet interface for OBEX over
+ * RFCOMM or OBEX over l2cap.
+ */
+public final class HeaderSet {
+
+    /**
+     * Represents the OBEX Count header. This allows the connection statement to
+     * tell the server how many objects it plans to send or retrieve.
+     * <P>
+     * The value of <code>COUNT</code> is 0xC0 (192).
+     */
+    public static final int COUNT = 0xC0;
+
+    /**
+     * Represents the OBEX Name header. This specifies the name of the object.
+     * <P>
+     * The value of <code>NAME</code> is 0x01 (1).
+     */
+    public static final int NAME = 0x01;
+
+    /**
+     * Represents the OBEX Type header. This allows a request to specify the
+     * type of the object (e.g. text, html, binary, etc.).
+     * <P>
+     * The value of <code>TYPE</code> is 0x42 (66).
+     */
+    public static final int TYPE = 0x42;
+
+    /**
+     * Represents the OBEX Length header. This is the length of the object in
+     * bytes.
+     * <P>
+     * The value of <code>LENGTH</code> is 0xC3 (195).
+     */
+    public static final int LENGTH = 0xC3;
+
+    /**
+     * Represents the OBEX Time header using the ISO 8601 standards. This is the
+     * preferred time header.
+     * <P>
+     * The value of <code>TIME_ISO_8601</code> is 0x44 (68).
+     */
+    public static final int TIME_ISO_8601 = 0x44;
+
+    /**
+     * Represents the OBEX Time header using the 4 byte representation. This is
+     * only included for backwards compatibility. It represents the number of
+     * seconds since January 1, 1970.
+     * <P>
+     * The value of <code>TIME_4_BYTE</code> is 0xC4 (196).
+     */
+    public static final int TIME_4_BYTE = 0xC4;
+
+    /**
+     * Represents the OBEX Description header. This is a text description of the
+     * object.
+     * <P>
+     * The value of <code>DESCRIPTION</code> is 0x05 (5).
+     */
+    public static final int DESCRIPTION = 0x05;
+
+    /**
+     * Represents the OBEX Target header. This is the name of the service an
+     * operation is targeted to.
+     * <P>
+     * The value of <code>TARGET</code> is 0x46 (70).
+     */
+    public static final int TARGET = 0x46;
+
+    /**
+     * Represents the OBEX HTTP header. This allows an HTTP 1.X header to be
+     * included in a request or reply.
+     * <P>
+     * The value of <code>HTTP</code> is 0x47 (71).
+     */
+    public static final int HTTP = 0x47;
+
+    /**
+     * Represents the OBEX BODY header.
+     * <P>
+     * The value of <code>BODY</code> is 0x48 (72).
+     *
+     * @hide
+     */
+    public static final int BODY = 0x48;
+
+    /**
+     * Represents the OBEX End of BODY header.
+     * <P>
+     * The value of <code>BODY</code> is 0x49 (73).
+     *
+     * @hide
+     */
+    public static final int END_OF_BODY = 0x49;
+
+    /**
+     * Represents the OBEX Who header. Identifies the OBEX application to
+     * determine if the two peers are talking to each other.
+     * <P>
+     * The value of <code>WHO</code> is 0x4A (74).
+     */
+    public static final int WHO = 0x4A;
+
+    /**
+     * Represents the OBEX Connection ID header. Identifies used for OBEX
+     * connection multiplexing.
+     * <P>
+     * The value of <code>CONNECTION_ID</code> is 0xCB (203).
+     *
+     * @hide
+     */
+    public static final int CONNECTION_ID = 0xCB;
+
+    /**
+     * Represents the OBEX Application Parameter header. This header specifies
+     * additional application request and response information.
+     * <P>
+     * The value of <code>APPLICATION_PARAMETER</code> is 0x4C (76).
+     */
+    public static final int APPLICATION_PARAMETER = 0x4C;
+
+    /**
+     * Represents the OBEX authentication digest-challenge.
+     * <P>
+     * The value of <code>AUTH_CHALLENGE</code> is 0x4D (77).
+     *
+     * @hide
+     */
+    public static final int AUTH_CHALLENGE = 0x4D;
+
+    /**
+     * Represents the OBEX authentication digest-response.
+     * <P>
+     * The value of <code>AUTH_RESPONSE</code> is 0x4E (78).
+     *
+     * @hide
+     */
+    public static final int AUTH_RESPONSE = 0x4E;
+
+    /**
+     * Represents the OBEX Object Class header. This header specifies the OBEX
+     * object class of the object.
+     * <P>
+     * The value of <code>OBJECT_CLASS</code> is 0x4F (79).
+     */
+    public static final int OBJECT_CLASS = 0x4F;
+
+    /**
+     * Represents the OBEX Single Response Mode (SRM). This header is used
+     * for Single response mode, introduced in OBEX 1.5.
+     * <P>
+     * The value of <code>SINGLE_RESPONSE_MODE</code> is 0x97 (151).
+     *
+     * @hide
+     */
+    public static final int SINGLE_RESPONSE_MODE = 0x97;
+
+    /**
+     * Represents the OBEX Single Response Mode Parameters. This header is used
+     * for Single response mode, introduced in OBEX 1.5.
+     * <P>
+     * The value of <code>SINGLE_RESPONSE_MODE_PARAMETER</code> is 0x98 (152).
+     *
+     * @hide
+     */
+    public static final int SINGLE_RESPONSE_MODE_PARAMETER = 0x98;
+
+    private Long mCount; // 4 byte unsigned integer
+
+    private String mName; // null terminated Unicode text string
+
+    private boolean mEmptyName;
+
+    private String mType; // null terminated ASCII text string
+
+    private Long mLength; // 4 byte unsigend integer
+
+    private Calendar mIsoTime; // String of the form YYYYMMDDTHHMMSSZ
+
+    private Calendar mByteTime; // 4 byte unsigned integer
+
+    private String mDescription; // null terminated Unicode text String
+
+    private byte[] mTarget; // byte sequence
+
+    private byte[] mHttpHeader; // byte sequence
+
+    private byte[] mWho; // length prefixed byte sequence
+
+    private byte[] mAppParam; // byte sequence of the form tag length value
+
+    private byte[] mObjectClass; // byte sequence
+
+    private String[] mUnicodeUserDefined; // null terminated unicode string
+
+    private byte[][] mSequenceUserDefined; // byte sequence user defined
+
+    private Byte[] mByteUserDefined; // 1 byte
+
+    private Long[] mIntegerUserDefined; // 4 byte unsigned integer
+
+    private SecureRandom mRandom = null;
+
+    private Byte mSingleResponseMode; // byte to indicate enable/disable/support for SRM
+
+    private Byte mSrmParam; // byte representing the SRM parameters - only "wait"
+                            // is supported by Bluetooth
+
+    /*package*/ byte[] nonce;
+
+    public byte[] mAuthChall; // The authentication challenge header
+
+    public byte[] mAuthResp; // The authentication response header
+
+    public byte[] mConnectionID; // THe connection ID
+
+    public int responseCode;
+
+    /**
+     * Creates new <code>HeaderSet</code> object.
+     */
+    public HeaderSet() {
+        mUnicodeUserDefined = new String[16];
+        mSequenceUserDefined = new byte[16][];
+        mByteUserDefined = new Byte[16];
+        mIntegerUserDefined = new Long[16];
+        responseCode = -1;
+    }
+
+    /**
+     * Sets flag for special "value" of NAME header which should be empty. This
+     * is not the same as NAME header with empty string in which case it will
+     * have length of 5 bytes. It should be 3 bytes with only header id and
+     * length field.
+     */
+    public void setEmptyNameHeader() {
+        mName = null;
+        mEmptyName = true;
+    }
+
+    /**
+     * Gets flag for special "value" of NAME header which should be empty. See
+     * above.
+     *
+     * @hide
+     */
+    public boolean getEmptyNameHeader() {
+        return mEmptyName;
+    }
+
+    /**
+     * Sets the value of the header identifier to the value provided. The type
+     * of object must correspond to the Java type defined in the description of
+     * this interface. If <code>null</code> is passed as the
+     * <code>headerValue</code> then the header will be removed from the set of
+     * headers to include in the next request.
+     * @param headerID the identifier to include in the message
+     * @param headerValue the value of the header identifier
+     * @throws IllegalArgumentException if the header identifier provided is not
+     *         one defined in this interface or a user-defined header; if the
+     *         type of <code>headerValue</code> is not the correct Java type as
+     *         defined in the description of this interface\
+     */
+    public void setHeader(int headerID, Object headerValue) {
+        long temp = -1;
+
+        switch (headerID) {
+            case COUNT:
+                if (!(headerValue instanceof Long)) {
+                    if (headerValue == null) {
+                        mCount = null;
+                        break;
+                    }
+                    throw new IllegalArgumentException("Count must be a Long");
+                }
+                temp = ((Long)headerValue).longValue();
+                if ((temp < 0L) || (temp > 0xFFFFFFFFL)) {
+                    throw new IllegalArgumentException("Count must be between 0 and 0xFFFFFFFF");
+                }
+                mCount = (Long)headerValue;
+                break;
+            case NAME:
+                if ((headerValue != null) && (!(headerValue instanceof String))) {
+                    throw new IllegalArgumentException("Name must be a String");
+                }
+                mEmptyName = false;
+                mName = (String)headerValue;
+                break;
+            case TYPE:
+                if ((headerValue != null) && (!(headerValue instanceof String))) {
+                    throw new IllegalArgumentException("Type must be a String");
+                }
+                mType = (String)headerValue;
+                break;
+            case LENGTH:
+                if (!(headerValue instanceof Long)) {
+                    if (headerValue == null) {
+                        mLength = null;
+                        break;
+                    }
+                    throw new IllegalArgumentException("Length must be a Long");
+                }
+                temp = ((Long)headerValue).longValue();
+                if ((temp < 0L) || (temp > 0xFFFFFFFFL)) {
+                    throw new IllegalArgumentException("Length must be between 0 and 0xFFFFFFFF");
+                }
+                mLength = (Long)headerValue;
+                break;
+            case TIME_ISO_8601:
+                if ((headerValue != null) && (!(headerValue instanceof Calendar))) {
+                    throw new IllegalArgumentException("Time ISO 8601 must be a Calendar");
+                }
+                mIsoTime = (Calendar)headerValue;
+                break;
+            case TIME_4_BYTE:
+                if ((headerValue != null) && (!(headerValue instanceof Calendar))) {
+                    throw new IllegalArgumentException("Time 4 Byte must be a Calendar");
+                }
+                mByteTime = (Calendar)headerValue;
+                break;
+            case DESCRIPTION:
+                if ((headerValue != null) && (!(headerValue instanceof String))) {
+                    throw new IllegalArgumentException("Description must be a String");
+                }
+                mDescription = (String)headerValue;
+                break;
+            case TARGET:
+                if (headerValue == null) {
+                    mTarget = null;
+                } else {
+                    if (!(headerValue instanceof byte[])) {
+                        throw new IllegalArgumentException("Target must be a byte array");
+                    } else {
+                        mTarget = new byte[((byte[])headerValue).length];
+                        System.arraycopy(headerValue, 0, mTarget, 0, mTarget.length);
+                    }
+                }
+                break;
+            case HTTP:
+                if (headerValue == null) {
+                    mHttpHeader = null;
+                } else {
+                    if (!(headerValue instanceof byte[])) {
+                        throw new IllegalArgumentException("HTTP must be a byte array");
+                    } else {
+                        mHttpHeader = new byte[((byte[])headerValue).length];
+                        System.arraycopy(headerValue, 0, mHttpHeader, 0, mHttpHeader.length);
+                    }
+                }
+                break;
+            case WHO:
+                if (headerValue == null) {
+                    mWho = null;
+                } else {
+                    if (!(headerValue instanceof byte[])) {
+                        throw new IllegalArgumentException("WHO must be a byte array");
+                    } else {
+                        mWho = new byte[((byte[])headerValue).length];
+                        System.arraycopy(headerValue, 0, mWho, 0, mWho.length);
+                    }
+                }
+                break;
+            case OBJECT_CLASS:
+                if (headerValue == null) {
+                    mObjectClass = null;
+                } else {
+                    if (!(headerValue instanceof byte[])) {
+                        throw new IllegalArgumentException("Object Class must be a byte array");
+                    } else {
+                        mObjectClass = new byte[((byte[])headerValue).length];
+                        System.arraycopy(headerValue, 0, mObjectClass, 0, mObjectClass.length);
+                    }
+                }
+                break;
+            case APPLICATION_PARAMETER:
+                if (headerValue == null) {
+                    mAppParam = null;
+                } else {
+                    if (!(headerValue instanceof byte[])) {
+                        throw new IllegalArgumentException(
+                                "Application Parameter must be a byte array");
+                    } else {
+                        mAppParam = new byte[((byte[])headerValue).length];
+                        System.arraycopy(headerValue, 0, mAppParam, 0, mAppParam.length);
+                    }
+                }
+                break;
+            case SINGLE_RESPONSE_MODE:
+                if (headerValue == null) {
+                    mSingleResponseMode = null;
+                } else {
+                    if (!(headerValue instanceof Byte)) {
+                        throw new IllegalArgumentException(
+                                "Single Response Mode must be a Byte");
+                    } else {
+                        mSingleResponseMode = (Byte)headerValue;
+                    }
+                }
+                break;
+            case SINGLE_RESPONSE_MODE_PARAMETER:
+                if (headerValue == null) {
+                    mSrmParam = null;
+                } else {
+                    if (!(headerValue instanceof Byte)) {
+                        throw new IllegalArgumentException(
+                                "Single Response Mode Parameter must be a Byte");
+                    } else {
+                        mSrmParam = (Byte)headerValue;
+                    }
+                }
+                break;
+            default:
+                // Verify that it was not a Unicode String user Defined
+                if ((headerID >= 0x30) && (headerID <= 0x3F)) {
+                    if ((headerValue != null) && (!(headerValue instanceof String))) {
+                        throw new IllegalArgumentException(
+                                "Unicode String User Defined must be a String");
+                    }
+                    mUnicodeUserDefined[headerID - 0x30] = (String)headerValue;
+
+                    break;
+                }
+                // Verify that it was not a byte sequence user defined value
+                if ((headerID >= 0x70) && (headerID <= 0x7F)) {
+
+                    if (headerValue == null) {
+                        mSequenceUserDefined[headerID - 0x70] = null;
+                    } else {
+                        if (!(headerValue instanceof byte[])) {
+                            throw new IllegalArgumentException(
+                                    "Byte Sequence User Defined must be a byte array");
+                        } else {
+                            mSequenceUserDefined[headerID - 0x70]
+                                    = new byte[((byte[])headerValue).length];
+                            System.arraycopy(headerValue, 0, mSequenceUserDefined[headerID - 0x70],
+                                    0, mSequenceUserDefined[headerID - 0x70].length);
+                        }
+                    }
+                    break;
+                }
+                // Verify that it was not a Byte user Defined
+                if ((headerID >= 0xB0) && (headerID <= 0xBF)) {
+                    if ((headerValue != null) && (!(headerValue instanceof Byte))) {
+                        throw new IllegalArgumentException("ByteUser Defined must be a Byte");
+                    }
+                    mByteUserDefined[headerID - 0xB0] = (Byte)headerValue;
+
+                    break;
+                }
+                // Verify that is was not the 4 byte unsigned integer user
+                // defined header
+                if ((headerID >= 0xF0) && (headerID <= 0xFF)) {
+                    if (!(headerValue instanceof Long)) {
+                        if (headerValue == null) {
+                            mIntegerUserDefined[headerID - 0xF0] = null;
+                            break;
+                        }
+                        throw new IllegalArgumentException("Integer User Defined must be a Long");
+                    }
+                    temp = ((Long)headerValue).longValue();
+                    if ((temp < 0L) || (temp > 0xFFFFFFFFL)) {
+                        throw new IllegalArgumentException(
+                                "Integer User Defined must be between 0 and 0xFFFFFFFF");
+                    }
+                    mIntegerUserDefined[headerID - 0xF0] = (Long)headerValue;
+                    break;
+                }
+                throw new IllegalArgumentException("Invalid Header Identifier");
+        }
+    }
+
+    /**
+     * Retrieves the value of the header identifier provided. The type of the
+     * Object returned is defined in the description of this interface.
+     * @param headerID the header identifier whose value is to be returned
+     * @return the value of the header provided or <code>null</code> if the
+     *         header identifier specified is not part of this
+     *         <code>HeaderSet</code> object
+     * @throws IllegalArgumentException if the <code>headerID</code> is not one
+     *         defined in this interface or any of the user-defined headers
+     * @throws IOException if an error occurred in the transport layer during
+     *         the operation or if the connection has been closed
+     */
+    public Object getHeader(int headerID) throws IOException {
+
+        switch (headerID) {
+            case COUNT:
+                return mCount;
+            case NAME:
+                return mName;
+            case TYPE:
+                return mType;
+            case LENGTH:
+                return mLength;
+            case TIME_ISO_8601:
+                return mIsoTime;
+            case TIME_4_BYTE:
+                return mByteTime;
+            case DESCRIPTION:
+                return mDescription;
+            case TARGET:
+                return mTarget;
+            case HTTP:
+                return mHttpHeader;
+            case WHO:
+                return mWho;
+            case CONNECTION_ID:
+                return mConnectionID;
+            case OBJECT_CLASS:
+                return mObjectClass;
+            case APPLICATION_PARAMETER:
+                return mAppParam;
+            case SINGLE_RESPONSE_MODE:
+                return mSingleResponseMode;
+            case SINGLE_RESPONSE_MODE_PARAMETER:
+                return mSrmParam;
+            default:
+                // Verify that it was not a Unicode String user Defined
+                if ((headerID >= 0x30) && (headerID <= 0x3F)) {
+                    return mUnicodeUserDefined[headerID - 0x30];
+                }
+                // Verify that it was not a byte sequence user defined header
+                if ((headerID >= 0x70) && (headerID <= 0x7F)) {
+                    return mSequenceUserDefined[headerID - 0x70];
+                }
+                // Verify that it was not a byte user defined header
+                if ((headerID >= 0xB0) && (headerID <= 0xBF)) {
+                    return mByteUserDefined[headerID - 0xB0];
+                }
+                // Verify that it was not a integer user defined header
+                if ((headerID >= 0xF0) && (headerID <= 0xFF)) {
+                    return mIntegerUserDefined[headerID - 0xF0];
+                }
+                throw new IllegalArgumentException("Invalid Header Identifier");
+        }
+    }
+
+    /**
+     * Retrieves the list of headers that may be retrieved via the
+     * <code>getHeader</code> method that will not return <code>null</code>. In
+     * other words, this method returns all the headers that are available in
+     * this object.
+     * @see #getHeader
+     * @return the array of headers that are set in this object or
+     *         <code>null</code> if no headers are available
+     * @throws IOException if an error occurred in the transport layer during
+     *         the operation or the connection has been closed
+     *
+     * @hide
+     */
+    public int[] getHeaderList() throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        if (mCount != null) {
+            out.write(COUNT);
+        }
+        if (mName != null) {
+            out.write(NAME);
+        }
+        if (mType != null) {
+            out.write(TYPE);
+        }
+        if (mLength != null) {
+            out.write(LENGTH);
+        }
+        if (mIsoTime != null) {
+            out.write(TIME_ISO_8601);
+        }
+        if (mByteTime != null) {
+            out.write(TIME_4_BYTE);
+        }
+        if (mDescription != null) {
+            out.write(DESCRIPTION);
+        }
+        if (mTarget != null) {
+            out.write(TARGET);
+        }
+        if (mHttpHeader != null) {
+            out.write(HTTP);
+        }
+        if (mWho != null) {
+            out.write(WHO);
+        }
+        if (mAppParam != null) {
+            out.write(APPLICATION_PARAMETER);
+        }
+        if (mObjectClass != null) {
+            out.write(OBJECT_CLASS);
+        }
+        if(mSingleResponseMode != null) {
+            out.write(SINGLE_RESPONSE_MODE);
+        }
+        if(mSrmParam != null) {
+            out.write(SINGLE_RESPONSE_MODE_PARAMETER);
+        }
+
+        for (int i = 0x30; i < 0x40; i++) {
+            if (mUnicodeUserDefined[i - 0x30] != null) {
+                out.write(i);
+            }
+        }
+
+        for (int i = 0x70; i < 0x80; i++) {
+            if (mSequenceUserDefined[i - 0x70] != null) {
+                out.write(i);
+            }
+        }
+
+        for (int i = 0xB0; i < 0xC0; i++) {
+            if (mByteUserDefined[i - 0xB0] != null) {
+                out.write(i);
+            }
+        }
+
+        for (int i = 0xF0; i < 0x100; i++) {
+            if (mIntegerUserDefined[i - 0xF0] != null) {
+                out.write(i);
+            }
+        }
+
+        byte[] headers = out.toByteArray();
+        out.close();
+
+        if ((headers == null) || (headers.length == 0)) {
+            return null;
+        }
+
+        int[] result = new int[headers.length];
+        for (int i = 0; i < headers.length; i++) {
+            // Convert the byte to a positive integer.  That is, an integer
+            // between 0 and 256.
+            result[i] = headers[i] & 0xFF;
+        }
+
+        return result;
+    }
+
+    /**
+     * Sets the authentication challenge header. The <code>realm</code> will be
+     * encoded based upon the default encoding scheme used by the implementation
+     * to encode strings. Therefore, the encoding scheme used to encode the
+     * <code>realm</code> is application dependent.
+     * @param realm a short description that describes what password to use; if
+     *        <code>null</code> no realm will be sent in the authentication
+     *        challenge header
+     * @param userID if <code>true</code>, a user ID is required in the reply;
+     *        if <code>false</code>, no user ID is required
+     * @param access if <code>true</code> then full access will be granted if
+     *        successful; if <code>false</code> then read-only access will be
+     *        granted if successful
+     * @throws IOException
+     *
+     * @hide
+     */
+    public void createAuthenticationChallenge(String realm, boolean userID, boolean access)
+            throws IOException {
+
+        nonce = new byte[16];
+        if(mRandom == null) {
+            mRandom = new SecureRandom();
+        }
+        for (int i = 0; i < 16; i++) {
+            nonce[i] = (byte)mRandom.nextInt();
+        }
+
+        mAuthChall = ObexHelper.computeAuthenticationChallenge(nonce, realm, access, userID);
+    }
+
+    /**
+     * Returns the response code received from the server. Response codes are
+     * defined in the <code>ResponseCodes</code> class.
+     * @see ResponseCodes
+     * @return the response code retrieved from the server
+     * @throws IOException if an error occurred in the transport layer during
+     *         the transaction; if this method is called on a
+     *         <code>HeaderSet</code> object created by calling
+     *         <code>createHeaderSet()</code> in a <code>ClientSession</code>
+     *         object; if this object was created by an OBEX server
+     */
+    public int getResponseCode() throws IOException {
+        if (responseCode == -1) {
+            throw new IOException("May not be called on a server");
+        } else {
+            return responseCode;
+        }
+    }
+}
diff --git a/javax/obex/ObexHelper.java b/javax/obex/ObexHelper.java
new file mode 100644
index 0000000..30dc8f8
--- /dev/null
+++ b/javax/obex/ObexHelper.java
@@ -0,0 +1,1100 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2015 Samsung LSI
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+
+
+/**
+ * This class defines a set of helper methods for the implementation of Obex.
+ */
+public final class ObexHelper {
+
+    private static final String TAG = "ObexHelper";
+    public static final boolean VDBG = false;
+    /**
+     * Defines the basic packet length used by OBEX. Every OBEX packet has the
+     * same basic format:<BR>
+     * Byte 0: Request or Response Code Byte 1&2: Length of the packet.
+     */
+    public static final int BASE_PACKET_LENGTH = 3;
+
+    /** Prevent object construction of helper class */
+    private ObexHelper() {
+    }
+
+    /**
+     * The maximum packet size for OBEX packets that this client can handle. At
+     * present, this must be changed for each port. TODO: The max packet size
+     * should be the Max incoming MTU minus TODO: L2CAP package headers and
+     * RFCOMM package headers. TODO: Retrieve the max incoming MTU from TODO:
+     * LocalDevice.getProperty().
+     * NOTE: This value must be larger than or equal to the L2CAP SDU
+     */
+    /*
+     * android note set as 0xFFFE to match remote MPS
+     */
+    public static final int MAX_PACKET_SIZE_INT = 0xFFFE;
+
+    // The minimum allowed max packet size is 255 according to the OBEX specification
+    public static final int LOWER_LIMIT_MAX_PACKET_SIZE = 255;
+
+    // The length of OBEX Byte Sequency Header Id according to the OBEX specification
+    public static final int OBEX_BYTE_SEQ_HEADER_LEN = 0x03;
+
+    /**
+     * Temporary workaround to be able to push files to Windows 7.
+     * TODO: Should be removed as soon as Microsoft updates their driver.
+     */
+    public static final int MAX_CLIENT_PACKET_SIZE = 0xFC00;
+
+    public static final int OBEX_OPCODE_FINAL_BIT_MASK = 0x80;
+
+    public static final int OBEX_OPCODE_CONNECT = 0x80;
+
+    public static final int OBEX_OPCODE_DISCONNECT = 0x81;
+
+    public static final int OBEX_OPCODE_PUT = 0x02;
+
+    public static final int OBEX_OPCODE_PUT_FINAL = 0x82;
+
+    public static final int OBEX_OPCODE_GET = 0x03;
+
+    public static final int OBEX_OPCODE_GET_FINAL = 0x83;
+
+    public static final int OBEX_OPCODE_RESERVED = 0x04;
+
+    public static final int OBEX_OPCODE_RESERVED_FINAL = 0x84;
+
+    public static final int OBEX_OPCODE_SETPATH = 0x85;
+
+    public static final int OBEX_OPCODE_ABORT = 0xFF;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_ASCII = 0x00;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_1 = 0x01;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_2 = 0x02;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_3 = 0x03;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_4 = 0x04;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_5 = 0x05;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_6 = 0x06;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_7 = 0x07;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_8 = 0x08;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_ISO_8859_9 = 0x09;
+
+    public static final int OBEX_AUTH_REALM_CHARSET_UNICODE = 0xFF;
+
+    public static final byte OBEX_SRM_ENABLE         = 0x01; // For BT we only need enable/disable
+    public static final byte OBEX_SRM_DISABLE        = 0x00;
+    public static final byte OBEX_SRM_SUPPORT        = 0x02; // Unused for now
+
+    public static final byte OBEX_SRMP_WAIT          = 0x01; // Only SRMP value used by BT
+
+    /**
+     * Updates the HeaderSet with the headers received in the byte array
+     * provided. Invalid headers are ignored.
+     * <P>
+     * The first two bits of an OBEX Header specifies the type of object that is
+     * being sent. The table below specifies the meaning of the high bits.
+     * <TABLE>
+     * <TR>
+     * <TH>Bits 8 and 7</TH>
+     * <TH>Value</TH>
+     * <TH>Description</TH>
+     * </TR>
+     * <TR>
+     * <TD>00</TD>
+     * <TD>0x00</TD>
+     * <TD>Null Terminated Unicode text, prefixed with 2 byte unsigned integer</TD>
+     * </TR>
+     * <TR>
+     * <TD>01</TD>
+     * <TD>0x40</TD>
+     * <TD>Byte Sequence, length prefixed with 2 byte unsigned integer</TD>
+     * </TR>
+     * <TR>
+     * <TD>10</TD>
+     * <TD>0x80</TD>
+     * <TD>1 byte quantity</TD>
+     * </TR>
+     * <TR>
+     * <TD>11</TD>
+     * <TD>0xC0</TD>
+     * <TD>4 byte quantity - transmitted in network byte order (high byte first</TD>
+     * </TR>
+     * </TABLE>
+     * This method uses the information in this table to determine the type of
+     * Java object to create and passes that object with the full header to
+     * setHeader() to update the HeaderSet object. Invalid headers will cause an
+     * exception to be thrown. When it is thrown, it is ignored.
+     * @param header the HeaderSet to update
+     * @param headerArray the byte array containing headers
+     * @return the result of the last start body or end body header provided;
+     *         the first byte in the result will specify if a body or end of
+     *         body is received
+     * @throws IOException if an invalid header was found
+     */
+    public static byte[] updateHeaderSet(HeaderSet header, byte[] headerArray) throws IOException {
+        int index = 0;
+        int length = 0;
+        int headerID;
+        byte[] value = null;
+        byte[] body = null;
+        HeaderSet headerImpl = header;
+        try {
+            while (index < headerArray.length) {
+                headerID = 0xFF & headerArray[index];
+                switch (headerID & (0xC0)) {
+
+                    /*
+                     * 0x00 is a unicode null terminate string with the first
+                     * two bytes after the header identifier being the length
+                     */
+                    case 0x00:
+                        // Fall through
+                        /*
+                         * 0x40 is a byte sequence with the first
+                         * two bytes after the header identifier being the length
+                         */
+                    case 0x40:
+                        boolean trimTail = true;
+                        index++;
+                        length = ((0xFF & headerArray[index]) << 8) +
+                                 (0xFF & headerArray[index + 1]);
+                        index += 2;
+                        if (length <= OBEX_BYTE_SEQ_HEADER_LEN) {
+                            Log.e(TAG, "Remote sent an OBEX packet with " +
+                                  "incorrect header length = " + length);
+                            break;
+                        }
+                        length -= OBEX_BYTE_SEQ_HEADER_LEN;
+                        value = new byte[length];
+                        System.arraycopy(headerArray, index, value, 0, length);
+                        if (length == 0 || (length > 0 && (value[length - 1] != 0))) {
+                            trimTail = false;
+                        }
+                        switch (headerID) {
+                            case HeaderSet.TYPE:
+                                try {
+                                    // Remove trailing null
+                                    if (trimTail == false) {
+                                        headerImpl.setHeader(headerID, new String(value, 0,
+                                                value.length, "ISO8859_1"));
+                                    } else {
+                                        headerImpl.setHeader(headerID, new String(value, 0,
+                                                value.length - 1, "ISO8859_1"));
+                                    }
+                                } catch (UnsupportedEncodingException e) {
+                                    throw e;
+                                }
+                                break;
+
+                            case HeaderSet.AUTH_CHALLENGE:
+                                headerImpl.mAuthChall = new byte[length];
+                                System.arraycopy(headerArray, index, headerImpl.mAuthChall, 0,
+                                        length);
+                                break;
+
+                            case HeaderSet.AUTH_RESPONSE:
+                                headerImpl.mAuthResp = new byte[length];
+                                System.arraycopy(headerArray, index, headerImpl.mAuthResp, 0,
+                                        length);
+                                break;
+
+                            case HeaderSet.BODY:
+                                /* Fall Through */
+                            case HeaderSet.END_OF_BODY:
+                                body = new byte[length + 1];
+                                body[0] = (byte)headerID;
+                                System.arraycopy(headerArray, index, body, 1, length);
+                                break;
+
+                            case HeaderSet.TIME_ISO_8601:
+                                try {
+                                    String dateString = new String(value, "ISO8859_1");
+                                    Calendar temp = Calendar.getInstance();
+                                    if ((dateString.length() == 16)
+                                            && (dateString.charAt(15) == 'Z')) {
+                                        temp.setTimeZone(TimeZone.getTimeZone("UTC"));
+                                    }
+                                    temp.set(Calendar.YEAR, Integer.parseInt(dateString.substring(
+                                            0, 4)));
+                                    temp.set(Calendar.MONTH, Integer.parseInt(dateString.substring(
+                                            4, 6)));
+                                    temp.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateString
+                                            .substring(6, 8)));
+                                    temp.set(Calendar.HOUR_OF_DAY, Integer.parseInt(dateString
+                                            .substring(9, 11)));
+                                    temp.set(Calendar.MINUTE, Integer.parseInt(dateString
+                                            .substring(11, 13)));
+                                    temp.set(Calendar.SECOND, Integer.parseInt(dateString
+                                            .substring(13, 15)));
+                                    headerImpl.setHeader(HeaderSet.TIME_ISO_8601, temp);
+                                } catch (UnsupportedEncodingException e) {
+                                    throw e;
+                                }
+                                break;
+
+                            default:
+                                if ((headerID & 0xC0) == 0x00) {
+                                    headerImpl.setHeader(headerID, ObexHelper.convertToUnicode(
+                                            value, true));
+                                } else {
+                                    headerImpl.setHeader(headerID, value);
+                                }
+                        }
+
+                        index += length;
+                        break;
+
+                    /*
+                     * 0x80 is a byte header.  The only valid byte headers are
+                     * the 16 user defined byte headers.
+                     */
+                    case 0x80:
+                        index++;
+                        try {
+                            headerImpl.setHeader(headerID, Byte.valueOf(headerArray[index]));
+                        } catch (Exception e) {
+                            // Not a valid header so ignore
+                        }
+                        index++;
+                        break;
+
+                    /*
+                     * 0xC0 is a 4 byte unsigned integer header and with the
+                     * exception of TIME_4_BYTE will be converted to a Long
+                     * and added.
+                     */
+                    case 0xC0:
+                        index++;
+                        value = new byte[4];
+                        System.arraycopy(headerArray, index, value, 0, 4);
+                        try {
+                            if (headerID != HeaderSet.TIME_4_BYTE) {
+                                // Determine if it is a connection ID.  These
+                                // need to be handled differently
+                                if (headerID == HeaderSet.CONNECTION_ID) {
+                                    headerImpl.mConnectionID = new byte[4];
+                                    System.arraycopy(value, 0, headerImpl.mConnectionID, 0, 4);
+                                } else {
+                                    headerImpl.setHeader(headerID, Long
+                                            .valueOf(convertToLong(value)));
+                                }
+                            } else {
+                                Calendar temp = Calendar.getInstance();
+                                temp.setTime(new Date(convertToLong(value) * 1000L));
+                                headerImpl.setHeader(HeaderSet.TIME_4_BYTE, temp);
+                            }
+                        } catch (Exception e) {
+                            // Not a valid header so ignore
+                            throw new IOException("Header was not formatted properly", e);
+                        }
+                        index += 4;
+                        break;
+                }
+
+            }
+        } catch (IOException e) {
+            throw new IOException("Header was not formatted properly", e);
+        }
+
+        return body;
+    }
+
+    /**
+     * Creates the header part of OBEX packet based on the header provided.
+     * TODO: Could use getHeaderList() to get the array of headers to include
+     * and then use the high two bits to determine the type of the object
+     * and construct the byte array from that. This will make the size smaller.
+     * @param head the header used to construct the byte array
+     * @param nullOut <code>true</code> if the header should be set to
+     *        <code>null</code> once it is added to the array or
+     *        <code>false</code> if it should not be nulled out
+     * @return the header of an OBEX packet
+     */
+    public static byte[] createHeader(HeaderSet head, boolean nullOut) {
+        Long intHeader = null;
+        String stringHeader = null;
+        Calendar dateHeader = null;
+        Byte byteHeader = null;
+        StringBuffer buffer = null;
+        byte[] value = null;
+        byte[] result = null;
+        byte[] lengthArray = new byte[2];
+        int length;
+        HeaderSet headImpl = null;
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        headImpl = head;
+
+        try {
+            /*
+             * Determine if there is a connection ID to send.  If there is,
+             * then it should be the first header in the packet.
+             */
+            if ((headImpl.mConnectionID != null)
+                    && (headImpl.getHeader(HeaderSet.TARGET) == null)) {
+
+                out.write((byte)HeaderSet.CONNECTION_ID);
+                out.write(headImpl.mConnectionID);
+            }
+
+            // Count Header
+            intHeader = (Long)headImpl.getHeader(HeaderSet.COUNT);
+            if (intHeader != null) {
+                out.write((byte)HeaderSet.COUNT);
+                value = ObexHelper.convertToByteArray(intHeader.longValue());
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.COUNT, null);
+                }
+            }
+
+            // Name Header
+            stringHeader = (String)headImpl.getHeader(HeaderSet.NAME);
+            if (stringHeader != null) {
+                out.write((byte)HeaderSet.NAME);
+                value = ObexHelper.convertToUnicodeByteArray(stringHeader);
+                length = value.length + 3;
+                lengthArray[0] = (byte)(0xFF & (length >> 8));
+                lengthArray[1] = (byte)(0xFF & length);
+                out.write(lengthArray);
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.NAME, null);
+                }
+            } else if (headImpl.getEmptyNameHeader()) {
+                out.write((byte) HeaderSet.NAME);
+                lengthArray[0] = (byte) 0x00;
+                lengthArray[1] = (byte) 0x03;
+                out.write(lengthArray);
+            }
+
+            // Type Header
+            stringHeader = (String)headImpl.getHeader(HeaderSet.TYPE);
+            if (stringHeader != null) {
+                out.write((byte)HeaderSet.TYPE);
+                try {
+                    value = stringHeader.getBytes("ISO8859_1");
+                } catch (UnsupportedEncodingException e) {
+                    throw e;
+                }
+
+                length = value.length + 4;
+                lengthArray[0] = (byte)(255 & (length >> 8));
+                lengthArray[1] = (byte)(255 & length);
+                out.write(lengthArray);
+                out.write(value);
+                out.write(0x00);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.TYPE, null);
+                }
+            }
+
+            // Length Header
+            intHeader = (Long)headImpl.getHeader(HeaderSet.LENGTH);
+            if (intHeader != null) {
+                out.write((byte)HeaderSet.LENGTH);
+                value = ObexHelper.convertToByteArray(intHeader.longValue());
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.LENGTH, null);
+                }
+            }
+
+            // Time ISO Header
+            dateHeader = (Calendar)headImpl.getHeader(HeaderSet.TIME_ISO_8601);
+            if (dateHeader != null) {
+
+                /*
+                 * The ISO Header should take the form YYYYMMDDTHHMMSSZ.  The
+                 * 'Z' will only be included if it is a UTC time.
+                 */
+                buffer = new StringBuffer();
+                int temp = dateHeader.get(Calendar.YEAR);
+                for (int i = temp; i < 1000; i = i * 10) {
+                    buffer.append("0");
+                }
+                buffer.append(temp);
+                temp = dateHeader.get(Calendar.MONTH);
+                if (temp < 10) {
+                    buffer.append("0");
+                }
+                buffer.append(temp);
+                temp = dateHeader.get(Calendar.DAY_OF_MONTH);
+                if (temp < 10) {
+                    buffer.append("0");
+                }
+                buffer.append(temp);
+                buffer.append("T");
+                temp = dateHeader.get(Calendar.HOUR_OF_DAY);
+                if (temp < 10) {
+                    buffer.append("0");
+                }
+                buffer.append(temp);
+                temp = dateHeader.get(Calendar.MINUTE);
+                if (temp < 10) {
+                    buffer.append("0");
+                }
+                buffer.append(temp);
+                temp = dateHeader.get(Calendar.SECOND);
+                if (temp < 10) {
+                    buffer.append("0");
+                }
+                buffer.append(temp);
+
+                if (dateHeader.getTimeZone().getID().equals("UTC")) {
+                    buffer.append("Z");
+                }
+
+                try {
+                    value = buffer.toString().getBytes("ISO8859_1");
+                } catch (UnsupportedEncodingException e) {
+                    throw e;
+                }
+
+                length = value.length + 3;
+                lengthArray[0] = (byte)(255 & (length >> 8));
+                lengthArray[1] = (byte)(255 & length);
+                out.write(HeaderSet.TIME_ISO_8601);
+                out.write(lengthArray);
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.TIME_ISO_8601, null);
+                }
+            }
+
+            // Time 4 Byte Header
+            dateHeader = (Calendar)headImpl.getHeader(HeaderSet.TIME_4_BYTE);
+            if (dateHeader != null) {
+                out.write(HeaderSet.TIME_4_BYTE);
+
+                /*
+                 * Need to call getTime() twice.  The first call will return
+                 * a java.util.Date object.  The second call returns the number
+                 * of milliseconds since January 1, 1970.  We need to convert
+                 * it to seconds since the TIME_4_BYTE expects the number of
+                 * seconds since January 1, 1970.
+                 */
+                value = ObexHelper.convertToByteArray(dateHeader.getTime().getTime() / 1000L);
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.TIME_4_BYTE, null);
+                }
+            }
+
+            // Description Header
+            stringHeader = (String)headImpl.getHeader(HeaderSet.DESCRIPTION);
+            if (stringHeader != null) {
+                out.write((byte)HeaderSet.DESCRIPTION);
+                value = ObexHelper.convertToUnicodeByteArray(stringHeader);
+                length = value.length + 3;
+                lengthArray[0] = (byte)(255 & (length >> 8));
+                lengthArray[1] = (byte)(255 & length);
+                out.write(lengthArray);
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.DESCRIPTION, null);
+                }
+            }
+
+            // Target Header
+            value = (byte[])headImpl.getHeader(HeaderSet.TARGET);
+            if (value != null) {
+                out.write((byte)HeaderSet.TARGET);
+                length = value.length + 3;
+                lengthArray[0] = (byte)(255 & (length >> 8));
+                lengthArray[1] = (byte)(255 & length);
+                out.write(lengthArray);
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.TARGET, null);
+                }
+            }
+
+            // HTTP Header
+            value = (byte[])headImpl.getHeader(HeaderSet.HTTP);
+            if (value != null) {
+                out.write((byte)HeaderSet.HTTP);
+                length = value.length + 3;
+                lengthArray[0] = (byte)(255 & (length >> 8));
+                lengthArray[1] = (byte)(255 & length);
+                out.write(lengthArray);
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.HTTP, null);
+                }
+            }
+
+            // Who Header
+            value = (byte[])headImpl.getHeader(HeaderSet.WHO);
+            if (value != null) {
+                out.write((byte)HeaderSet.WHO);
+                length = value.length + 3;
+                lengthArray[0] = (byte)(255 & (length >> 8));
+                lengthArray[1] = (byte)(255 & length);
+                out.write(lengthArray);
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.WHO, null);
+                }
+            }
+
+            // Connection ID Header
+            value = (byte[])headImpl.getHeader(HeaderSet.APPLICATION_PARAMETER);
+            if (value != null) {
+                out.write((byte)HeaderSet.APPLICATION_PARAMETER);
+                length = value.length + 3;
+                lengthArray[0] = (byte)(255 & (length >> 8));
+                lengthArray[1] = (byte)(255 & length);
+                out.write(lengthArray);
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.APPLICATION_PARAMETER, null);
+                }
+            }
+
+            // Object Class Header
+            value = (byte[])headImpl.getHeader(HeaderSet.OBJECT_CLASS);
+            if (value != null) {
+                out.write((byte)HeaderSet.OBJECT_CLASS);
+                length = value.length + 3;
+                lengthArray[0] = (byte)(255 & (length >> 8));
+                lengthArray[1] = (byte)(255 & length);
+                out.write(lengthArray);
+                out.write(value);
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.OBJECT_CLASS, null);
+                }
+            }
+
+            // Check User Defined Headers
+            for (int i = 0; i < 16; i++) {
+
+                //Unicode String Header
+                stringHeader = (String)headImpl.getHeader(i + 0x30);
+                if (stringHeader != null) {
+                    out.write((byte)i + 0x30);
+                    value = ObexHelper.convertToUnicodeByteArray(stringHeader);
+                    length = value.length + 3;
+                    lengthArray[0] = (byte)(255 & (length >> 8));
+                    lengthArray[1] = (byte)(255 & length);
+                    out.write(lengthArray);
+                    out.write(value);
+                    if (nullOut) {
+                        headImpl.setHeader(i + 0x30, null);
+                    }
+                }
+
+                // Byte Sequence Header
+                value = (byte[])headImpl.getHeader(i + 0x70);
+                if (value != null) {
+                    out.write((byte)i + 0x70);
+                    length = value.length + 3;
+                    lengthArray[0] = (byte)(255 & (length >> 8));
+                    lengthArray[1] = (byte)(255 & length);
+                    out.write(lengthArray);
+                    out.write(value);
+                    if (nullOut) {
+                        headImpl.setHeader(i + 0x70, null);
+                    }
+                }
+
+                // Byte Header
+                byteHeader = (Byte)headImpl.getHeader(i + 0xB0);
+                if (byteHeader != null) {
+                    out.write((byte)i + 0xB0);
+                    out.write(byteHeader.byteValue());
+                    if (nullOut) {
+                        headImpl.setHeader(i + 0xB0, null);
+                    }
+                }
+
+                // Integer header
+                intHeader = (Long)headImpl.getHeader(i + 0xF0);
+                if (intHeader != null) {
+                    out.write((byte)i + 0xF0);
+                    out.write(ObexHelper.convertToByteArray(intHeader.longValue()));
+                    if (nullOut) {
+                        headImpl.setHeader(i + 0xF0, null);
+                    }
+                }
+            }
+
+            // Add the authentication challenge header
+            if (headImpl.mAuthChall != null) {
+                out.write((byte)HeaderSet.AUTH_CHALLENGE);
+                length = headImpl.mAuthChall.length + 3;
+                lengthArray[0] = (byte)(255 & (length >> 8));
+                lengthArray[1] = (byte)(255 & length);
+                out.write(lengthArray);
+                out.write(headImpl.mAuthChall);
+                if (nullOut) {
+                    headImpl.mAuthChall = null;
+                }
+            }
+
+            // Add the authentication response header
+            if (headImpl.mAuthResp != null) {
+                out.write((byte)HeaderSet.AUTH_RESPONSE);
+                length = headImpl.mAuthResp.length + 3;
+                lengthArray[0] = (byte)(255 & (length >> 8));
+                lengthArray[1] = (byte)(255 & length);
+                out.write(lengthArray);
+                out.write(headImpl.mAuthResp);
+                if (nullOut) {
+                    headImpl.mAuthResp = null;
+                }
+            }
+
+            // TODO:
+            // If the SRM and SRMP header is in use, they must be send in the same OBEX packet
+            // But the current structure of the obex code cannot handle this, and therefore
+            // it makes sense to put them in the tail of the headers, since we then reduce the
+            // chance of enabling SRM to soon. The down side is that SRM cannot be used while
+            // transferring non-body headers
+
+            // Add the SRM header
+            byteHeader = (Byte)headImpl.getHeader(HeaderSet.SINGLE_RESPONSE_MODE);
+            if (byteHeader != null) {
+                out.write((byte)HeaderSet.SINGLE_RESPONSE_MODE);
+                out.write(byteHeader.byteValue());
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, null);
+                }
+            }
+
+            // Add the SRM parameter header
+            byteHeader = (Byte)headImpl.getHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
+            if (byteHeader != null) {
+                out.write((byte)HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
+                out.write(byteHeader.byteValue());
+                if (nullOut) {
+                    headImpl.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, null);
+                }
+            }
+
+        } catch (IOException e) {
+        } finally {
+            result = out.toByteArray();
+            try {
+                out.close();
+            } catch (Exception ex) {
+            }
+        }
+
+        return result;
+
+    }
+
+    /**
+     * Determines where the maximum divide is between headers. This method is
+     * used by put and get operations to separate headers to a size that meets
+     * the max packet size allowed.
+     * @param headerArray the headers to separate
+     * @param start the starting index to search
+     * @param maxSize the maximum size of a packet
+     * @return the index of the end of the header block to send or -1 if the
+     *         header could not be divided because the header is too large
+     */
+    public static int findHeaderEnd(byte[] headerArray, int start, int maxSize) {
+
+        int fullLength = 0;
+        int lastLength = -1;
+        int index = start;
+        int length = 0;
+
+        // TODO: Ensure SRM and SRMP headers are not split into two OBEX packets
+
+        while ((fullLength < maxSize) && (index < headerArray.length)) {
+            int headerID = (headerArray[index] < 0 ? headerArray[index] + 256 : headerArray[index]);
+            lastLength = fullLength;
+
+            switch (headerID & (0xC0)) {
+
+                case 0x00:
+                    // Fall through
+                case 0x40:
+
+                    index++;
+                    length = (headerArray[index] < 0 ? headerArray[index] + 256
+                            : headerArray[index]);
+                    length = length << 8;
+                    index++;
+                    length += (headerArray[index] < 0 ? headerArray[index] + 256
+                            : headerArray[index]);
+                    length -= 3;
+                    index++;
+                    index += length;
+                    fullLength += length + 3;
+                    break;
+
+                case 0x80:
+
+                    index++;
+                    index++;
+                    fullLength += 2;
+                    break;
+
+                case 0xC0:
+
+                    index += 5;
+                    fullLength += 5;
+                    break;
+
+            }
+
+        }
+
+        /*
+         * Determine if this is the last header or not
+         */
+        if (lastLength == 0) {
+            /*
+             * Since this is the last header, check to see if the size of this
+             * header is less than maxSize.  If it is, return the length of the
+             * header, otherwise return -1.  The length of the header is
+             * returned since it would be the start of the next header
+             */
+            if (fullLength < maxSize) {
+                return headerArray.length;
+            } else {
+                return -1;
+            }
+        } else {
+            return lastLength + start;
+        }
+    }
+
+    /**
+     * Converts the byte array to a long.
+     * @param b the byte array to convert to a long
+     * @return the byte array as a long
+     */
+    public static long convertToLong(byte[] b) {
+        long result = 0;
+        long value = 0;
+        long power = 0;
+
+        for (int i = (b.length - 1); i >= 0; i--) {
+            value = b[i];
+            if (value < 0) {
+                value += 256;
+            }
+
+            result = result | (value << power);
+            power += 8;
+        }
+
+        return result;
+    }
+
+    /**
+     * Converts the long to a 4 byte array. The long must be non negative.
+     * @param l the long to convert
+     * @return a byte array that is the same as the long
+     */
+    public static byte[] convertToByteArray(long l) {
+        byte[] b = new byte[4];
+
+        b[0] = (byte)(255 & (l >> 24));
+        b[1] = (byte)(255 & (l >> 16));
+        b[2] = (byte)(255 & (l >> 8));
+        b[3] = (byte)(255 & l);
+
+        return b;
+    }
+
+    /**
+     * Converts the String to a UNICODE byte array. It will also add the ending
+     * null characters to the end of the string.
+     * @param s the string to convert
+     * @return the unicode byte array of the string
+     */
+    public static byte[] convertToUnicodeByteArray(String s) {
+        if (s == null) {
+            return null;
+        }
+
+        char c[] = s.toCharArray();
+        byte[] result = new byte[(c.length * 2) + 2];
+        for (int i = 0; i < c.length; i++) {
+            result[(i * 2)] = (byte)(c[i] >> 8);
+            result[((i * 2) + 1)] = (byte)c[i];
+        }
+
+        // Add the UNICODE null character
+        result[result.length - 2] = 0;
+        result[result.length - 1] = 0;
+
+        return result;
+    }
+
+    /**
+     * Retrieves the value from the byte array for the tag value specified. The
+     * array should be of the form Tag - Length - Value triplet.
+     * @param tag the tag to retrieve from the byte array
+     * @param triplet the byte sequence containing the tag length value form
+     * @return the value of the specified tag
+     */
+    public static byte[] getTagValue(byte tag, byte[] triplet) {
+
+        int index = findTag(tag, triplet);
+        if (index == -1) {
+            return null;
+        }
+
+        index++;
+        int length = triplet[index] & 0xFF;
+
+        byte[] result = new byte[length];
+        index++;
+        System.arraycopy(triplet, index, result, 0, length);
+
+        return result;
+    }
+
+    /**
+     * Finds the index that starts the tag value pair in the byte array provide.
+     * @param tag the tag to look for
+     * @param value the byte array to search
+     * @return the starting index of the tag or -1 if the tag could not be found
+     */
+    public static int findTag(byte tag, byte[] value) {
+        int length = 0;
+
+        if (value == null) {
+            return -1;
+        }
+
+        int index = 0;
+
+        while ((index < value.length) && (value[index] != tag)) {
+            length = value[index + 1] & 0xFF;
+            index += length + 2;
+        }
+
+        if (index >= value.length) {
+            return -1;
+        }
+
+        return index;
+    }
+
+    /**
+     * Converts the byte array provided to a unicode string.
+     * @param b the byte array to convert to a string
+     * @param includesNull determine if the byte string provided contains the
+     *        UNICODE null character at the end or not; if it does, it will be
+     *        removed
+     * @return a Unicode string
+     * @throws IllegalArgumentException if the byte array has an odd length
+     */
+    public static String convertToUnicode(byte[] b, boolean includesNull) {
+        if (b == null || b.length == 0) {
+            return null;
+        }
+        int arrayLength = b.length;
+        if (!((arrayLength % 2) == 0)) {
+            throw new IllegalArgumentException("Byte array not of a valid form");
+        }
+        arrayLength = (arrayLength >> 1);
+        if (includesNull) {
+            arrayLength -= 1;
+        }
+
+        char[] c = new char[arrayLength];
+        for (int i = 0; i < arrayLength; i++) {
+            int upper = b[2 * i];
+            int lower = b[(2 * i) + 1];
+            if (upper < 0) {
+                upper += 256;
+            }
+            if (lower < 0) {
+                lower += 256;
+            }
+            // If upper and lower both equal 0, it should be the end of string.
+            // Ignore left bytes from array to avoid potential issues
+            if (upper == 0 && lower == 0) {
+                return new String(c, 0, i);
+            }
+
+            c[i] = (char)((upper << 8) | lower);
+        }
+
+        return new String(c);
+    }
+
+    /**
+     * Compute the MD5 hash of the byte array provided. Does not accumulate
+     * input.
+     * @param in the byte array to hash
+     * @return the MD5 hash of the byte array
+     */
+    public static byte[] computeMd5Hash(byte[] in) {
+        try {
+            MessageDigest md5 = MessageDigest.getInstance("MD5");
+            return md5.digest(in);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Computes an authentication challenge header.
+     * @param nonce the challenge that will be provided to the peer; the
+     *        challenge must be 16 bytes long
+     * @param realm a short description that describes what password to use
+     * @param access if <code>true</code> then full access will be granted if
+     *        successful; if <code>false</code> then read only access will be
+     *        granted if successful
+     * @param userID if <code>true</code>, a user ID is required in the reply;
+     *        if <code>false</code>, no user ID is required
+     * @throws IllegalArgumentException if the challenge is not 16 bytes long;
+     *         if the realm can not be encoded in less than 255 bytes
+     * @throws IOException if the encoding scheme ISO 8859-1 is not supported
+     */
+    public static byte[] computeAuthenticationChallenge(byte[] nonce, String realm, boolean access,
+            boolean userID) throws IOException {
+        byte[] authChall = null;
+
+        if (nonce.length != 16) {
+            throw new IllegalArgumentException("Nonce must be 16 bytes long");
+        }
+
+        /*
+         * The authentication challenge is a byte sequence of the following form
+         * byte 0: 0x00 - the tag for the challenge
+         * byte 1: 0x10 - the length of the challenge; must be 16
+         * byte 2-17: the authentication challenge
+         * byte 18: 0x01 - the options tag; this is optional in the spec, but
+         *                 we are going to include it in every message
+         * byte 19: 0x01 - length of the options; must be 1
+         * byte 20: the value of the options; bit 0 is set if user ID is
+         *          required; bit 1 is set if access mode is read only
+         * byte 21: 0x02 - the tag for authentication realm; only included if
+         *                 an authentication realm is specified
+         * byte 22: the length of the authentication realm; only included if
+         *          the authentication realm is specified
+         * byte 23: the encoding scheme of the authentication realm; we will use
+         *          the ISO 8859-1 encoding scheme since it is part of the KVM
+         * byte 24 & up: the realm if one is specified.
+         */
+        if (realm == null) {
+            authChall = new byte[21];
+        } else {
+            if (realm.length() >= 255) {
+                throw new IllegalArgumentException("Realm must be less than 255 bytes");
+            }
+            authChall = new byte[24 + realm.length()];
+            authChall[21] = 0x02;
+            authChall[22] = (byte)(realm.length() + 1);
+            authChall[23] = 0x01; // ISO 8859-1 Encoding
+            System.arraycopy(realm.getBytes("ISO8859_1"), 0, authChall, 24, realm.length());
+        }
+
+        // Include the nonce field in the header
+        authChall[0] = 0x00;
+        authChall[1] = 0x10;
+        System.arraycopy(nonce, 0, authChall, 2, 16);
+
+        // Include the options header
+        authChall[18] = 0x01;
+        authChall[19] = 0x01;
+        authChall[20] = 0x00;
+
+        if (!access) {
+            authChall[20] = (byte)(authChall[20] | 0x02);
+        }
+        if (userID) {
+            authChall[20] = (byte)(authChall[20] | 0x01);
+        }
+
+        return authChall;
+    }
+
+    /**
+     * Return the maximum allowed OBEX packet to transmit.
+     * OBEX packets transmitted must be smaller than this value.
+     * @param transport Reference to the ObexTransport in use.
+     * @return the maximum allowed OBEX packet to transmit
+     */
+    public static int getMaxTxPacketSize(ObexTransport transport) {
+        int size = transport.getMaxTransmitPacketSize();
+        return validateMaxPacketSize(size);
+    }
+
+    /**
+     * Return the maximum allowed OBEX packet to receive - used in OBEX connect.
+     * @param transport
+     * @return the maximum allowed OBEX packet to receive
+     */
+    public static int getMaxRxPacketSize(ObexTransport transport) {
+        int size = transport.getMaxReceivePacketSize();
+        return validateMaxPacketSize(size);
+    }
+
+    private static int validateMaxPacketSize(int size) {
+        if (VDBG && (size > MAX_PACKET_SIZE_INT)) {
+            Log.w(TAG, "The packet size supported for the connection (" + size + ") is larger"
+                    + " than the configured OBEX packet size: " + MAX_PACKET_SIZE_INT);
+        }
+        if (size != -1 && size < MAX_PACKET_SIZE_INT) {
+            if (size < LOWER_LIMIT_MAX_PACKET_SIZE) {
+                throw new IllegalArgumentException(size + " is less that the lower limit: "
+                        + LOWER_LIMIT_MAX_PACKET_SIZE);
+            }
+            return size;
+        }
+        return MAX_PACKET_SIZE_INT;
+    }
+}
diff --git a/javax/obex/ObexPacket.java b/javax/obex/ObexPacket.java
new file mode 100644
index 0000000..bb6c96e
--- /dev/null
+++ b/javax/obex/ObexPacket.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015 The Android Open Source Project
+ * Copyright (c) 2015 Samsung LSI
+ *
+ * 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 javax.obex;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ObexPacket {
+    public int mHeaderId;
+    public int mLength;
+    public byte[] mPayload = null;
+
+    private ObexPacket(int headerId, int length) {
+        mHeaderId = headerId;
+        mLength = length;
+    }
+
+    /**
+     * Create a complete OBEX packet by reading data from an InputStream.
+     * @param is the input stream to read from.
+     * @return the OBEX packet read.
+     * @throws IOException if an IO exception occurs during read.
+     */
+    public static ObexPacket read(InputStream is) throws IOException {
+        int headerId = is.read();
+        return read(headerId, is);
+    }
+
+    /**
+     * Read the remainder of an OBEX packet, with a specified headerId.
+     * @param headerId the headerId already read from the stream.
+     * @param is the stream to read from, assuming 1 byte have already been read.
+     * @return the OBEX packet read.
+     * @throws IOException
+     */
+    public static ObexPacket read(int headerId, InputStream is) throws IOException {
+        // Read the 2 byte length field from the stream
+        int length = is.read();
+        length = (length << 8) + is.read();
+
+        ObexPacket newPacket = new ObexPacket(headerId, length);
+
+        int bytesReceived;
+        byte[] temp = null;
+        if (length > 3) {
+            // First three bytes already read, compensating for this
+            temp = new byte[length - 3];
+            bytesReceived = is.read(temp);
+            while (bytesReceived != temp.length) {
+                bytesReceived += is.read(temp, bytesReceived, temp.length - bytesReceived);
+            }
+        }
+        newPacket.mPayload = temp;
+        return newPacket;
+    }
+}
diff --git a/javax/obex/ObexSession.java b/javax/obex/ObexSession.java
new file mode 100644
index 0000000..373e573
--- /dev/null
+++ b/javax/obex/ObexSession.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import android.util.Log;
+
+import java.io.IOException;
+
+/**
+ * The <code>ObexSession</code> interface characterizes the term
+ * "OBEX Connection" as defined in the IrDA Object Exchange Protocol v1.2, which
+ * could be the server-side view of an OBEX connection, or the client-side view
+ * of the same connection, which is established by server's accepting of a
+ * client issued "CONNECT".
+ * <P>
+ * This interface serves as the common super class for
+ * <CODE>ClientSession</CODE> and <CODE>ServerSession</CODE>.
+ */
+public class ObexSession {
+
+    private static final String TAG = "ObexSession";
+    private static final boolean V = ObexHelper.VDBG;
+
+    protected Authenticator mAuthenticator;
+
+    protected byte[] mChallengeDigest;
+
+    /**
+     * Called when the server received an authentication challenge header. This
+     * will cause the authenticator to handle the authentication challenge.
+     * @param header the header with the authentication challenge
+     * @return <code>true</code> if the last request should be resent;
+     *         <code>false</code> if the last request should not be resent
+     * @throws IOException
+     */
+    public boolean handleAuthChall(HeaderSet header) throws IOException {
+        if (mAuthenticator == null) {
+            return false;
+        }
+
+        /*
+         * An authentication challenge is made up of one required and two
+         * optional tag length value triplets. The tag 0x00 is required to be in
+         * the authentication challenge and it represents the challenge digest
+         * that was received. The tag 0x01 is the options tag. This tag tracks
+         * if user ID is required and if full access will be granted. The tag
+         * 0x02 is the realm, which provides a description of which user name
+         * and password to use.
+         */
+        byte[] challenge = ObexHelper.getTagValue((byte)0x00, header.mAuthChall);
+        byte[] option = ObexHelper.getTagValue((byte)0x01, header.mAuthChall);
+        byte[] description = ObexHelper.getTagValue((byte)0x02, header.mAuthChall);
+
+        String realm = null;
+        if (description != null) {
+            byte[] realmString = new byte[description.length - 1];
+            System.arraycopy(description, 1, realmString, 0, realmString.length);
+
+            switch (description[0] & 0xFF) {
+
+                case ObexHelper.OBEX_AUTH_REALM_CHARSET_ASCII:
+                    // ASCII encoding
+                    // Fall through
+                case ObexHelper.OBEX_AUTH_REALM_CHARSET_ISO_8859_1:
+                    // ISO-8859-1 encoding
+                    try {
+                        realm = new String(realmString, "ISO8859_1");
+                    } catch (Exception e) {
+                        throw new IOException("Unsupported Encoding Scheme");
+                    }
+                    break;
+
+                case ObexHelper.OBEX_AUTH_REALM_CHARSET_UNICODE:
+                    // UNICODE Encoding
+                    realm = ObexHelper.convertToUnicode(realmString, false);
+                    break;
+
+                default:
+                    throw new IOException("Unsupported Encoding Scheme");
+            }
+        }
+
+        boolean isUserIDRequired = false;
+        boolean isFullAccess = true;
+        if (option != null) {
+            if ((option[0] & 0x01) != 0) {
+                isUserIDRequired = true;
+            }
+
+            if ((option[0] & 0x02) != 0) {
+                isFullAccess = false;
+            }
+        }
+
+        PasswordAuthentication result = null;
+        header.mAuthChall = null;
+
+        try {
+            result = mAuthenticator
+                    .onAuthenticationChallenge(realm, isUserIDRequired, isFullAccess);
+        } catch (Exception e) {
+            if (V) Log.d(TAG, "Exception occurred - returning false", e);
+            return false;
+        }
+
+        /*
+         * If no password is provided then we not resent the request
+         */
+        if (result == null) {
+            return false;
+        }
+
+        byte[] password = result.getPassword();
+        if (password == null) {
+            return false;
+        }
+
+        byte[] userName = result.getUserName();
+
+        /*
+         * Create the authentication response header. It includes 1 required and
+         * 2 option tag length value triples. The required triple has a tag of
+         * 0x00 and is the response digest. The first optional tag is 0x01 and
+         * represents the user ID. If no user ID is provided, then no user ID
+         * will be sent. The second optional tag is 0x02 and is the challenge
+         * that was received. This will always be sent
+         */
+        if (userName != null) {
+            header.mAuthResp = new byte[38 + userName.length];
+            header.mAuthResp[36] = (byte)0x01;
+            header.mAuthResp[37] = (byte)userName.length;
+            System.arraycopy(userName, 0, header.mAuthResp, 38, userName.length);
+        } else {
+            header.mAuthResp = new byte[36];
+        }
+
+        // Create the secret String
+        byte[] digest = new byte[challenge.length + password.length + 1];
+        System.arraycopy(challenge, 0, digest, 0, challenge.length);
+        // Insert colon between challenge and password
+        digest[challenge.length] = (byte)0x3A;
+        System.arraycopy(password, 0, digest, challenge.length + 1, password.length);
+
+        // Add the Response Digest
+        header.mAuthResp[0] = (byte)0x00;
+        header.mAuthResp[1] = (byte)0x10;
+
+        System.arraycopy(ObexHelper.computeMd5Hash(digest), 0, header.mAuthResp, 2, 16);
+
+        // Add the challenge
+        header.mAuthResp[18] = (byte)0x02;
+        header.mAuthResp[19] = (byte)0x10;
+        System.arraycopy(challenge, 0, header.mAuthResp, 20, 16);
+
+        return true;
+    }
+
+    /**
+     * Called when the server received an authentication response header. This
+     * will cause the authenticator to handle the authentication response.
+     * @param authResp the authentication response
+     * @return <code>true</code> if the response passed; <code>false</code> if
+     *         the response failed
+     */
+    public boolean handleAuthResp(byte[] authResp) {
+        if (mAuthenticator == null) {
+            return false;
+        }
+        // get the correct password from the application
+        byte[] correctPassword = mAuthenticator.onAuthenticationResponse(ObexHelper.getTagValue(
+                (byte)0x01, authResp));
+        if (correctPassword == null) {
+            return false;
+        }
+
+        byte[] temp = new byte[correctPassword.length + 16];
+
+        System.arraycopy(mChallengeDigest, 0, temp, 0, 16);
+        System.arraycopy(correctPassword, 0, temp, 16, correctPassword.length);
+
+        byte[] correctResponse = ObexHelper.computeMd5Hash(temp);
+        byte[] actualResponse = ObexHelper.getTagValue((byte)0x00, authResp);
+
+        // compare the MD5 hash array .
+        for (int i = 0; i < 16; i++) {
+            if (correctResponse[i] != actualResponse[i]) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/javax/obex/ObexTransport.java b/javax/obex/ObexTransport.java
new file mode 100644
index 0000000..cb16c17
--- /dev/null
+++ b/javax/obex/ObexTransport.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * The <code>ObexTransport</code> interface defines the underlying transport
+ * connection which carries the OBEX protocol( such as TCP, RFCOMM device file
+ * exposed by Bluetooth or USB in kernel, RFCOMM socket emulated in Android
+ * platform, Irda). This interface provides an abstract layer to be used by the
+ * <code>ObexConnection</code>. Each kind of medium shall have its own
+ * implementation to wrap and follow the same interface.
+ * <P>
+ * See section 1.2.2 of IrDA Object Exchange Protocol specification.
+ * <P>
+ * Different kind of medium may have different construction - for example, the
+ * RFCOMM device file medium may be constructed from a file descriptor or simply
+ * a string while the TCP medium usually from a socket.
+ */
+public interface ObexTransport {
+
+    void create() throws IOException;
+
+    void listen() throws IOException;
+
+    void close() throws IOException;
+
+    void connect() throws IOException;
+
+    void disconnect() throws IOException;
+
+    InputStream openInputStream() throws IOException;
+
+    OutputStream openOutputStream() throws IOException;
+
+    DataInputStream openDataInputStream() throws IOException;
+
+    DataOutputStream openDataOutputStream() throws IOException;
+
+    /**
+     * Must return the maximum allowed OBEX packet that can be sent over
+     * the transport. For L2CAP this will be the Max SDU reported by the
+     * peer device.
+     * The returned value will be used to set the outgoing OBEX packet
+     * size. Therefore this value shall not change.
+     * For RFCOMM or other transport types where the OBEX packets size
+     * is unrelated to the transport packet size, return -1;
+     * Exception can be made (like PBAP transport) with a smaller value
+     * to avoid bad effect on other profiles using the RFCOMM;
+     * @return the maximum allowed OBEX packet that can be send over
+     *         the transport. Or -1 in case of don't care.
+     */
+    int getMaxTransmitPacketSize();
+
+    /**
+     * Must return the maximum allowed OBEX packet that can be received over
+     * the transport. For L2CAP this will be the Max SDU configured for the
+     * L2CAP channel.
+     * The returned value will be used to validate the incoming packet size
+     * values.
+     * For RFCOMM or other transport types where the OBEX packets size
+     * is unrelated to the transport packet size, return -1;
+     * @return the maximum allowed OBEX packet that can be send over
+     *         the transport. Or -1 in case of don't care.
+     */
+    int getMaxReceivePacketSize();
+
+    /**
+     * Shall return true if the transport in use supports SRM.
+     * @return
+     *        <code>true</code> if SRM operation is supported, and is to be enabled.
+     *        <code>false</code> if SRM operations are not supported, or should not be used.
+     */
+    boolean isSrmSupported();
+
+
+}
diff --git a/javax/obex/Operation.java b/javax/obex/Operation.java
new file mode 100644
index 0000000..1f6c20a
--- /dev/null
+++ b/javax/obex/Operation.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * The <code>Operation</code> interface provides ways to manipulate a single
+ * OBEX PUT or GET operation. The implementation of this interface sends OBEX
+ * packets as they are built. If during the operation the peer in the operation
+ * ends the operation, an <code>IOException</code> is thrown on the next read
+ * from the input stream, write to the output stream, or call to
+ * <code>sendHeaders()</code>.
+ * <P>
+ * <STRONG>How Headers are Handled</STRONG>
+ * <P>
+ * As headers are received, they may be retrieved through the
+ * <code>getReceivedHeaders()</code> method. If new headers are set during the
+ * operation, the new headers will be sent during the next packet exchange.
+ * <P>
+ * <STRONG>PUT example</STRONG>
+ * <P>
+ * <PRE>
+ * void putObjectViaOBEX(ClientSession conn, HeaderSet head, byte[] obj) throws IOException {
+ *     // Include the length header
+ *     head.setHeader(head.LENGTH, new Long(obj.length));
+ *     // Initiate the PUT request
+ *     Operation op = conn.put(head);
+ *     // Open the output stream to put the object to it
+ *     DataOutputStream out = op.openDataOutputStream();
+ *     // Send the object to the server
+ *     out.write(obj);
+ *     // End the transaction
+ *     out.close();
+ *     op.close();
+ * }
+ * </PRE>
+ * <P>
+ * <STRONG>GET example</STRONG>
+ * <P>
+ * <PRE>
+ * byte[] getObjectViaOBEX(ClientSession conn, HeaderSet head) throws IOException {
+ *     // Send the initial GET request to the server
+ *     Operation op = conn.get(head);
+ *     // Retrieve the length of the object being sent back
+ *     int length = op.getLength();
+ *     // Create space for the object
+ *     byte[] obj = new byte[length];
+ *     // Get the object from the input stream
+ *     DataInputStream in = trans.openDataInputStream();
+ *     in.read(obj);
+ *     // End the transaction
+ *     in.close();
+ *     op.close();
+ *     return obj;
+ * }
+ * </PRE>
+ *
+ * <H3>Client PUT Operation Flow</H3> For PUT operations, a call to
+ * <code>close()</code> the <code>OutputStream</code> returned from
+ * <code>openOutputStream()</code> or <code>openDataOutputStream()</code> will
+ * signal that the request is done. (In OBEX terms, the End-Of-Body header
+ * should be sent and the final bit in the request will be set.) At this point,
+ * the reply from the server may begin to be processed. A call to
+ * <code>getResponseCode()</code> will do an implicit close on the
+ * <code>OutputStream</code> and therefore signal that the request is done.
+ * <H3>Client GET Operation Flow</H3> For GET operation, a call to
+ * <code>openInputStream()</code> or <code>openDataInputStream()</code> will
+ * signal that the request is done. (In OBEX terms, the final bit in the request
+ * will be set.) A call to <code>getResponseCode()</code> will cause an implicit
+ * close on the <code>InputStream</code>. No further data may be read at this
+ * point.
+ */
+public interface Operation {
+
+    /**
+     * Sends an ABORT message to the server. By calling this method, the
+     * corresponding input and output streams will be closed along with this
+     * object. No headers are sent in the abort request. This will end the
+     * operation since <code>close()</code> will be called by this method.
+     * @throws IOException if the transaction has already ended or if an OBEX
+     *         server calls this method
+     */
+    void abort() throws IOException;
+
+    /**
+     * Returns the headers that have been received during the operation.
+     * Modifying the object returned has no effect on the headers that are sent
+     * or retrieved.
+     * @return the headers received during this <code>Operation</code>
+     * @throws IOException if this <code>Operation</code> has been closed
+     */
+    HeaderSet getReceivedHeader() throws IOException;
+
+    /**
+     * Specifies the headers that should be sent in the next OBEX message that
+     * is sent.
+     * @param headers the headers to send in the next message
+     * @throws IOException if this <code>Operation</code> has been closed or the
+     *         transaction has ended and no further messages will be exchanged
+     * @throws IllegalArgumentException if <code>headers</code> was not created
+     *         by a call to <code>ServerRequestHandler.createHeaderSet()</code>
+     *         or <code>ClientSession.createHeaderSet()</code>
+     * @throws NullPointerException if <code>headers</code> if <code>null</code>
+     */
+    void sendHeaders(HeaderSet headers) throws IOException;
+
+    /**
+     * Returns the response code received from the server. Response codes are
+     * defined in the <code>ResponseCodes</code> class.
+     * @see ResponseCodes
+     * @return the response code retrieved from the server
+     * @throws IOException if an error occurred in the transport layer during
+     *         the transaction; if this object was created by an OBEX server
+     */
+    int getResponseCode() throws IOException;
+
+    int getHeaderLength();
+
+    InputStream openInputStream() throws IOException;
+
+    DataInputStream openDataInputStream() throws IOException;
+
+    OutputStream openOutputStream() throws IOException;
+
+    DataOutputStream openDataOutputStream() throws IOException;
+
+    void close() throws IOException;
+
+    int getMaxPacketSize();
+
+    public void noBodyHeader();
+}
diff --git a/javax/obex/PasswordAuthentication.java b/javax/obex/PasswordAuthentication.java
new file mode 100644
index 0000000..cb2303e
--- /dev/null
+++ b/javax/obex/PasswordAuthentication.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+/**
+ * This class holds user name and password combinations.
+ */
+public final class PasswordAuthentication {
+
+    private byte[] mUserName;
+
+    private final byte[] mPassword;
+
+    /**
+     * Creates a new <code>PasswordAuthentication</code> with the user name and
+     * password provided.
+     * @param userName the user name to include; this may be <code>null</code>
+     * @param password the password to include in the response
+     * @throws NullPointerException if <code>password</code> is
+     *         <code>null</code>
+     */
+    public PasswordAuthentication(final byte[] userName, final byte[] password) {
+        if (userName != null) {
+            mUserName = new byte[userName.length];
+            System.arraycopy(userName, 0, mUserName, 0, userName.length);
+        }
+
+        mPassword = new byte[password.length];
+        System.arraycopy(password, 0, mPassword, 0, password.length);
+    }
+
+    /**
+     * Retrieves the user name that was specified in the constructor. The user
+     * name may be <code>null</code>.
+     * @return the user name
+     *
+     * @hide
+     */
+    public byte[] getUserName() {
+        return mUserName;
+    }
+
+    /**
+     * Retrieves the password.
+     * @return the password
+     *
+     * @hide
+     */
+    public byte[] getPassword() {
+        return mPassword;
+    }
+}
diff --git a/javax/obex/PrivateInputStream.java b/javax/obex/PrivateInputStream.java
new file mode 100644
index 0000000..18219f9
--- /dev/null
+++ b/javax/obex/PrivateInputStream.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * This object provides an input stream to the Operation objects used in this
+ * package.
+ */
+public final class PrivateInputStream extends InputStream {
+
+    private BaseStream mParent;
+
+    private byte[] mData;
+
+    private int mIndex;
+
+    private boolean mOpen;
+
+    /**
+     * Creates an input stream for the <code>Operation</code> to read from
+     * @param p the connection this input stream is for
+     */
+    public PrivateInputStream(BaseStream p) {
+        mParent = p;
+        mData = new byte[0];
+        mIndex = 0;
+        mOpen = true;
+    }
+
+    /**
+     * Returns the number of bytes that can be read (or skipped over) from this
+     * input stream without blocking by the next caller of a method for this
+     * input stream. The next caller might be the same thread or or another
+     * thread.
+     * @return the number of bytes that can be read from this input stream
+     *         without blocking
+     * @throws IOException if an I/O error occurs
+     */
+    @Override
+    public synchronized int available() throws IOException {
+        ensureOpen();
+        return mData.length - mIndex;
+    }
+
+    /**
+     * Reads the next byte of data from the input stream. The value byte is
+     * returned as an int in the range 0 to 255. If no byte is available because
+     * the end of the stream has been reached, the value -1 is returned. This
+     * method blocks until input data is available, the end of the stream is
+     * detected, or an exception is thrown.
+     * @return the byte read from the input stream or -1 if it reaches the end of
+     *         stream
+     * @throws IOException if an I/O error occurs
+     */
+    @Override
+    public synchronized int read() throws IOException {
+        ensureOpen();
+        while (mData.length == mIndex) {
+            if (!mParent.continueOperation(true, true)) {
+                return -1;
+            }
+        }
+        return (mData[mIndex++] & 0xFF);
+    }
+
+    @Override
+    public int read(byte[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    @Override
+    public synchronized int read(byte[] b, int offset, int length) throws IOException {
+
+        if (b == null) {
+            throw new IOException("buffer is null");
+        }
+        if ((offset | length) < 0 || length > b.length - offset) {
+            throw new ArrayIndexOutOfBoundsException("index outof bound");
+        }
+        ensureOpen();
+
+        int currentDataLength = mData.length - mIndex;
+        int remainReadLength = length;
+        int offset1 = offset;
+        int result = 0;
+
+        while (currentDataLength <= remainReadLength) {
+            System.arraycopy(mData, mIndex, b, offset1, currentDataLength);
+            mIndex += currentDataLength;
+            offset1 += currentDataLength;
+            result += currentDataLength;
+            remainReadLength -= currentDataLength;
+
+            if (!mParent.continueOperation(true, true)) {
+                return result == 0 ? -1 : result;
+            }
+            currentDataLength = mData.length - mIndex;
+        }
+        if (remainReadLength > 0) {
+            System.arraycopy(mData, mIndex, b, offset1, remainReadLength);
+            mIndex += remainReadLength;
+            result += remainReadLength;
+        }
+        return result;
+    }
+
+    /**
+     * Allows the <code>OperationImpl</code> thread to add body data to the
+     * input stream.
+     * @param body the data to add to the stream
+     * @param start the start of the body to array to copy
+     */
+    public synchronized void writeBytes(byte[] body, int start) {
+
+        int length = (body.length - start) + (mData.length - mIndex);
+        byte[] temp = new byte[length];
+
+        System.arraycopy(mData, mIndex, temp, 0, mData.length - mIndex);
+        System.arraycopy(body, start, temp, mData.length - mIndex, body.length - start);
+
+        mData = temp;
+        mIndex = 0;
+        notifyAll();
+    }
+
+    /**
+     * Verifies that this stream is open
+     * @throws IOException if the stream is not open
+     */
+    private void ensureOpen() throws IOException {
+        mParent.ensureOpen();
+        if (!mOpen) {
+            throw new IOException("Input stream is closed");
+        }
+    }
+
+    /**
+     * Closes the input stream. If the input stream is already closed, do
+     * nothing.
+     * @throws IOException this will never happen
+     */
+    @Override
+    public void close() throws IOException {
+        mOpen = false;
+        mParent.streamClosed(true);
+    }
+}
diff --git a/javax/obex/PrivateOutputStream.java b/javax/obex/PrivateOutputStream.java
new file mode 100644
index 0000000..e8bfd1c
--- /dev/null
+++ b/javax/obex/PrivateOutputStream.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * This object provides an output stream to the Operation objects used in this
+ * package.
+ */
+public final class PrivateOutputStream extends OutputStream {
+
+    private BaseStream mParent;
+
+    private ByteArrayOutputStream mArray;
+
+    private boolean mOpen;
+
+    private int mMaxPacketSize;
+
+    /**
+     * Creates an empty <code>PrivateOutputStream</code> to write to.
+     * @param p the connection that this stream runs over
+     */
+    public PrivateOutputStream(BaseStream p, int maxSize) {
+        mParent = p;
+        mArray = new ByteArrayOutputStream();
+        mMaxPacketSize = maxSize;
+        mOpen = true;
+    }
+
+    /**
+     * Determines how many bytes have been written to the output stream.
+     * @return the number of bytes written to the output stream
+     */
+    public int size() {
+        return mArray.size();
+    }
+
+    /**
+     * Writes the specified byte to this output stream. The general contract for
+     * write is that one byte is written to the output stream. The byte to be
+     * written is the eight low-order bits of the argument b. The 24 high-order
+     * bits of b are ignored.
+     * @param b the byte to write
+     * @throws IOException if an I/O error occurs
+     */
+    @Override
+    public synchronized void write(int b) throws IOException {
+        ensureOpen();
+        mParent.ensureNotDone();
+        mArray.write(b);
+        if (mArray.size() == mMaxPacketSize) {
+            mParent.continueOperation(true, false);
+        }
+    }
+
+    @Override
+    public void write(byte[] buffer) throws IOException {
+        write(buffer, 0, buffer.length);
+    }
+
+    @Override
+    public synchronized void write(byte[] buffer, int offset, int count) throws IOException {
+        int offset1 = offset;
+        int remainLength = count;
+
+        if (buffer == null) {
+            throw new IOException("buffer is null");
+        }
+        if ((offset | count) < 0 || count > buffer.length - offset) {
+            throw new IndexOutOfBoundsException("index outof bound");
+        }
+
+        ensureOpen();
+        mParent.ensureNotDone();
+        while ((mArray.size() + remainLength) >= mMaxPacketSize) {
+            int bufferLeft = mMaxPacketSize - mArray.size();
+            mArray.write(buffer, offset1, bufferLeft);
+            offset1 += bufferLeft;
+            remainLength -= bufferLeft;
+            mParent.continueOperation(true, false);
+        }
+        if (remainLength > 0) {
+            mArray.write(buffer, offset1, remainLength);
+        }
+    }
+
+    /**
+     * Reads the bytes that have been written to this stream.
+     * @param size the size of the array to return
+     * @return the byte array that is written
+     */
+    public synchronized byte[] readBytes(int size) {
+        if (mArray.size() > 0) {
+            byte[] temp = mArray.toByteArray();
+            mArray.reset();
+            byte[] result = new byte[size];
+            System.arraycopy(temp, 0, result, 0, size);
+            if (temp.length != size) {
+                mArray.write(temp, size, temp.length - size);
+            }
+            return result;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Verifies that this stream is open
+     * @throws IOException if the stream is not open
+     */
+    private void ensureOpen() throws IOException {
+        mParent.ensureOpen();
+        if (!mOpen) {
+            throw new IOException("Output stream is closed");
+        }
+    }
+
+    /**
+     * Closes the output stream. If the input stream is already closed, do
+     * nothing.
+     * @throws IOException this will never happen
+     */
+    @Override
+    public void close() throws IOException {
+        mOpen = false;
+        mParent.streamClosed(false);
+    }
+
+    /**
+     * Determines if the connection is closed
+     * @return <code>true</code> if the connection is closed; <code>false</code>
+     *         if the connection is open
+     */
+    public boolean isClosed() {
+        return !mOpen;
+    }
+}
diff --git a/javax/obex/ResponseCodes.java b/javax/obex/ResponseCodes.java
new file mode 100644
index 0000000..a46490d
--- /dev/null
+++ b/javax/obex/ResponseCodes.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+/**
+ * The <code>ResponseCodes</code> class contains the list of valid response
+ * codes a server may send to a client.
+ * <P>
+ * <STRONG>IMPORTANT NOTE</STRONG>
+ * <P>
+ * The values in this interface represent the values defined in the IrOBEX
+ * specification, which is different with the HTTP specification.
+ * <P>
+ * <code>OBEX_DATABASE_FULL</code> and <code>OBEX_DATABASE_LOCKED</code> require
+ * further description since they are not defined in HTTP. The server will send
+ * an <code>OBEX_DATABASE_FULL</code> message when the client requests that
+ * something be placed into a database but the database is full (cannot take
+ * more data). <code>OBEX_DATABASE_LOCKED</code> will be returned when the
+ * client wishes to access a database, database table, or database record that
+ * has been locked.
+ */
+public final class ResponseCodes {
+
+    /**
+     * Defines the OBEX CONTINUE response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_CONTINUE</code> is 0x90 (144).
+     */
+    public static final int OBEX_HTTP_CONTINUE = 0x90;
+
+    /**
+     * Defines the OBEX SUCCESS response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_OK</code> is 0xA0 (160).
+     */
+    public static final int OBEX_HTTP_OK = 0xA0;
+
+    /**
+     * Defines the OBEX CREATED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_CREATED</code> is 0xA1 (161).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_CREATED = 0xA1;
+
+    /**
+     * Defines the OBEX ACCEPTED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_ACCEPTED</code> is 0xA2 (162).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_ACCEPTED = 0xA2;
+
+    /**
+     * Defines the OBEX NON-AUTHORITATIVE INFORMATION response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_NOT_AUTHORITATIVE</code> is 0xA3 (163).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_NOT_AUTHORITATIVE = 0xA3;
+
+    /**
+     * Defines the OBEX NO CONTENT response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_NO_CONTENT</code> is 0xA4 (164).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_NO_CONTENT = 0xA4;
+
+    /**
+     * Defines the OBEX RESET CONTENT response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_RESET</code> is 0xA5 (165).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_RESET = 0xA5;
+
+    /**
+     * Defines the OBEX PARTIAL CONTENT response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_PARTIAL</code> is 0xA6 (166).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_PARTIAL = 0xA6;
+
+    /**
+     * Defines the OBEX MULTIPLE_CHOICES response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_MULT_CHOICE</code> is 0xB0 (176).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_MULT_CHOICE = 0xB0;
+
+    /**
+     * Defines the OBEX MOVED PERMANENTLY response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_MOVED_PERM</code> is 0xB1 (177).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_MOVED_PERM = 0xB1;
+
+    /**
+     * Defines the OBEX MOVED TEMPORARILY response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_MOVED_TEMP</code> is 0xB2 (178).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_MOVED_TEMP = 0xB2;
+
+    /**
+     * Defines the OBEX SEE OTHER response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_SEE_OTHER</code> is 0xB3 (179).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_SEE_OTHER = 0xB3;
+
+    /**
+     * Defines the OBEX NOT MODIFIED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_NOT_MODIFIED</code> is 0xB4 (180).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_NOT_MODIFIED = 0xB4;
+
+    /**
+     * Defines the OBEX USE PROXY response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_USE_PROXY</code> is 0xB5 (181).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_USE_PROXY = 0xB5;
+
+    /**
+     * Defines the OBEX BAD REQUEST response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_BAD_REQUEST</code> is 0xC0 (192).
+     */
+    public static final int OBEX_HTTP_BAD_REQUEST = 0xC0;
+
+    /**
+     * Defines the OBEX UNAUTHORIZED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_UNAUTHORIZED</code> is 0xC1 (193).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_UNAUTHORIZED = 0xC1;
+
+    /**
+     * Defines the OBEX PAYMENT REQUIRED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_PAYMENT_REQUIRED</code> is 0xC2 (194).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_PAYMENT_REQUIRED = 0xC2;
+
+    /**
+     * Defines the OBEX FORBIDDEN response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_FORBIDDEN</code> is 0xC3 (195).
+     */
+    public static final int OBEX_HTTP_FORBIDDEN = 0xC3;
+
+    /**
+     * Defines the OBEX NOT FOUND response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_NOT_FOUND</code> is 0xC4 (196).
+     */
+    public static final int OBEX_HTTP_NOT_FOUND = 0xC4;
+
+    /**
+     * Defines the OBEX METHOD NOT ALLOWED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_BAD_METHOD</code> is 0xC5 (197).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_BAD_METHOD = 0xC5;
+
+    /**
+     * Defines the OBEX NOT ACCEPTABLE response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_NOT_ACCEPTABLE</code> is 0xC6 (198).
+     */
+    public static final int OBEX_HTTP_NOT_ACCEPTABLE = 0xC6;
+
+    /**
+     * Defines the OBEX PROXY AUTHENTICATION REQUIRED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_PROXY_AUTH</code> is 0xC7 (199).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_PROXY_AUTH = 0xC7;
+
+    /**
+     * Defines the OBEX REQUEST TIME OUT response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_TIMEOUT</code> is 0xC8 (200).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_TIMEOUT = 0xC8;
+
+    /**
+     * Defines the OBEX METHOD CONFLICT response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_CONFLICT</code> is 0xC9 (201).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_CONFLICT = 0xC9;
+
+    /**
+     * Defines the OBEX METHOD GONE response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_GONE</code> is 0xCA (202).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_GONE = 0xCA;
+
+    /**
+     * Defines the OBEX METHOD LENGTH REQUIRED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_LENGTH_REQUIRED</code> is 0xCB (203).
+     */
+    public static final int OBEX_HTTP_LENGTH_REQUIRED = 0xCB;
+
+    /**
+     * Defines the OBEX PRECONDITION FAILED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_PRECON_FAILED</code> is 0xCC (204).
+     */
+    public static final int OBEX_HTTP_PRECON_FAILED = 0xCC;
+
+    /**
+     * Defines the OBEX REQUESTED ENTITY TOO LARGE response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_ENTITY_TOO_LARGE</code> is 0xCD (205).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_ENTITY_TOO_LARGE = 0xCD;
+
+    /**
+     * Defines the OBEX REQUESTED URL TOO LARGE response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_REQ_TOO_LARGE</code> is 0xCE (206).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_REQ_TOO_LARGE = 0xCE;
+
+    /**
+     * Defines the OBEX UNSUPPORTED MEDIA TYPE response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_UNSUPPORTED_TYPE</code> is 0xCF (207).
+     */
+    public static final int OBEX_HTTP_UNSUPPORTED_TYPE = 0xCF;
+
+    /**
+     * Defines the OBEX INTERNAL SERVER ERROR response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_INTERNAL_ERROR</code> is 0xD0 (208).
+     */
+    public static final int OBEX_HTTP_INTERNAL_ERROR = 0xD0;
+
+    /**
+     * Defines the OBEX NOT IMPLEMENTED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_NOT_IMPLEMENTED</code> is 0xD1 (209).
+     */
+    public static final int OBEX_HTTP_NOT_IMPLEMENTED = 0xD1;
+
+    /**
+     * Defines the OBEX BAD GATEWAY response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_BAD_GATEWAY</code> is 0xD2 (210).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_BAD_GATEWAY = 0xD2;
+
+    /**
+     * Defines the OBEX SERVICE UNAVAILABLE response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_UNAVAILABLE</code> is 0xD3 (211).
+     */
+    public static final int OBEX_HTTP_UNAVAILABLE = 0xD3;
+
+    /**
+     * Defines the OBEX GATEWAY TIMEOUT response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_GATEWAY_TIMEOUT</code> is 0xD4 (212).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_GATEWAY_TIMEOUT = 0xD4;
+
+    /**
+     * Defines the OBEX HTTP VERSION NOT SUPPORTED response code.
+     * <P>
+     * The value of <code>OBEX_HTTP_VERSION</code> is 0xD5 (213).
+     *
+     * @hide
+     */
+    public static final int OBEX_HTTP_VERSION = 0xD5;
+
+    /**
+     * Defines the OBEX DATABASE FULL response code.
+     * <P>
+     * The value of <code>OBEX_DATABASE_FULL</code> is 0xE0 (224).
+     *
+     * @hide
+     */
+    public static final int OBEX_DATABASE_FULL = 0xE0;
+
+    /**
+     * Defines the OBEX DATABASE LOCKED response code.
+     * <P>
+     * The value of <code>OBEX_DATABASE_LOCKED</code> is 0xE1 (225).
+     *
+     * @hide
+     */
+    public static final int OBEX_DATABASE_LOCKED = 0xE1;
+
+    /**
+     * Constructor does nothing.
+     */
+    private ResponseCodes() {
+    }
+}
diff --git a/javax/obex/ServerOperation.java b/javax/obex/ServerOperation.java
new file mode 100644
index 0000000..4e77b6c
--- /dev/null
+++ b/javax/obex/ServerOperation.java
@@ -0,0 +1,868 @@
+/* Copyright (c) 2015 The Android Open Source Project
+ * Copyright (C) 2015 Samsung LSI
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * This class implements the Operation interface for server side connections.
+ * <P>
+ * <STRONG>Request Codes</STRONG> There are four different request codes that
+ * are in this class. 0x02 is a PUT request that signals that the request is not
+ * complete and requires an additional OBEX packet. 0x82 is a PUT request that
+ * says that request is complete. In this case, the server can begin sending the
+ * response. The 0x03 is a GET request that signals that the request is not
+ * finished. When the server receives a 0x83, the client is signaling the server
+ * that it is done with its request. TODO: Extend the ClientOperation and reuse
+ * the methods defined TODO: in that class.
+ */
+public final class ServerOperation implements Operation, BaseStream {
+
+    private static final String TAG = "ServerOperation";
+
+    private static final boolean V = ObexHelper.VDBG; // Verbose debugging
+
+    private boolean mAborted;
+
+    /** @hide */
+    public HeaderSet requestHeader;
+
+    /** @hide */
+    public HeaderSet replyHeader;
+
+    /** @hide */
+    public boolean finalBitSet;
+
+    private InputStream mInput;
+
+    private ServerSession mParent;
+
+    private int mMaxPacketLength;
+
+    private int mResponseSize;
+
+    private boolean mClosed;
+
+    private boolean mGetOperation;
+
+    private PrivateInputStream mPrivateInput;
+
+    private PrivateOutputStream mPrivateOutput;
+
+    private ObexTransport mTransport;
+
+    private boolean mPrivateOutputOpen;
+
+    private String mExceptionString;
+
+    private ServerRequestHandler mListener;
+
+    private boolean mRequestFinished;
+
+    private boolean mHasBody;
+
+    private boolean mSendBodyHeader = true;
+    // Assume SRM disabled - needs to be explicit
+    // enabled by client
+    private boolean mSrmEnabled = false;
+    // A latch - when triggered, there is not way back ;-)
+    private boolean mSrmActive = false;
+    // Set to true when a SRM enable response have been send
+    private boolean mSrmResponseSent = false;
+    // keep waiting until final-bit is received in request
+    // to handle the case where the SRM enable header is in
+    // a different OBEX packet than the SRMP header.
+    private boolean mSrmWaitingForRemote = true;
+    // Why should we wait? - currently not exposed to apps.
+    private boolean mSrmLocalWait = false;
+
+    /**
+     * Creates new ServerOperation
+     * @param p the parent that created this object
+     * @param in the input stream to read from
+     * @param request the initial request that was received from the client
+     * @param maxSize the max packet size that the client will accept
+     * @param listen the listener that is responding to the request
+     * @throws IOException if an IO error occurs
+     *
+     * @hide
+     */
+    public ServerOperation(ServerSession p, InputStream in, int request, int maxSize,
+            ServerRequestHandler listen) throws IOException {
+
+        mAborted = false;
+        mParent = p;
+        mInput = in;
+        mMaxPacketLength = maxSize;
+        mClosed = false;
+        requestHeader = new HeaderSet();
+        replyHeader = new HeaderSet();
+        mPrivateInput = new PrivateInputStream(this);
+        mResponseSize = 3;
+        mListener = listen;
+        mRequestFinished = false;
+        mPrivateOutputOpen = false;
+        mHasBody = false;
+        ObexPacket packet;
+        mTransport = p.getTransport();
+
+        /*
+         * Determine if this is a PUT request
+         */
+        if ((request == ObexHelper.OBEX_OPCODE_PUT) ||
+                (request == ObexHelper.OBEX_OPCODE_PUT_FINAL)) {
+            /*
+             * It is a PUT request.
+             */
+            mGetOperation = false;
+
+            /*
+             * Determine if the final bit is set
+             */
+            if ((request & ObexHelper.OBEX_OPCODE_FINAL_BIT_MASK) == 0) {
+                finalBitSet = false;
+            } else {
+                finalBitSet = true;
+                mRequestFinished = true;
+            }
+        } else if ((request == ObexHelper.OBEX_OPCODE_GET) ||
+                (request == ObexHelper.OBEX_OPCODE_GET_FINAL)) {
+            /*
+             * It is a GET request.
+             */
+            mGetOperation = true;
+
+            // For Get request, final bit set is decided by server side logic
+            finalBitSet = false;
+
+            if (request == ObexHelper.OBEX_OPCODE_GET_FINAL) {
+                mRequestFinished = true;
+            }
+        } else {
+            throw new IOException("ServerOperation can not handle such request");
+        }
+
+        packet = ObexPacket.read(request, mInput);
+
+        /*
+         * Determine if the packet length is larger than this device can receive
+         */
+        if (packet.mLength > ObexHelper.getMaxRxPacketSize(mTransport)) {
+            mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null);
+            throw new IOException("Packet received was too large. Length: "
+                    + packet.mLength + " maxLength: " + ObexHelper.getMaxRxPacketSize(mTransport));
+        }
+
+        /*
+         * Determine if any headers were sent in the initial request
+         */
+        if (packet.mLength > 3) {
+            if(!handleObexPacket(packet)) {
+                return;
+            }
+            /* Don't Pre-Send continue when Remote requested for SRM
+             * Let the Application confirm.
+             */
+            if (V) Log.v(TAG, "Get App confirmation if SRM ENABLED case: " + mSrmEnabled
+                    + " not hasBody case: " + mHasBody);
+            if (!mHasBody && !mSrmEnabled) {
+                while ((!mGetOperation) && (!finalBitSet)) {
+                    sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
+                    if (mPrivateInput.available() > 0) {
+                        break;
+                    }
+                }
+            }
+        }
+        /* Don't Pre-Send continue when Remote requested for SRM
+          * Let the Application confirm.
+          */
+        if (V) Log.v(TAG, "Get App confirmation if SRM ENABLED case: " + mSrmEnabled
+            + " not finalPacket: " + finalBitSet + " not GETOp Case: " + mGetOperation);
+        while ((!mSrmEnabled) && (!mGetOperation) && (!finalBitSet)
+                && (mPrivateInput.available() == 0)) {
+            sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
+            if (mPrivateInput.available() > 0) {
+                break;
+            }
+        }
+
+        // wait for get request finished !!!!
+        while (mGetOperation && !mRequestFinished) {
+            sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
+        }
+    }
+
+    /**
+     * Parse headers and update member variables
+     * @param packet the received obex packet
+     * @return false for failing authentication - and a OBEX_HTTP_UNAUTHORIZED
+     * response have been send. Else true.
+     * @throws IOException
+     */
+    private boolean handleObexPacket(ObexPacket packet) throws IOException {
+        byte[] body = updateRequestHeaders(packet);
+
+        if (body != null) {
+            mHasBody = true;
+        }
+        if (mListener.getConnectionId() != -1 && requestHeader.mConnectionID != null) {
+            mListener.setConnectionId(ObexHelper
+                    .convertToLong(requestHeader.mConnectionID));
+        } else {
+            mListener.setConnectionId(1);
+        }
+
+        if (requestHeader.mAuthResp != null) {
+            if (!mParent.handleAuthResp(requestHeader.mAuthResp)) {
+                mExceptionString = "Authentication Failed";
+                mParent.sendResponse(ResponseCodes.OBEX_HTTP_UNAUTHORIZED, null);
+                mClosed = true;
+                requestHeader.mAuthResp = null;
+                return false;
+            }
+            requestHeader.mAuthResp = null;
+        }
+
+        if (requestHeader.mAuthChall != null) {
+            mParent.handleAuthChall(requestHeader);
+            // send the auhtResp to the client
+            replyHeader.mAuthResp = new byte[requestHeader.mAuthResp.length];
+            System.arraycopy(requestHeader.mAuthResp, 0, replyHeader.mAuthResp, 0,
+                    replyHeader.mAuthResp.length);
+            requestHeader.mAuthResp = null;
+            requestHeader.mAuthChall = null;
+        }
+
+        if (body != null) {
+            mPrivateInput.writeBytes(body, 1);
+        }
+        return true;
+    }
+
+    /**
+     * Update the request header set, and sniff on SRM headers to update local state.
+     * @param data the OBEX packet data
+     * @return any bytes in a body/end-of-body header returned by {@link ObexHelper.updateHeaderSet}
+     * @throws IOException
+     */
+    private byte[] updateRequestHeaders(ObexPacket packet) throws IOException {
+        byte[] body = null;
+        if (packet.mPayload != null) {
+            body = ObexHelper.updateHeaderSet(requestHeader, packet.mPayload);
+        }
+        Byte srmMode = (Byte)requestHeader.getHeader(HeaderSet.SINGLE_RESPONSE_MODE);
+        if(mTransport.isSrmSupported() && srmMode != null
+                && srmMode == ObexHelper.OBEX_SRM_ENABLE) {
+            mSrmEnabled = true;
+            if(V) Log.d(TAG,"SRM is now ENABLED (but not active) for this operation");
+        }
+        checkForSrmWait(packet.mHeaderId);
+        if((!mSrmWaitingForRemote) && (mSrmEnabled)) {
+            if(V) Log.d(TAG,"SRM is now ACTIVE for this operation");
+            mSrmActive = true;
+        }
+        return body;
+    }
+
+    /**
+     * Call this only when a complete request have been received.
+     * (This is not optimal, but the current design is not really suited to
+     * the way SRM is specified.)
+     */
+    private void checkForSrmWait(int headerId){
+        if (mSrmEnabled && (headerId == ObexHelper.OBEX_OPCODE_GET
+                || headerId == ObexHelper.OBEX_OPCODE_GET_FINAL
+                || headerId == ObexHelper.OBEX_OPCODE_PUT)) {
+            try {
+                mSrmWaitingForRemote = false;
+                Byte srmp = (Byte)requestHeader.getHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER);
+                if(srmp != null && srmp == ObexHelper.OBEX_SRMP_WAIT) {
+                    mSrmWaitingForRemote = true;
+                    // Clear the wait header, as the absents of the header when the final bit is set
+                    // indicates don't wait.
+                    requestHeader.setHeader(HeaderSet.SINGLE_RESPONSE_MODE_PARAMETER, null);
+                }
+            } catch (IOException e) {if(V){Log.w(TAG,"Exception while extracting header",e);}}
+        }
+    }
+
+    /** @hide */
+    public boolean isValidBody() {
+        return mHasBody;
+    }
+
+    /**
+     * Determines if the operation should continue or should wait. If it should
+     * continue, this method will continue the operation.
+     * @param sendEmpty if <code>true</code> then this will continue the
+     *        operation even if no headers will be sent; if <code>false</code>
+     *        then this method will only continue the operation if there are
+     *        headers to send
+     * @param inStream if<code>true</code> the stream is input stream, otherwise
+     *        output stream
+     * @return <code>true</code> if the operation was completed;
+     *         <code>false</code> if no operation took place
+     *
+     * @hide
+     */
+    public synchronized boolean continueOperation(boolean sendEmpty, boolean inStream)
+            throws IOException {
+        if (!mGetOperation) {
+            if (!finalBitSet) {
+                if (sendEmpty) {
+                    sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
+                    return true;
+                } else {
+                    if ((mResponseSize > 3) || (mPrivateOutput.size() > 0)) {
+                        sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+            } else {
+                return false;
+            }
+        } else {
+            sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
+            return true;
+        }
+    }
+
+    /**
+     * Sends a reply to the client. If the reply is a OBEX_HTTP_CONTINUE, it
+     * will wait for a response from the client before ending unless SRM is active.
+     * @param type the response code to send back to the client
+     * @return <code>true</code> if the final bit was not set on the reply;
+     *         <code>false</code> if no reply was received because the operation
+     *         ended, an abort was received, the final bit was set in the
+     *         reply or SRM is active.
+     * @throws IOException if an IO error occurs
+     *
+     * @hide
+     */
+    public synchronized boolean sendReply(int type) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        boolean skipSend = false;
+        boolean skipReceive = false;
+        boolean srmRespSendPending = false;
+
+        long id = mListener.getConnectionId();
+        if (id == -1) {
+            replyHeader.mConnectionID = null;
+        } else {
+            replyHeader.mConnectionID = ObexHelper.convertToByteArray(id);
+        }
+
+        if(mSrmEnabled && !mSrmResponseSent) {
+            // As we are not ensured that the SRM enable is in the first OBEX packet
+            // We must check for each reply.
+            if(V)Log.v(TAG, "mSrmEnabled==true, sending SRM enable response.");
+            replyHeader.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, (byte)ObexHelper.OBEX_SRM_ENABLE);
+            srmRespSendPending = true;
+        }
+
+        if(mSrmEnabled && !mGetOperation && mSrmLocalWait) {
+            replyHeader.setHeader(HeaderSet.SINGLE_RESPONSE_MODE, (byte)ObexHelper.OBEX_SRMP_WAIT);
+        }
+
+        byte[] headerArray = ObexHelper.createHeader(replyHeader, true); // This clears the headers
+        int bodyLength = -1;
+        int originalBodyLength = -1;
+
+        if (mPrivateOutput != null) {
+            bodyLength = mPrivateOutput.size();
+            originalBodyLength = bodyLength;
+        }
+
+        if ((ObexHelper.BASE_PACKET_LENGTH + headerArray.length) > mMaxPacketLength) {
+
+            int end = 0;
+            int start = 0;
+
+            while (end != headerArray.length) {
+                end = ObexHelper.findHeaderEnd(headerArray, start, mMaxPacketLength
+                        - ObexHelper.BASE_PACKET_LENGTH);
+                if (end == -1) {
+
+                    mClosed = true;
+
+                    if (mPrivateInput != null) {
+                        mPrivateInput.close();
+                    }
+
+                    if (mPrivateOutput != null) {
+                        mPrivateOutput.close();
+                    }
+                    mParent.sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
+                    throw new IOException("OBEX Packet exceeds max packet size");
+                }
+                byte[] sendHeader = new byte[end - start];
+                System.arraycopy(headerArray, start, sendHeader, 0, sendHeader.length);
+
+                mParent.sendResponse(type, sendHeader);
+                start = end;
+            }
+
+            if (bodyLength > 0) {
+                return true;
+            } else {
+                return false;
+            }
+
+        } else {
+            out.write(headerArray);
+        }
+
+        // For Get operation: if response code is OBEX_HTTP_OK, then this is the
+        // last packet; so set finalBitSet to true.
+        if (mGetOperation && type == ResponseCodes.OBEX_HTTP_OK) {
+            finalBitSet = true;
+        }
+
+        if(mSrmActive) {
+            if(!mGetOperation && type == ResponseCodes.OBEX_HTTP_CONTINUE &&
+                    mSrmResponseSent == true) {
+                // we are in the middle of a SRM PUT operation, don't send a continue.
+                skipSend = true;
+            } else if(mGetOperation && mRequestFinished == false && mSrmResponseSent == true) {
+                // We are still receiving the get request, receive, but don't send continue.
+                skipSend = true;
+            } else if(mGetOperation && mRequestFinished == true) {
+                // All done receiving the GET request, send data to the client, without
+                // expecting a continue.
+                skipReceive = true;
+            }
+            if(V)Log.v(TAG, "type==" + type + " skipSend==" + skipSend
+                    + " skipReceive==" + skipReceive);
+        }
+        if(srmRespSendPending) {
+            if(V)Log.v(TAG,
+                    "SRM Enabled (srmRespSendPending == true)- sending SRM Enable response");
+            mSrmResponseSent = true;
+        }
+
+        if ((finalBitSet) || (headerArray.length < (mMaxPacketLength - 20))) {
+            if (bodyLength > 0) {
+                /*
+                 * Determine if I can send the whole body or just part of
+                 * the body.  Remember that there is the 3 bytes for the
+                 * response message and 3 bytes for the header ID and length
+                 */
+                if (bodyLength > (mMaxPacketLength - headerArray.length - 6)) {
+                    bodyLength = mMaxPacketLength - headerArray.length - 6;
+                }
+
+                byte[] body = mPrivateOutput.readBytes(bodyLength);
+
+                /*
+                 * Since this is a put request if the final bit is set or
+                 * the output stream is closed we need to send the 0x49
+                 * (End of Body) otherwise, we need to send 0x48 (Body)
+                 */
+                if ((finalBitSet) || (mPrivateOutput.isClosed())) {
+                    if(mSendBodyHeader == true) {
+                        out.write(0x49);
+                        bodyLength += 3;
+                        out.write((byte)(bodyLength >> 8));
+                        out.write((byte)bodyLength);
+                        out.write(body);
+                    }
+                } else {
+                    if(mSendBodyHeader == true) {
+                    out.write(0x48);
+                    bodyLength += 3;
+                    out.write((byte)(bodyLength >> 8));
+                    out.write((byte)bodyLength);
+                    out.write(body);
+                    }
+                }
+
+            }
+        }
+
+        if ((finalBitSet) && (type == ResponseCodes.OBEX_HTTP_OK) && (originalBodyLength <= 0)) {
+            if(mSendBodyHeader) {
+                out.write(0x49);
+                originalBodyLength = 3;
+                out.write((byte)(originalBodyLength >> 8));
+                out.write((byte)originalBodyLength);
+            }
+        }
+
+        if(skipSend == false) {
+            mResponseSize = 3;
+            mParent.sendResponse(type, out.toByteArray());
+        }
+
+        if (type == ResponseCodes.OBEX_HTTP_CONTINUE) {
+
+            if(mGetOperation && skipReceive) {
+                // Here we need to check for and handle abort (throw an exception).
+                // Any other signal received should be discarded silently (only on server side)
+                checkSrmRemoteAbort();
+            } else {
+                // Receive and handle data (only send reply if !skipSend)
+                // Read a complete OBEX Packet
+                ObexPacket packet = ObexPacket.read(mInput);
+
+                int headerId = packet.mHeaderId;
+                if ((headerId != ObexHelper.OBEX_OPCODE_PUT)
+                        && (headerId != ObexHelper.OBEX_OPCODE_PUT_FINAL)
+                        && (headerId != ObexHelper.OBEX_OPCODE_GET)
+                        && (headerId != ObexHelper.OBEX_OPCODE_GET_FINAL)) {
+
+                    /*
+                     * Determine if an ABORT was sent as the reply
+                     */
+                    if (headerId == ObexHelper.OBEX_OPCODE_ABORT) {
+                        handleRemoteAbort();
+                    } else {
+                        // TODO:shall we send this if it occurs during SRM? Errata on the subject
+                        mParent.sendResponse(ResponseCodes.OBEX_HTTP_BAD_REQUEST, null);
+                        mClosed = true;
+                        mExceptionString = "Bad Request Received";
+                        throw new IOException("Bad Request Received");
+                    }
+                } else {
+
+                    if ((headerId == ObexHelper.OBEX_OPCODE_PUT_FINAL)) {
+                        finalBitSet = true;
+                    } else if (headerId == ObexHelper.OBEX_OPCODE_GET_FINAL) {
+                        mRequestFinished = true;
+                    }
+
+                    /*
+                     * Determine if the packet length is larger than the negotiated packet size
+                     */
+                    if (packet.mLength > ObexHelper.getMaxRxPacketSize(mTransport)) {
+                        mParent.sendResponse(ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE, null);
+                        throw new IOException("Packet received was too large");
+                    }
+
+                    /*
+                     * Determine if any headers were sent in the initial request
+                     */
+                    if (packet.mLength > 3 || (mSrmEnabled && packet.mLength == 3)) {
+                        if(handleObexPacket(packet) == false) {
+                            return false;
+                        }
+                    }
+                }
+
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * This method will look for an abort from the peer during a SRM transfer.
+     * The function will not block if no data has been received from the remote device.
+     * If data have been received, the function will block while reading the incoming
+     * OBEX package.
+     * An Abort request will be handled, and cause an IOException("Abort Received").
+     * Other messages will be discarded silently as per GOEP specification.
+     * @throws IOException if an abort request have been received.
+     * TODO: I think this is an error in the specification. If we discard other messages,
+     *       the peer device will most likely stall, as it will not receive the expected
+     *       response for the message...
+     *       I'm not sure how to understand "Receipt of invalid or unexpected SRM or SRMP
+     *       header values shall be ignored by the receiving device."
+     *       If any signal is received during an active SRM transfer it is unexpected regardless
+     *       whether or not it contains SRM/SRMP headers...
+     */
+    private void checkSrmRemoteAbort() throws IOException {
+        if(mInput.available() > 0) {
+            ObexPacket packet = ObexPacket.read(mInput);
+            /*
+             * Determine if an ABORT was sent as the reply
+             */
+            if (packet.mHeaderId == ObexHelper.OBEX_OPCODE_ABORT) {
+                handleRemoteAbort();
+            } else {
+                // TODO: should we throw an exception here anyway? - don't see how to
+                //       ignore SRM/SRMP headers without ignoring the complete signal
+                //       (in this particular case).
+                Log.w(TAG, "Received unexpected request from client - discarding...\n"
+                        + "   headerId: " + packet.mHeaderId + " length: " + packet.mLength);
+            }
+        }
+    }
+
+    private void handleRemoteAbort() throws IOException {
+        /* TODO: To increase the speed of the abort operation in SRM, we need
+         *       to be able to flush the L2CAP queue for the PSM in use.
+         *       This could be implemented by introducing a control
+         *       message to be send over the socket, that in the abort case
+         *       could carry a flush command. */
+        mParent.sendResponse(ResponseCodes.OBEX_HTTP_OK, null);
+        mClosed = true;
+        mAborted = true;
+        mExceptionString = "Abort Received";
+        throw new IOException("Abort Received");
+    }
+
+    /**
+     * Sends an ABORT message to the server. By calling this method, the
+     * corresponding input and output streams will be closed along with this
+     * object.
+     * @throws IOException if the transaction has already ended or if an OBEX
+     *         server called this method
+     *
+     * @hide
+     */
+    public void abort() throws IOException {
+        throw new IOException("Called from a server");
+    }
+
+    /**
+     * Returns the headers that have been received during the operation.
+     * Modifying the object returned has no effect on the headers that are sent
+     * or retrieved.
+     * @return the headers received during this <code>Operation</code>
+     * @throws IOException if this <code>Operation</code> has been closed
+     *
+     * @hide
+     */
+    public HeaderSet getReceivedHeader() throws IOException {
+        ensureOpen();
+        return requestHeader;
+    }
+
+    /**
+     * Specifies the headers that should be sent in the next OBEX message that
+     * is sent.
+     * @param headers the headers to send in the next message
+     * @throws IOException if this <code>Operation</code> has been closed or the
+     *         transaction has ended and no further messages will be exchanged
+     * @throws IllegalArgumentException if <code>headers</code> was not created
+     *         by a call to <code>ServerRequestHandler.createHeaderSet()</code>
+     *
+     * @hide
+     */
+    public void sendHeaders(HeaderSet headers) throws IOException {
+        ensureOpen();
+
+        if (headers == null) {
+            throw new IOException("Headers may not be null");
+        }
+
+        int[] headerList = headers.getHeaderList();
+        if (headerList != null) {
+            for (int i = 0; i < headerList.length; i++) {
+                replyHeader.setHeader(headerList[i], headers.getHeader(headerList[i]));
+            }
+
+        }
+    }
+
+    /**
+     * Retrieves the response code retrieved from the server. Response codes are
+     * defined in the <code>ResponseCodes</code> interface.
+     * @return the response code retrieved from the server
+     * @throws IOException if an error occurred in the transport layer during
+     *         the transaction; if this method is called on a
+     *         <code>HeaderSet</code> object created by calling
+     *         <code>createHeaderSet</code> in a <code>ClientSession</code>
+     *         object; if this is called from a server
+     *
+     * @hide
+     */
+    public int getResponseCode() throws IOException {
+        throw new IOException("Called from a server");
+    }
+
+    /** @hide */
+    public int getMaxPacketSize() {
+        return mMaxPacketLength - 6 - getHeaderLength();
+    }
+
+    /** @hide */
+    public int getHeaderLength() {
+        long id = mListener.getConnectionId();
+        if (id == -1) {
+            replyHeader.mConnectionID = null;
+        } else {
+            replyHeader.mConnectionID = ObexHelper.convertToByteArray(id);
+        }
+
+        byte[] headerArray = ObexHelper.createHeader(replyHeader, false);
+
+        return headerArray.length;
+    }
+
+    /**
+     * Open and return an input stream for a connection.
+     * @return an input stream
+     * @throws IOException if an I/O error occurs
+     *
+     * @hide
+     */
+    public InputStream openInputStream() throws IOException {
+        ensureOpen();
+        return mPrivateInput;
+    }
+
+    /**
+     * Open and return a data input stream for a connection.
+     * @return an input stream
+     * @throws IOException if an I/O error occurs
+     *
+     * @hide
+     */
+    public DataInputStream openDataInputStream() throws IOException {
+        return new DataInputStream(openInputStream());
+    }
+
+    /**
+     * Open and return an output stream for a connection.
+     * @return an output stream
+     * @throws IOException if an I/O error occurs
+     *
+     * @hide
+     */
+    public OutputStream openOutputStream() throws IOException {
+        ensureOpen();
+
+        if (mPrivateOutputOpen) {
+            throw new IOException("no more input streams available, stream already opened");
+        }
+
+        if (!mRequestFinished) {
+            throw new IOException("no  output streams available ,request not finished");
+        }
+
+        if (mPrivateOutput == null) {
+            mPrivateOutput = new PrivateOutputStream(this, getMaxPacketSize());
+        }
+        mPrivateOutputOpen = true;
+        return mPrivateOutput;
+    }
+
+    /**
+     * Open and return a data output stream for a connection.
+     * @return an output stream
+     * @throws IOException if an I/O error occurs
+     *
+     * @hide
+     */
+    public DataOutputStream openDataOutputStream() throws IOException {
+        return new DataOutputStream(openOutputStream());
+    }
+
+    /**
+     * Closes the connection and ends the transaction
+     * @throws IOException if the operation has already ended or is closed
+     *
+     * @hide
+     */
+    public void close() throws IOException {
+        ensureOpen();
+        mClosed = true;
+    }
+
+    /**
+     * Verifies that the connection is open and no exceptions should be thrown.
+     * @throws IOException if an exception needs to be thrown
+     *
+     * @hide
+     */
+    public void ensureOpen() throws IOException {
+        if (mExceptionString != null) {
+            throw new IOException(mExceptionString);
+        }
+        if (mClosed) {
+            throw new IOException("Operation has already ended");
+        }
+    }
+
+    /**
+     * Verifies that additional information may be sent. In other words, the
+     * operation is not done.
+     * <P>
+     * Included to implement the BaseStream interface only. It does not do
+     * anything on the server side since the operation of the Operation object
+     * is not done until after the handler returns from its method.
+     * @throws IOException if the operation is completed
+     *
+     * @hide
+     */
+    public void ensureNotDone() throws IOException {
+    }
+
+    /**
+     * Called when the output or input stream is closed. It does not do anything
+     * on the server side since the operation of the Operation object is not
+     * done until after the handler returns from its method.
+     * @param inStream <code>true</code> if the input stream is closed;
+     *        <code>false</code> if the output stream is closed
+     * @throws IOException if an IO error occurs
+     *
+     * @hide
+     */
+    public void streamClosed(boolean inStream) throws IOException {
+
+    }
+
+    /** @hide */
+    public void noBodyHeader(){
+        mSendBodyHeader = false;
+    }
+
+    /**
+     * Returns whether the operation is aborted.
+     */
+    public boolean isAborted() {
+        return mAborted;
+    }
+
+    /**
+     * Set whether the operation is aborted.
+     *
+     * @param aborted {@code true} if the operation is aborted, {@code false} otherwise
+     */
+    public void setAborted(boolean aborted) {
+        this.mAborted = aborted;
+    }
+}
diff --git a/javax/obex/ServerRequestHandler.java b/javax/obex/ServerRequestHandler.java
new file mode 100644
index 0000000..f33f234
--- /dev/null
+++ b/javax/obex/ServerRequestHandler.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+/**
+ * The <code>ServerRequestHandler</code> class defines an event listener that
+ * will respond to OBEX requests made to the server.
+ * <P>
+ * The <code>onConnect()</code>, <code>onSetPath()</code>,
+ * <code>onDelete()</code>, <code>onGet()</code>, and <code>onPut()</code>
+ * methods may return any response code defined in the
+ * <code>ResponseCodes</code> class except for <code>OBEX_HTTP_CONTINUE</code>.
+ * If <code>OBEX_HTTP_CONTINUE</code> or a value not defined in the
+ * <code>ResponseCodes</code> class is returned, the server implementation will
+ * send an <code>OBEX_HTTP_INTERNAL_ERROR</code> response to the client.
+ * <P>
+ * <STRONG>Connection ID and Target Headers</STRONG>
+ * <P>
+ * According to the IrOBEX specification, a packet may not contain a Connection
+ * ID and Target header. Since the Connection ID header is managed by the
+ * implementation, it will not send a Connection ID header, if a Connection ID
+ * was specified, in a packet that has a Target header. In other words, if an
+ * application adds a Target header to a <code>HeaderSet</code> object used in
+ * an OBEX operation and a Connection ID was specified, no Connection ID will be
+ * sent in the packet containing the Target header.
+ * <P>
+ * <STRONG>CREATE-EMPTY Requests</STRONG>
+ * <P>
+ * A CREATE-EMPTY request allows clients to create empty objects on the server.
+ * When a CREATE-EMPTY request is received, the <code>onPut()</code> method will
+ * be called by the implementation. To differentiate between a normal PUT
+ * request and a CREATE-EMPTY request, an application must open the
+ * <code>InputStream</code> from the <code>Operation</code> object passed to the
+ * <code>onPut()</code> method. For a PUT request, the application will be able
+ * to read Body data from this <code>InputStream</code>. For a CREATE-EMPTY
+ * request, there will be no Body data to read. Therefore, a call to
+ * <code>InputStream.read()</code> will return -1.
+ */
+public class ServerRequestHandler {
+
+    private long mConnectionId;
+
+    /**
+     * Creates a <code>ServerRequestHandler</code>.
+     */
+    protected ServerRequestHandler() {
+        /*
+         * A connection ID of -1 implies there is no connection ID
+         */
+        mConnectionId = -1;
+    }
+
+    /**
+     * Sets the connection ID header to include in the reply packets.
+     * @param connectionId the connection ID to use; -1 if no connection ID
+     *        should be sent
+     * @throws IllegalArgumentException if <code>id</code> is not in the range
+     *         -1 to 2<sup>32</sup>-1
+     *
+     * @hide
+     */
+    public void setConnectionId(final long connectionId) {
+        if ((connectionId < -1) || (connectionId > 0xFFFFFFFFL)) {
+            throw new IllegalArgumentException("Illegal Connection ID");
+        }
+        mConnectionId = connectionId;
+    }
+
+    /**
+     * Retrieves the connection ID that is being used in the present connection.
+     * This method will return -1 if no connection ID is being used.
+     * @return the connection id being used or -1 if no connection ID is being
+     *         used
+     *
+     * @hide
+     */
+    public long getConnectionId() {
+        return mConnectionId;
+    }
+
+    /**
+     * Called when a CONNECT request is received.
+     * <P>
+     * If this method is not implemented by the class that extends this class,
+     * <code>onConnect()</code> will always return an <code>OBEX_HTTP_OK</code>
+     * response code.
+     * <P>
+     * The headers received in the request can be retrieved from the
+     * <code>request</code> argument. The headers that should be sent in the
+     * reply must be specified in the <code>reply</code> argument.
+     * @param request contains the headers sent by the client;
+     *        <code>request</code> will never be <code>null</code>
+     * @param reply the headers that should be sent in the reply;
+     *        <code>reply</code> will never be <code>null</code>
+     * @return a response code defined in <code>ResponseCodes</code> that will
+     *         be returned to the client; if an invalid response code is
+     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
+     *         will be used
+     */
+    public int onConnect(HeaderSet request, HeaderSet reply) {
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    /**
+     * Called when a DISCONNECT request is received.
+     * <P>
+     * The headers received in the request can be retrieved from the
+     * <code>request</code> argument. The headers that should be sent in the
+     * reply must be specified in the <code>reply</code> argument.
+     * @param request contains the headers sent by the client;
+     *        <code>request</code> will never be <code>null</code>
+     * @param reply the headers that should be sent in the reply;
+     *        <code>reply</code> will never be <code>null</code>
+     */
+    public void onDisconnect(HeaderSet request, HeaderSet reply) {
+    }
+
+    /**
+     * Called when a SETPATH request is received.
+     * <P>
+     * If this method is not implemented by the class that extends this class,
+     * <code>onSetPath()</code> will always return an
+     * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
+     * <P>
+     * The headers received in the request can be retrieved from the
+     * <code>request</code> argument. The headers that should be sent in the
+     * reply must be specified in the <code>reply</code> argument.
+     * @param request contains the headers sent by the client;
+     *        <code>request</code> will never be <code>null</code>
+     * @param reply the headers that should be sent in the reply;
+     *        <code>reply</code> will never be <code>null</code>
+     * @param backup <code>true</code> if the client requests that the server
+     *        back up one directory before changing to the path described by
+     *        <code>name</code>; <code>false</code> to apply the request to the
+     *        present path
+     * @param create <code>true</code> if the path should be created if it does
+     *        not already exist; <code>false</code> if the path should not be
+     *        created if it does not exist and an error code should be returned
+     * @return a response code defined in <code>ResponseCodes</code> that will
+     *         be returned to the client; if an invalid response code is
+     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
+     *         will be used
+     */
+    public int onSetPath(HeaderSet request, HeaderSet reply, boolean backup, boolean create) {
+
+        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Called when a DELETE request is received.
+     * <P>
+     * If this method is not implemented by the class that extends this class,
+     * <code>onDelete()</code> will always return an
+     * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
+     * <P>
+     * The headers received in the request can be retrieved from the
+     * <code>request</code> argument. The headers that should be sent in the
+     * reply must be specified in the <code>reply</code> argument.
+     * @param request contains the headers sent by the client;
+     *        <code>request</code> will never be <code>null</code>
+     * @param reply the headers that should be sent in the reply;
+     *        <code>reply</code> will never be <code>null</code>
+     * @return a response code defined in <code>ResponseCodes</code> that will
+     *         be returned to the client; if an invalid response code is
+     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
+     *         will be used
+     */
+    public int onDelete(HeaderSet request, HeaderSet reply) {
+        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Called when a ABORT request is received.
+     */
+    public int onAbort(HeaderSet request, HeaderSet reply) {
+        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Called when a PUT request is received.
+     * <P>
+     * If this method is not implemented by the class that extends this class,
+     * <code>onPut()</code> will always return an
+     * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
+     * <P>
+     * If an ABORT request is received during the processing of a PUT request,
+     * <code>op</code> will be closed by the implementation.
+     * @param operation contains the headers sent by the client and allows new
+     *        headers to be sent in the reply; <code>op</code> will never be
+     *        <code>null</code>
+     * @return a response code defined in <code>ResponseCodes</code> that will
+     *         be returned to the client; if an invalid response code is
+     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
+     *         will be used
+     */
+    public int onPut(Operation operation) {
+        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Called when a GET request is received.
+     * <P>
+     * If this method is not implemented by the class that extends this class,
+     * <code>onGet()</code> will always return an
+     * <code>OBEX_HTTP_NOT_IMPLEMENTED</code> response code.
+     * <P>
+     * If an ABORT request is received during the processing of a GET request,
+     * <code>op</code> will be closed by the implementation.
+     * @param operation contains the headers sent by the client and allows new
+     *        headers to be sent in the reply; <code>op</code> will never be
+     *        <code>null</code>
+     * @return a response code defined in <code>ResponseCodes</code> that will
+     *         be returned to the client; if an invalid response code is
+     *         provided, the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code
+     *         will be used
+     */
+    public int onGet(Operation operation) {
+        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
+    }
+
+    /**
+     * Called when this object attempts to authenticate a client and the
+     * authentication request fails because the response digest in the
+     * authentication response header was wrong.
+     * <P>
+     * If this method is not implemented by the class that extends this class,
+     * this method will do nothing.
+     * @param userName the user name returned in the authentication response;
+     *        <code>null</code> if no user name was provided in the response
+     */
+    public void onAuthenticationFailure(byte[] userName) {
+    }
+
+    /**
+     * Called by ServerSession to update the status of current transaction
+     * <P>
+     * If this method is not implemented by the class that extends this class,
+     * this method will do nothing.
+     */
+    public void updateStatus(String message) {
+    }
+
+    /**
+     * Called when session is closed.
+     * <P>
+     * If this method is not implemented by the class that extends this class,
+     * this method will do nothing.
+     */
+    public void onClose() {
+    }
+
+    /**
+     * Override to add Single Response Mode support - e.g. if the supplied
+     * transport is l2cap.
+     * @return True if SRM is supported, else False
+     */
+    public boolean isSrmSupported() {
+        return false;
+    }
+}
diff --git a/javax/obex/ServerSession.java b/javax/obex/ServerSession.java
new file mode 100644
index 0000000..68cd766
--- /dev/null
+++ b/javax/obex/ServerSession.java
@@ -0,0 +1,750 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (c) 2015 Samsung LSI
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * This class in an implementation of the OBEX ServerSession.
+ */
+public final class ServerSession extends ObexSession implements Runnable {
+
+    private static final String TAG = "Obex ServerSession";
+    private static final boolean V = ObexHelper.VDBG;
+
+    private ObexTransport mTransport;
+
+    private InputStream mInput;
+
+    private OutputStream mOutput;
+
+    private ServerRequestHandler mListener;
+
+    private Thread mProcessThread;
+
+    private int mMaxPacketLength;
+
+    private boolean mClosed;
+
+    /**
+     * Creates new ServerSession.
+     *
+     * @param transport the connection to the client
+     * @param handler the event listener that will process requests
+     * @param auth the authenticator to use with this connection
+     * @throws IOException if an error occurred while opening the input and
+     *         output streams
+     */
+    public ServerSession(ObexTransport transport, ServerRequestHandler handler, Authenticator auth)
+            throws IOException {
+        mAuthenticator = auth;
+        mTransport = transport;
+        mInput = mTransport.openInputStream();
+        mOutput = mTransport.openOutputStream();
+        mListener = handler;
+        mMaxPacketLength = 256;
+
+        mClosed = false;
+        mProcessThread = new Thread(this);
+        mProcessThread.start();
+    }
+
+    /**
+     * Processes requests made to the server and forwards them to the
+     * appropriate event listener.
+     *
+     * @hide
+     */
+    public void run() {
+        try {
+
+            boolean done = false;
+            while (!done && !mClosed) {
+                if(V) Log.v(TAG, "Waiting for incoming request...");
+                int requestType = mInput.read();
+                if(V) Log.v(TAG, "Read request: " + requestType);
+                switch (requestType) {
+                    case ObexHelper.OBEX_OPCODE_CONNECT:
+                        handleConnectRequest();
+                        break;
+
+                    case ObexHelper.OBEX_OPCODE_DISCONNECT:
+                        handleDisconnectRequest();
+                        break;
+
+                    case ObexHelper.OBEX_OPCODE_GET:
+                    case ObexHelper.OBEX_OPCODE_GET_FINAL:
+                        handleGetRequest(requestType);
+                        break;
+
+                    case ObexHelper.OBEX_OPCODE_PUT:
+                    case ObexHelper.OBEX_OPCODE_PUT_FINAL:
+                        handlePutRequest(requestType);
+                        break;
+
+                    case ObexHelper.OBEX_OPCODE_SETPATH:
+                        handleSetPathRequest();
+                        break;
+                    case ObexHelper.OBEX_OPCODE_ABORT:
+                        handleAbortRequest();
+                        break;
+
+                    case -1:
+                        done = true;
+                        break;
+
+                    default:
+
+                        /*
+                         * Received a request type that is not recognized so I am
+                         * just going to read the packet and send a not implemented
+                         * to the client
+                         */
+                        int length = mInput.read();
+                        length = (length << 8) + mInput.read();
+                        for (int i = 3; i < length; i++) {
+                            mInput.read();
+                        }
+                        sendResponse(ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED, null);
+                }
+            }
+
+        } catch (NullPointerException e) {
+            Log.d(TAG, "Exception occurred - ignoring", e);
+        } catch (Exception e) {
+            Log.d(TAG, "Exception occurred - ignoring", e);
+        }
+        close();
+    }
+
+    /**
+     * Handles a ABORT request from a client. This method will read the rest of
+     * the request from the client. Assuming the request is valid, it will
+     * create a <code>HeaderSet</code> object to pass to the
+     * <code>ServerRequestHandler</code> object. After the handler processes the
+     * request, this method will create a reply message to send to the server.
+     *
+     * @throws IOException if an error occurred at the transport layer
+     */
+    private void handleAbortRequest() throws IOException {
+        int code = ResponseCodes.OBEX_HTTP_OK;
+        HeaderSet request = new HeaderSet();
+        HeaderSet reply = new HeaderSet();
+
+        int length = mInput.read();
+        length = (length << 8) + mInput.read();
+        if (length > ObexHelper.getMaxRxPacketSize(mTransport)) {
+            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
+        } else {
+            for (int i = 3; i < length; i++) {
+                mInput.read();
+            }
+            code = mListener.onAbort(request, reply);
+            Log.v(TAG, "onAbort request handler return value- " + code);
+            code = validateResponseCode(code);
+        }
+        sendResponse(code, null);
+    }
+
+    /**
+     * Handles a PUT request from a client. This method will provide a
+     * <code>ServerOperation</code> object to the request handler. The
+     * <code>ServerOperation</code> object will handle the rest of the request.
+     * It will also send replies and receive requests until the final reply
+     * should be sent. When the final reply should be sent, this method will get
+     * the response code to use and send the reply. The
+     * <code>ServerOperation</code> object will always reply with a
+     * OBEX_HTTP_CONTINUE reply. It will only reply if further information is
+     * needed.
+     * @param type the type of request received; either 0x02 or 0x82
+     * @throws IOException if an error occurred at the transport layer
+     */
+    private void handlePutRequest(int type) throws IOException {
+        ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener);
+        try {
+            int response = -1;
+
+            if ((op.finalBitSet) && !op.isValidBody()) {
+                response = validateResponseCode(mListener
+                        .onDelete(op.requestHeader, op.replyHeader));
+            } else {
+                response = validateResponseCode(mListener.onPut(op));
+            }
+            if (response != ResponseCodes.OBEX_HTTP_OK && !op.isAborted()) {
+                op.sendReply(response);
+            } else if (!op.isAborted()) {
+                // wait for the final bit
+                while (!op.finalBitSet) {
+                    op.sendReply(ResponseCodes.OBEX_HTTP_CONTINUE);
+                }
+                op.sendReply(response);
+            }
+        } catch (Exception e) {
+            /*To fix bugs in aborted cases,
+             *(client abort file transfer prior to the last packet which has the end of body header,
+             *internal error should not be sent because server has already replied with
+             *OK response in "sendReply")
+             */
+            if(V) Log.d(TAG,"Exception occurred - sending OBEX_HTTP_INTERNAL_ERROR reply",e);
+            if (!op.isAborted()) {
+                sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
+            }
+        }
+    }
+
+    /**
+     * Handles a GET request from a client. This method will provide a
+     * <code>ServerOperation</code> object to the request handler. The
+     * <code>ServerOperation</code> object will handle the rest of the request.
+     * It will also send replies and receive requests until the final reply
+     * should be sent. When the final reply should be sent, this method will get
+     * the response code to use and send the reply. The
+     * <code>ServerOperation</code> object will always reply with a
+     * OBEX_HTTP_CONTINUE reply. It will only reply if further information is
+     * needed.
+     * @param type the type of request received; either 0x03 or 0x83
+     * @throws IOException if an error occurred at the transport layer
+     */
+    private void handleGetRequest(int type) throws IOException {
+        ServerOperation op = new ServerOperation(this, mInput, type, mMaxPacketLength, mListener);
+        try {
+            int response = validateResponseCode(mListener.onGet(op));
+
+            if (!op.isAborted()) {
+                op.sendReply(response);
+            }
+        } catch (Exception e) {
+            if(V) Log.d(TAG,"Exception occurred - sending OBEX_HTTP_INTERNAL_ERROR reply",e);
+            sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
+        }
+    }
+
+    /**
+     * Send standard response.
+     * @param code the response code to send
+     * @param header the headers to include in the response
+     * @throws IOException if an IO error occurs
+     *
+     * @hide
+     */
+    public void sendResponse(int code, byte[] header) throws IOException {
+        int totalLength = 3;
+        byte[] data = null;
+        OutputStream op = mOutput;
+        if (op == null) {
+            return;
+        }
+
+        if (header != null) {
+            totalLength += header.length;
+            data = new byte[totalLength];
+            data[0] = (byte)code;
+            data[1] = (byte)(totalLength >> 8);
+            data[2] = (byte)totalLength;
+            System.arraycopy(header, 0, data, 3, header.length);
+        } else {
+            data = new byte[totalLength];
+            data[0] = (byte)code;
+            data[1] = (byte)0x00;
+            data[2] = (byte)totalLength;
+        }
+        op.write(data);
+        op.flush(); // TODO: Do we need to flush?
+    }
+
+    /**
+     * Handles a SETPATH request from a client. This method will read the rest
+     * of the request from the client. Assuming the request is valid, it will
+     * create a <code>HeaderSet</code> object to pass to the
+     * <code>ServerRequestHandler</code> object. After the handler processes the
+     * request, this method will create a reply message to send to the server
+     * with the response code provided.
+     * @throws IOException if an error occurred at the transport layer
+     */
+    private void handleSetPathRequest() throws IOException {
+        int length;
+        int flags;
+        @SuppressWarnings("unused")
+        int constants;
+        int totalLength = 3;
+        byte[] head = null;
+        int code = -1;
+        int bytesReceived;
+        HeaderSet request = new HeaderSet();
+        HeaderSet reply = new HeaderSet();
+
+        length = mInput.read();
+        length = (length << 8) + mInput.read();
+        flags = mInput.read();
+        constants = mInput.read();
+
+        if (length > ObexHelper.getMaxRxPacketSize(mTransport)) {
+            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
+            totalLength = 3;
+        } else {
+            if (length > 5) {
+                byte[] headers = new byte[length - 5];
+                bytesReceived = mInput.read(headers);
+
+                while (bytesReceived != headers.length) {
+                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
+                            - bytesReceived);
+                }
+
+                ObexHelper.updateHeaderSet(request, headers);
+
+                if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
+                    mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
+                } else {
+                    mListener.setConnectionId(1);
+                }
+                // the Auth chan is initiated by the server, client sent back the authResp .
+                if (request.mAuthResp != null) {
+                    if (!handleAuthResp(request.mAuthResp)) {
+                        code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
+                        mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
+                                request.mAuthResp));
+                    }
+                    request.mAuthResp = null;
+                }
+            }
+
+            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
+                // the Auth challenge is initiated by the client
+                // the server will send back the authResp to the client
+                if (request.mAuthChall != null) {
+                    handleAuthChall(request);
+                    reply.mAuthResp = new byte[request.mAuthResp.length];
+                    System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0,
+                            reply.mAuthResp.length);
+                    request.mAuthChall = null;
+                    request.mAuthResp = null;
+                }
+                boolean backup = false;
+                boolean create = true;
+                if (!((flags & 1) == 0)) {
+                    backup = true;
+                }
+                if (!((flags & 2) == 0)) {
+                    create = false;
+                }
+
+                try {
+                    code = mListener.onSetPath(request, reply, backup, create);
+                } catch (Exception e) {
+                    if(V) Log.d(TAG,"Exception occurred - sending OBEX_HTTP_INTERNAL_ERROR reply",
+                            e);
+                    sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
+                    return;
+                }
+
+                code = validateResponseCode(code);
+
+                if (reply.nonce != null) {
+                    mChallengeDigest = new byte[16];
+                    System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16);
+                } else {
+                    mChallengeDigest = null;
+                }
+
+                long id = mListener.getConnectionId();
+                if (id == -1) {
+                    reply.mConnectionID = null;
+                } else {
+                    reply.mConnectionID = ObexHelper.convertToByteArray(id);
+                }
+
+                head = ObexHelper.createHeader(reply, false);
+                totalLength += head.length;
+
+                if (totalLength > mMaxPacketLength) {
+                    totalLength = 3;
+                    head = null;
+                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+                }
+            }
+        }
+
+        // Compute Length of OBEX SETPATH packet
+        byte[] replyData = new byte[totalLength];
+        replyData[0] = (byte)code;
+        replyData[1] = (byte)(totalLength >> 8);
+        replyData[2] = (byte)totalLength;
+        if (head != null) {
+            System.arraycopy(head, 0, replyData, 3, head.length);
+        }
+        /*
+         * Write the OBEX SETPATH packet to the server. Byte 0: response code
+         * Byte 1&2: Connect Packet Length Byte 3 to n: headers
+         */
+        mOutput.write(replyData);
+        mOutput.flush();
+    }
+
+    /**
+     * Handles a disconnect request from a client. This method will read the
+     * rest of the request from the client. Assuming the request is valid, it
+     * will create a <code>HeaderSet</code> object to pass to the
+     * <code>ServerRequestHandler</code> object. After the handler processes the
+     * request, this method will create a reply message to send to the server.
+     * @throws IOException if an error occurred at the transport layer
+     */
+    private void handleDisconnectRequest() throws IOException {
+        int length;
+        int code = ResponseCodes.OBEX_HTTP_OK;
+        int totalLength = 3;
+        byte[] head = null;
+        int bytesReceived;
+        HeaderSet request = new HeaderSet();
+        HeaderSet reply = new HeaderSet();
+
+        length = mInput.read();
+        length = (length << 8) + mInput.read();
+
+        if (length > ObexHelper.getMaxRxPacketSize(mTransport)) {
+            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
+            totalLength = 3;
+        } else {
+            if (length > 3) {
+                byte[] headers = new byte[length - 3];
+                bytesReceived = mInput.read(headers);
+
+                while (bytesReceived != headers.length) {
+                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
+                            - bytesReceived);
+                }
+
+                ObexHelper.updateHeaderSet(request, headers);
+            }
+
+            if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
+                mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
+            } else {
+                mListener.setConnectionId(1);
+            }
+
+            if (request.mAuthResp != null) {
+                if (!handleAuthResp(request.mAuthResp)) {
+                    code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
+                    mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
+                            request.mAuthResp));
+                }
+                request.mAuthResp = null;
+            }
+
+            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
+
+                if (request.mAuthChall != null) {
+                    handleAuthChall(request);
+                    request.mAuthChall = null;
+                }
+
+                try {
+                    mListener.onDisconnect(request, reply);
+                } catch (Exception e) {
+                    if(V) Log.d(TAG,"Exception occurred - sending OBEX_HTTP_INTERNAL_ERROR reply",
+                            e);
+                    sendResponse(ResponseCodes.OBEX_HTTP_INTERNAL_ERROR, null);
+                    return;
+                }
+
+                long id = mListener.getConnectionId();
+                if (id == -1) {
+                    reply.mConnectionID = null;
+                } else {
+                    reply.mConnectionID = ObexHelper.convertToByteArray(id);
+                }
+
+                head = ObexHelper.createHeader(reply, false);
+                totalLength += head.length;
+
+                if (totalLength > mMaxPacketLength) {
+                    totalLength = 3;
+                    head = null;
+                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+                }
+            }
+        }
+
+        // Compute Length of OBEX CONNECT packet
+        byte[] replyData;
+        if (head != null) {
+            replyData = new byte[3 + head.length];
+        } else {
+            replyData = new byte[3];
+        }
+        replyData[0] = (byte)code;
+        replyData[1] = (byte)(totalLength >> 8);
+        replyData[2] = (byte)totalLength;
+        if (head != null) {
+            System.arraycopy(head, 0, replyData, 3, head.length);
+        }
+        /*
+         * Write the OBEX DISCONNECT packet to the server. Byte 0: response code
+         * Byte 1&2: Connect Packet Length Byte 3 to n: headers
+         */
+        mOutput.write(replyData);
+        mOutput.flush();
+    }
+
+    /**
+     * Handles a connect request from a client. This method will read the rest
+     * of the request from the client. Assuming the request is valid, it will
+     * create a <code>HeaderSet</code> object to pass to the
+     * <code>ServerRequestHandler</code> object. After the handler processes the
+     * request, this method will create a reply message to send to the server
+     * with the response code provided.
+     * @throws IOException if an error occurred at the transport layer
+     */
+    private void handleConnectRequest() throws IOException {
+        int packetLength;
+        @SuppressWarnings("unused")
+        int version;
+        @SuppressWarnings("unused")
+        int flags;
+        int totalLength = 7;
+        byte[] head = null;
+        int code = -1;
+        HeaderSet request = new HeaderSet();
+        HeaderSet reply = new HeaderSet();
+        int bytesReceived;
+
+        if(V) Log.v(TAG,"handleConnectRequest()");
+
+        /*
+         * Read in the length of the OBEX packet, OBEX version, flags, and max
+         * packet length
+         */
+        packetLength = mInput.read();
+        packetLength = (packetLength << 8) + mInput.read();
+        if(V) Log.v(TAG,"handleConnectRequest() - packetLength: " + packetLength);
+
+        version = mInput.read();
+        flags = mInput.read();
+        mMaxPacketLength = mInput.read();
+        mMaxPacketLength = (mMaxPacketLength << 8) + mInput.read();
+
+        if(V) Log.v(TAG,"handleConnectRequest() - version: " + version
+                + " MaxLength: " + mMaxPacketLength + " flags: " + flags);
+
+        // should we check it?
+        if (mMaxPacketLength > ObexHelper.MAX_PACKET_SIZE_INT) {
+            mMaxPacketLength = ObexHelper.MAX_PACKET_SIZE_INT;
+        }
+
+        if(mMaxPacketLength > ObexHelper.getMaxTxPacketSize(mTransport)) {
+            Log.w(TAG, "Requested MaxObexPacketSize " + mMaxPacketLength
+                    + " is larger than the max size supported by the transport: "
+                    + ObexHelper.getMaxTxPacketSize(mTransport)
+                    + " Reducing to this size.");
+            mMaxPacketLength = ObexHelper.getMaxTxPacketSize(mTransport);
+        }
+
+        if (packetLength > ObexHelper.getMaxRxPacketSize(mTransport)) {
+            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
+            totalLength = 7;
+        } else {
+            if (packetLength > 7) {
+                byte[] headers = new byte[packetLength - 7];
+                bytesReceived = mInput.read(headers);
+
+                while (bytesReceived != headers.length) {
+                    bytesReceived += mInput.read(headers, bytesReceived, headers.length
+                            - bytesReceived);
+                }
+
+                ObexHelper.updateHeaderSet(request, headers);
+            }
+
+            if (mListener.getConnectionId() != -1 && request.mConnectionID != null) {
+                mListener.setConnectionId(ObexHelper.convertToLong(request.mConnectionID));
+            } else {
+                mListener.setConnectionId(1);
+            }
+
+            if (request.mAuthResp != null) {
+                if (!handleAuthResp(request.mAuthResp)) {
+                    code = ResponseCodes.OBEX_HTTP_UNAUTHORIZED;
+                    mListener.onAuthenticationFailure(ObexHelper.getTagValue((byte)0x01,
+                            request.mAuthResp));
+                }
+                request.mAuthResp = null;
+            }
+
+            if (code != ResponseCodes.OBEX_HTTP_UNAUTHORIZED) {
+                if (request.mAuthChall != null) {
+                    handleAuthChall(request);
+                    reply.mAuthResp = new byte[request.mAuthResp.length];
+                    System.arraycopy(request.mAuthResp, 0, reply.mAuthResp, 0,
+                            reply.mAuthResp.length);
+                    request.mAuthChall = null;
+                    request.mAuthResp = null;
+                }
+
+                try {
+                    code = mListener.onConnect(request, reply);
+                    code = validateResponseCode(code);
+
+                    if (reply.nonce != null) {
+                        mChallengeDigest = new byte[16];
+                        System.arraycopy(reply.nonce, 0, mChallengeDigest, 0, 16);
+                    } else {
+                        mChallengeDigest = null;
+                    }
+                    long id = mListener.getConnectionId();
+                    if (id == -1) {
+                        reply.mConnectionID = null;
+                    } else {
+                        reply.mConnectionID = ObexHelper.convertToByteArray(id);
+                    }
+
+                    head = ObexHelper.createHeader(reply, false);
+                    totalLength += head.length;
+
+                    if (totalLength > mMaxPacketLength) {
+                        totalLength = 7;
+                        head = null;
+                        code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+                    }
+                } catch (Exception e) {
+                    if(V) Log.d(TAG,"Exception occurred - sending OBEX_HTTP_INTERNAL_ERROR reply",
+                            e);
+                    totalLength = 7;
+                    head = null;
+                    code = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+                }
+
+            }
+        }
+
+        // Compute Length of OBEX CONNECT packet
+        byte[] length = ObexHelper.convertToByteArray(totalLength);
+
+        /*
+         * Write the OBEX CONNECT packet to the server. Byte 0: response code
+         * Byte 1&2: Connect Packet Length Byte 3: OBEX Version Number
+         * (Presently, 0x10) Byte 4: Flags (For TCP 0x00) Byte 5&6: Max OBEX
+         * Packet Length (Defined in MAX_PACKET_SIZE) Byte 7 to n: headers
+         */
+        byte[] sendData = new byte[totalLength];
+        int maxRxLength = ObexHelper.getMaxRxPacketSize(mTransport);
+        if (maxRxLength > mMaxPacketLength) {
+            if(V) Log.v(TAG,"Set maxRxLength to min of maxRxServrLen:" + maxRxLength +
+                    " and MaxNegotiated from Client: " + mMaxPacketLength);
+            maxRxLength = mMaxPacketLength;
+        }
+        sendData[0] = (byte)code;
+        sendData[1] = length[2];
+        sendData[2] = length[3];
+        sendData[3] = (byte)0x10;
+        sendData[4] = (byte)0x00;
+        sendData[5] = (byte)(maxRxLength >> 8);
+        sendData[6] = (byte)(maxRxLength & 0xFF);
+
+        if (head != null) {
+            System.arraycopy(head, 0, sendData, 7, head.length);
+        }
+
+        mOutput.write(sendData);
+        mOutput.flush();
+    }
+
+    /**
+     * Closes the server session - in detail close I/O streams and the
+     * underlying transport layer. Internal flag is also set so that later
+     * attempt to read/write will throw an exception.
+     */
+    public synchronized void close() {
+        if (mListener != null) {
+            mListener.onClose();
+        }
+        try {
+            /* Set state to closed before interrupting the thread by closing the streams */
+            mClosed = true;
+            if(mInput != null)
+                mInput.close();
+            if(mOutput != null)
+                mOutput.close();
+            if(mTransport != null)
+                mTransport.close();
+        } catch (Exception e) {
+            if(V) Log.d(TAG,"Exception occurred during close() - ignore",e);
+        }
+        mTransport = null;
+        mInput = null;
+        mOutput = null;
+        mListener = null;
+    }
+
+    /**
+     * Verifies that the response code is valid. If it is not valid, it will
+     * return the <code>OBEX_HTTP_INTERNAL_ERROR</code> response code.
+     * @param code the response code to check
+     * @return the valid response code or <code>OBEX_HTTP_INTERNAL_ERROR</code>
+     *         if <code>code</code> is not valid
+     */
+    private int validateResponseCode(int code) {
+
+        if ((code >= ResponseCodes.OBEX_HTTP_OK) && (code <= ResponseCodes.OBEX_HTTP_PARTIAL)) {
+            return code;
+        }
+        if ((code >= ResponseCodes.OBEX_HTTP_MULT_CHOICE)
+                && (code <= ResponseCodes.OBEX_HTTP_USE_PROXY)) {
+            return code;
+        }
+        if ((code >= ResponseCodes.OBEX_HTTP_BAD_REQUEST)
+                && (code <= ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE)) {
+            return code;
+        }
+        if ((code >= ResponseCodes.OBEX_HTTP_INTERNAL_ERROR)
+                && (code <= ResponseCodes.OBEX_HTTP_VERSION)) {
+            return code;
+        }
+        if ((code >= ResponseCodes.OBEX_DATABASE_FULL)
+                && (code <= ResponseCodes.OBEX_DATABASE_LOCKED)) {
+            return code;
+        }
+        return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+    }
+
+    /** @hide */
+    public ObexTransport getTransport() {
+        return mTransport;
+    }
+}
diff --git a/javax/obex/SessionNotifier.java b/javax/obex/SessionNotifier.java
new file mode 100644
index 0000000..d2760f7
--- /dev/null
+++ b/javax/obex/SessionNotifier.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package javax.obex;
+
+import java.io.IOException;
+
+/**
+ * The <code>SessionNotifier</code> interface defines a connection notifier for
+ * server-side OBEX connections. When a <code>SessionNotifier</code> is created
+ * and calls <code>acceptAndOpen()</code>, it will begin listening for clients
+ * to create a connection at the transport layer. When the transport layer
+ * connection is received, the <code>acceptAndOpen()</code> method will return a
+ * <code>javax.microedition.io.Connection</code> that is the connection to the
+ * client. The <code>acceptAndOpen()</code> method also takes a
+ * <code>ServerRequestHandler</code> argument that will process the requests
+ * from the client that connects to the server.
+ */
+public interface SessionNotifier {
+
+    /**
+     * Waits for a transport layer connection to be established and specifies
+     * the handler to handle the requests from the client. No authenticator is
+     * associated with this connection, therefore, it is implementation
+     * dependent as to how an authentication challenge and authentication
+     * response header will be received and processed.
+     * <P>
+     * <H4>Additional Note for OBEX over Bluetooth</H4> If this method is called
+     * on a <code>SessionNotifier</code> object that does not have a
+     * <code>ServiceRecord</code> in the SDDB, the <code>ServiceRecord</code>
+     * for this object will be added to the SDDB. This method requests the BCC
+     * to put the local device in connectable mode so that it will respond to
+     * connection attempts by clients.
+     * <P>
+     * The following checks are done to verify that the service record provided
+     * is valid. If any of these checks fail, then a
+     * <code>ServiceRegistrationException</code> is thrown.
+     * <UL>
+     * <LI>ServiceClassIDList and ProtocolDescriptorList, the mandatory service
+     * attributes for a <code>btgoep</code> service record, must be present in
+     * the <code>ServiceRecord</code> associated with this notifier.
+     * <LI>L2CAP, RFCOMM and OBEX must all be in the ProtocolDescriptorList
+     * <LI>The <code>ServiceRecord</code> associated with this notifier must not
+     * have changed the RFCOMM server channel number
+     * </UL>
+     * <P>
+     * This method will not ensure that <code>ServiceRecord</code> associated
+     * with this notifier is a completely valid service record. It is the
+     * responsibility of the application to ensure that the service record
+     * follows all of the applicable syntactic and semantic rules for service
+     * record correctness.
+     * @param handler the request handler that will respond to OBEX requests
+     * @return the connection to the client
+     * @throws IOException if an error occurs in the transport layer
+     * @throws NullPointerException if <code>handler</code> is <code>null</code>
+     */
+    ObexSession acceptAndOpen(ServerRequestHandler handler) throws IOException;
+
+    /**
+     * Waits for a transport layer connection to be established and specifies
+     * the handler to handle the requests from the client and the
+     * <code>Authenticator</code> to use to respond to authentication challenge
+     * and authentication response headers.
+     * <P>
+     * <H4>Additional Note for OBEX over Bluetooth</H4> If this method is called
+     * on a <code>SessionNotifier</code> object that does not have a
+     * <code>ServiceRecord</code> in the SDDB, the <code>ServiceRecord</code>
+     * for this object will be added to the SDDB. This method requests the BCC
+     * to put the local device in connectable mode so that it will respond to
+     * connection attempts by clients.
+     * <P>
+     * The following checks are done to verify that the service record provided
+     * is valid. If any of these checks fail, then a
+     * <code>ServiceRegistrationException</code> is thrown.
+     * <UL>
+     * <LI>ServiceClassIDList and ProtocolDescriptorList, the mandatory service
+     * attributes for a <code>btgoep</code> service record, must be present in
+     * the <code>ServiceRecord</code> associated with this notifier.
+     * <LI>L2CAP, RFCOMM and OBEX must all be in the ProtocolDescriptorList
+     * <LI>The <code>ServiceRecord</code> associated with this notifier must not
+     * have changed the RFCOMM server channel number
+     * </UL>
+     * <P>
+     * This method will not ensure that <code>ServiceRecord</code> associated
+     * with this notifier is a completely valid service record. It is the
+     * responsibility of the application to ensure that the service record
+     * follows all of the applicable syntactic and semantic rules for service
+     * record correctness.
+     * @param handler the request handler that will respond to OBEX requests
+     * @param auth the <code>Authenticator</code> to use with this connection;
+     *        if <code>null</code> then no <code>Authenticator</code> will be
+     *        used
+     * @return the connection to the client
+     * @throws IOException if an error occurs in the transport layer
+     * @throws NullPointerException if <code>handler</code> is <code>null</code>
+     */
+    ObexSession acceptAndOpen(ServerRequestHandler handler, Authenticator auth) throws IOException;
+}
