diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..68acd2a
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,35 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+src_dirs:= src/android/bluetooth/client/pbap
+
+LOCAL_SRC_FILES := \
+        $(call all-java-files-under, $(src_dirs))
+
+LOCAL_MODULE:= android.bluetooth.client.pbap
+LOCAL_JAVA_LIBRARIES := javax.obex
+LOCAL_STATIC_JAVA_LIBRARIES := com.android.vcard
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+
+src_dirs:= src/android/bluetooth/client/map
+
+LOCAL_SRC_FILES := \
+        $(call all-java-files-under, $(src_dirs))
+
+LOCAL_MODULE:= android.bluetooth.client.map
+LOCAL_JAVA_LIBRARIES := javax.obex
+LOCAL_STATIC_JAVA_LIBRARIES := com.android.vcard
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/src/android/bluetooth/client/map/BluetoothMapBmessage.java b/src/android/bluetooth/client/map/BluetoothMapBmessage.java
new file mode 100644
index 0000000..84e4c75
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMapBmessage.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import com.android.vcard.VCardEntry;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+
+/**
+ * Object representation of message in bMessage format
+ * <p>
+ * This object will be received in {@link BluetoothMasClient#EVENT_GET_MESSAGE}
+ * callback message.
+ */
+public class BluetoothMapBmessage {
+
+    String mBmsgVersion;
+    Status mBmsgStatus;
+    Type mBmsgType;
+    String mBmsgFolder;
+
+    String mBbodyEncoding;
+    String mBbodyCharset;
+    String mBbodyLanguage;
+    int mBbodyLength;
+
+    String mMessage;
+
+    ArrayList<VCardEntry> mOriginators;
+    ArrayList<VCardEntry> mRecipients;
+
+    public enum Status {
+        READ, UNREAD
+    }
+
+    public enum Type {
+        EMAIL, SMS_GSM, SMS_CDMA, MMS
+    }
+
+    /**
+     * Constructs empty message object
+     */
+    public BluetoothMapBmessage() {
+        mOriginators = new ArrayList<VCardEntry>();
+        mRecipients = new ArrayList<VCardEntry>();
+    }
+
+    public VCardEntry getOriginator() {
+        if (mOriginators.size() > 0) {
+            return mOriginators.get(0);
+        } else {
+            return null;
+        }
+    }
+
+    public ArrayList<VCardEntry> getOriginators() {
+        return mOriginators;
+    }
+
+    public BluetoothMapBmessage addOriginator(VCardEntry vcard) {
+        mOriginators.add(vcard);
+        return this;
+    }
+
+    public ArrayList<VCardEntry> getRecipients() {
+        return mRecipients;
+    }
+
+    public BluetoothMapBmessage addRecipient(VCardEntry vcard) {
+        mRecipients.add(vcard);
+        return this;
+    }
+
+    public Status getStatus() {
+        return mBmsgStatus;
+    }
+
+    public BluetoothMapBmessage setStatus(Status status) {
+        mBmsgStatus = status;
+        return this;
+    }
+
+    public Type getType() {
+        return mBmsgType;
+    }
+
+    public BluetoothMapBmessage setType(Type type) {
+        mBmsgType = type;
+        return this;
+    }
+
+    public String getFolder() {
+        return mBmsgFolder;
+    }
+
+    public BluetoothMapBmessage setFolder(String folder) {
+        mBmsgFolder = folder;
+        return this;
+    }
+
+    public String getEncoding() {
+        return mBbodyEncoding;
+    }
+
+    public BluetoothMapBmessage setEncoding(String encoding) {
+        mBbodyEncoding = encoding;
+        return this;
+    }
+
+    public String getCharset() {
+        return mBbodyCharset;
+    }
+
+    public BluetoothMapBmessage setCharset(String charset) {
+        mBbodyCharset = charset;
+        return this;
+    }
+
+    public String getLanguage() {
+        return mBbodyLanguage;
+    }
+
+    public BluetoothMapBmessage setLanguage(String language) {
+        mBbodyLanguage = language;
+        return this;
+    }
+
+    public String getBodyContent() {
+        return mMessage;
+    }
+
+    public BluetoothMapBmessage setBodyContent(String body) {
+        mMessage = body;
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        JSONObject json = new JSONObject();
+
+        try {
+            json.put("status", mBmsgStatus);
+            json.put("type", mBmsgType);
+            json.put("folder", mBmsgFolder);
+            json.put("message", mMessage);
+        } catch (JSONException e) {
+            // do nothing
+        }
+
+        return json.toString();
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMapBmessageBuilder.java b/src/android/bluetooth/client/map/BluetoothMapBmessageBuilder.java
new file mode 100644
index 0000000..8629423
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMapBmessageBuilder.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+import com.android.vcard.VCardEntry;
+import com.android.vcard.VCardEntry.EmailData;
+import com.android.vcard.VCardEntry.NameData;
+import com.android.vcard.VCardEntry.PhoneData;
+
+import java.util.List;
+
+class BluetoothMapBmessageBuilder {
+
+    private final static String CRLF = "\r\n";
+
+    private final static String BMSG_BEGIN = "BEGIN:BMSG";
+    private final static String BMSG_VERSION = "VERSION:1.0";
+    private final static String BMSG_STATUS = "STATUS:";
+    private final static String BMSG_TYPE = "TYPE:";
+    private final static String BMSG_FOLDER = "FOLDER:";
+    private final static String BMSG_END = "END:BMSG";
+
+    private final static String BENV_BEGIN = "BEGIN:BENV";
+    private final static String BENV_END = "END:BENV";
+
+    private final static String BBODY_BEGIN = "BEGIN:BBODY";
+    private final static String BBODY_ENCODING = "ENCODING:";
+    private final static String BBODY_CHARSET = "CHARSET:";
+    private final static String BBODY_LANGUAGE = "LANGUAGE:";
+    private final static String BBODY_LENGTH = "LENGTH:";
+    private final static String BBODY_END = "END:BBODY";
+
+    private final static String MSG_BEGIN = "BEGIN:MSG";
+    private final static String MSG_END = "END:MSG";
+
+    private final static String VCARD_BEGIN = "BEGIN:VCARD";
+    private final static String VCARD_VERSION = "VERSION:2.1";
+    private final static String VCARD_N = "N:";
+    private final static String VCARD_EMAIL = "EMAIL:";
+    private final static String VCARD_TEL = "TEL:";
+    private final static String VCARD_END = "END:VCARD";
+
+    private final StringBuilder mBmsg;
+
+    private BluetoothMapBmessageBuilder() {
+        mBmsg = new StringBuilder();
+    }
+
+    static public String createBmessage(BluetoothMapBmessage bmsg) {
+        BluetoothMapBmessageBuilder b = new BluetoothMapBmessageBuilder();
+
+        b.build(bmsg);
+
+        return b.mBmsg.toString();
+    }
+
+    private void build(BluetoothMapBmessage bmsg) {
+        int bodyLen = MSG_BEGIN.length() + MSG_END.length() + 3 * CRLF.length()
+                + bmsg.mMessage.getBytes().length;
+
+        mBmsg.append(BMSG_BEGIN).append(CRLF);
+
+        mBmsg.append(BMSG_VERSION).append(CRLF);
+        mBmsg.append(BMSG_STATUS).append(bmsg.mBmsgStatus).append(CRLF);
+        mBmsg.append(BMSG_TYPE).append(bmsg.mBmsgType).append(CRLF);
+        mBmsg.append(BMSG_FOLDER).append(bmsg.mBmsgFolder).append(CRLF);
+
+        for (VCardEntry vcard : bmsg.mOriginators) {
+            buildVcard(vcard);
+        }
+
+        {
+            mBmsg.append(BENV_BEGIN).append(CRLF);
+
+            for (VCardEntry vcard : bmsg.mRecipients) {
+                buildVcard(vcard);
+            }
+
+            {
+                mBmsg.append(BBODY_BEGIN).append(CRLF);
+
+                if (bmsg.mBbodyEncoding != null) {
+                    mBmsg.append(BBODY_ENCODING).append(bmsg.mBbodyEncoding).append(CRLF);
+                }
+
+                if (bmsg.mBbodyCharset != null) {
+                    mBmsg.append(BBODY_CHARSET).append(bmsg.mBbodyCharset).append(CRLF);
+                }
+
+                if (bmsg.mBbodyLanguage != null) {
+                    mBmsg.append(BBODY_LANGUAGE).append(bmsg.mBbodyLanguage).append(CRLF);
+                }
+
+                mBmsg.append(BBODY_LENGTH).append(bodyLen).append(CRLF);
+
+                {
+                    mBmsg.append(MSG_BEGIN).append(CRLF);
+
+                    mBmsg.append(bmsg.mMessage).append(CRLF);
+
+                    mBmsg.append(MSG_END).append(CRLF);
+                }
+
+                mBmsg.append(BBODY_END).append(CRLF);
+            }
+
+            mBmsg.append(BENV_END).append(CRLF);
+        }
+
+        mBmsg.append(BMSG_END).append(CRLF);
+    }
+
+    private void buildVcard(VCardEntry vcard) {
+        String n = buildVcardN(vcard);
+        List<PhoneData> tel = vcard.getPhoneList();
+        List<EmailData> email = vcard.getEmailList();
+
+        mBmsg.append(VCARD_BEGIN).append(CRLF);
+
+        mBmsg.append(VCARD_VERSION).append(CRLF);
+
+        mBmsg.append(VCARD_N).append(n).append(CRLF);
+
+        if (tel != null && tel.size() > 0) {
+            mBmsg.append(VCARD_TEL).append(tel.get(0).getNumber()).append(CRLF);
+        }
+
+        if (email != null && email.size() > 0) {
+            mBmsg.append(VCARD_EMAIL).append(email.get(0).getAddress()).append(CRLF);
+        }
+
+        mBmsg.append(VCARD_END).append(CRLF);
+    }
+
+    private String buildVcardN(VCardEntry vcard) {
+        NameData nd = vcard.getNameData();
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(nd.getFamily()).append(";");
+        sb.append(nd.getGiven() == null ? "" : nd.getGiven()).append(";");
+        sb.append(nd.getMiddle() == null ? "" : nd.getMiddle()).append(";");
+        sb.append(nd.getPrefix() == null ? "" : nd.getPrefix()).append(";");
+        sb.append(nd.getSuffix() == null ? "" : nd.getSuffix());
+
+        return sb.toString();
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMapBmessageParser.java b/src/android/bluetooth/client/map/BluetoothMapBmessageParser.java
new file mode 100644
index 0000000..fa3d817
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMapBmessageParser.java
@@ -0,0 +1,421 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.util.Log;
+
+import com.android.vcard.VCardEntry;
+import com.android.vcard.VCardEntryConstructor;
+import com.android.vcard.VCardEntryHandler;
+import com.android.vcard.VCardParser;
+import com.android.vcard.VCardParser_V21;
+import com.android.vcard.VCardParser_V30;
+import com.android.vcard.exception.VCardException;
+import com.android.vcard.exception.VCardVersionException;
+import android.bluetooth.client.map.BluetoothMapBmessage.Status;
+import android.bluetooth.client.map.BluetoothMapBmessage.Type;
+import android.bluetooth.client.map.utils.BmsgTokenizer;
+import android.bluetooth.client.map.utils.BmsgTokenizer.Property;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.text.ParseException;
+
+class BluetoothMapBmessageParser {
+
+    private final static String TAG = "BluetoothMapBmessageParser";
+
+    private final static String CRLF = "\r\n";
+
+    private final static Property BEGIN_BMSG = new Property("BEGIN", "BMSG");
+    private final static Property END_BMSG = new Property("END", "BMSG");
+
+    private final static Property BEGIN_VCARD = new Property("BEGIN", "VCARD");
+    private final static Property END_VCARD = new Property("END", "VCARD");
+
+    private final static Property BEGIN_BENV = new Property("BEGIN", "BENV");
+    private final static Property END_BENV = new Property("END", "BENV");
+
+    private final static Property BEGIN_BBODY = new Property("BEGIN", "BBODY");
+    private final static Property END_BBODY = new Property("END", "BBODY");
+
+    private final static Property BEGIN_MSG = new Property("BEGIN", "MSG");
+    private final static Property END_MSG = new Property("END", "MSG");
+
+    private final static int CRLF_LEN = 2;
+
+    /*
+     * length of "container" for 'message' in bmessage-body-content:
+     * BEGIN:MSG<CRLF> + <CRLF> + END:MSG<CRFL>
+     */
+    private final static int MSG_CONTAINER_LEN = 22;
+
+    private BmsgTokenizer mParser;
+
+    private final BluetoothMapBmessage mBmsg;
+
+    private BluetoothMapBmessageParser() {
+        mBmsg = new BluetoothMapBmessage();
+    }
+
+    static public BluetoothMapBmessage createBmessage(String str) {
+        BluetoothMapBmessageParser p = new BluetoothMapBmessageParser();
+
+        try {
+            p.parse(str);
+        } catch (IOException e) {
+            Log.e(TAG, "I/O exception when parsing bMessage", e);
+            return null;
+        } catch (ParseException e) {
+            Log.e(TAG, "Cannot parse bMessage", e);
+            return null;
+        }
+
+        return p.mBmsg;
+    }
+
+    private ParseException expected(Property... props) {
+        boolean first = true;
+        StringBuilder sb = new StringBuilder();
+
+        for (Property prop : props) {
+            if (!first) {
+                sb.append(" or ");
+            }
+            sb.append(prop);
+            first = false;
+        }
+
+        return new ParseException("Expected: " + sb.toString(), mParser.pos());
+    }
+
+    private void parse(String str) throws IOException, ParseException {
+
+        Property prop;
+
+        /*
+         * <bmessage-object>::= { "BEGIN:BMSG" <CRLF> <bmessage-property>
+         * [<bmessage-originator>]* <bmessage-envelope> "END:BMSG" <CRLF> }
+         */
+
+        mParser = new BmsgTokenizer(str + CRLF);
+
+        prop = mParser.next();
+        if (!prop.equals(BEGIN_BMSG)) {
+            throw expected(BEGIN_BMSG);
+        }
+
+        prop = parseProperties();
+
+        while (prop.equals(BEGIN_VCARD)) {
+
+            /* <bmessage-originator>::= <vcard> <CRLF> */
+
+            StringBuilder vcard = new StringBuilder();
+            prop = extractVcard(vcard);
+
+            VCardEntry entry = parseVcard(vcard.toString());
+            mBmsg.mOriginators.add(entry);
+        }
+
+        if (!prop.equals(BEGIN_BENV)) {
+            throw expected(BEGIN_BENV);
+        }
+
+        prop = parseEnvelope(1);
+
+        if (!prop.equals(END_BMSG)) {
+            throw expected(END_BENV);
+        }
+
+        /*
+         * there should be no meaningful data left in stream here so we just
+         * ignore whatever is left
+         */
+
+        mParser = null;
+    }
+
+    private Property parseProperties() throws ParseException {
+
+        Property prop;
+
+        /*
+         * <bmessage-property>::=<bmessage-version-property>
+         * <bmessage-readstatus-property> <bmessage-type-property>
+         * <bmessage-folder-property> <bmessage-version-property>::="VERSION:"
+         * <common-digit>*"."<common-digit>* <CRLF>
+         * <bmessage-readstatus-property>::="STATUS:" 'readstatus' <CRLF>
+         * <bmessage-type-property>::="TYPE:" 'type' <CRLF>
+         * <bmessage-folder-property>::="FOLDER:" 'foldername' <CRLF>
+         */
+
+        do {
+            prop = mParser.next();
+
+            if (prop.name.equals("VERSION")) {
+                mBmsg.mBmsgVersion = prop.value;
+
+            } else if (prop.name.equals("STATUS")) {
+                for (Status s : Status.values()) {
+                    if (prop.value.equals(s.toString())) {
+                        mBmsg.mBmsgStatus = s;
+                        break;
+                    }
+                }
+
+            } else if (prop.name.equals("TYPE")) {
+                for (Type t : Type.values()) {
+                    if (prop.value.equals(t.toString())) {
+                        mBmsg.mBmsgType = t;
+                        break;
+                    }
+                }
+
+            } else if (prop.name.equals("FOLDER")) {
+                mBmsg.mBmsgFolder = prop.value;
+
+            }
+
+        } while (!prop.equals(BEGIN_VCARD) && !prop.equals(BEGIN_BENV));
+
+        return prop;
+    }
+
+    private Property parseEnvelope(int level) throws IOException, ParseException {
+
+        Property prop;
+
+        /*
+         * we can support as many nesting level as we want, but MAP spec clearly
+         * defines that there should be no more than 3 levels. so we verify it
+         * here.
+         */
+
+        if (level > 3) {
+            throw new ParseException("bEnvelope is nested more than 3 times", mParser.pos());
+        }
+
+        /*
+         * <bmessage-envelope> ::= { "BEGIN:BENV" <CRLF> [<bmessage-recipient>]*
+         * <bmessage-envelope> | <bmessage-content> "END:BENV" <CRLF> }
+         */
+
+        prop = mParser.next();
+
+        while (prop.equals(BEGIN_VCARD)) {
+
+            /* <bmessage-originator>::= <vcard> <CRLF> */
+
+            StringBuilder vcard = new StringBuilder();
+            prop = extractVcard(vcard);
+
+            if (level == 1) {
+                VCardEntry entry = parseVcard(vcard.toString());
+                mBmsg.mRecipients.add(entry);
+            }
+        }
+
+        if (prop.equals(BEGIN_BENV)) {
+            prop = parseEnvelope(level + 1);
+
+        } else if (prop.equals(BEGIN_BBODY)) {
+            prop = parseBody();
+
+        } else {
+            throw expected(BEGIN_BENV, BEGIN_BBODY);
+        }
+
+        if (!prop.equals(END_BENV)) {
+            throw expected(END_BENV);
+        }
+
+        return mParser.next();
+    }
+
+    private Property parseBody() throws IOException, ParseException {
+
+        Property prop;
+
+        /*
+         * <bmessage-content>::= { "BEGIN:BBODY"<CRLF> [<bmessage-body-part-ID>
+         * <CRLF>] <bmessage-body-property> <bmessage-body-content>* <CRLF>
+         * "END:BBODY"<CRLF> } <bmessage-body-part-ID>::="PARTID:" 'Part-ID'
+         * <bmessage-body-property>::=[<bmessage-body-encoding-property>]
+         * [<bmessage-body-charset-property>]
+         * [<bmessage-body-language-property>]
+         * <bmessage-body-content-length-property>
+         * <bmessage-body-encoding-property>::="ENCODING:"'encoding' <CRLF>
+         * <bmessage-body-charset-property>::="CHARSET:"'charset' <CRLF>
+         * <bmessage-body-language-property>::="LANGUAGE:"'language' <CRLF>
+         * <bmessage-body-content-length-property>::= "LENGTH:" <common-digit>*
+         * <CRLF>
+         */
+
+        do {
+            prop = mParser.next();
+
+            if (prop.name.equals("PARTID")) {
+            } else if (prop.name.equals("ENCODING")) {
+                mBmsg.mBbodyEncoding = prop.value;
+
+            } else if (prop.name.equals("CHARSET")) {
+                mBmsg.mBbodyCharset = prop.value;
+
+            } else if (prop.name.equals("LANGUAGE")) {
+                mBmsg.mBbodyLanguage = prop.value;
+
+            } else if (prop.name.equals("LENGTH")) {
+                try {
+                    mBmsg.mBbodyLength = Integer.valueOf(prop.value);
+                } catch (NumberFormatException e) {
+                    throw new ParseException("Invalid LENGTH value", mParser.pos());
+                }
+
+            }
+
+        } while (!prop.equals(BEGIN_MSG));
+
+        /*
+         * <bmessage-body-content>::={ "BEGIN:MSG"<CRLF> 'message'<CRLF>
+         * "END:MSG"<CRLF> }
+         */
+
+        int messageLen = mBmsg.mBbodyLength - MSG_CONTAINER_LEN;
+        int offset = messageLen + CRLF_LEN;
+        int restartPos = mParser.pos() + offset;
+
+        /*
+         * length is specified in bytes so we need to convert from unicode
+         * string back to bytes array
+         */
+
+        String remng = mParser.remaining();
+        byte[] data = remng.getBytes();
+
+        /* restart parsing from after 'message'<CRLF> */
+        mParser = new BmsgTokenizer(new String(data, offset, data.length - offset), restartPos);
+
+        prop = mParser.next(true);
+
+        if (prop != null && prop.equals(END_MSG)) {
+            mBmsg.mMessage = new String(data, 0, messageLen);
+        } else {
+
+            data = null;
+
+            /*
+             * now we check if bMessage can be parsed if LENGTH is handled as
+             * number of characters instead of number of bytes
+             */
+
+            Log.w(TAG, "byte LENGTH seems to be invalid, trying with char length");
+
+            mParser = new BmsgTokenizer(remng.substring(offset));
+
+            prop = mParser.next();
+
+            if (!prop.equals(END_MSG)) {
+                throw expected(END_MSG);
+            }
+
+            mBmsg.mMessage = remng.substring(0, messageLen);
+        }
+
+        prop = mParser.next();
+
+        if (!prop.equals(END_BBODY)) {
+            throw expected(END_BBODY);
+        }
+
+        return mParser.next();
+    }
+
+    private Property extractVcard(StringBuilder out) throws IOException, ParseException {
+        Property prop;
+
+        out.append(BEGIN_VCARD).append(CRLF);
+
+        do {
+            prop = mParser.next();
+            out.append(prop).append(CRLF);
+        } while (!prop.equals(END_VCARD));
+
+        return mParser.next();
+    }
+
+    private class VcardHandler implements VCardEntryHandler {
+
+        VCardEntry vcard;
+
+        @Override
+        public void onStart() {
+        }
+
+        @Override
+        public void onEntryCreated(VCardEntry entry) {
+            vcard = entry;
+        }
+
+        @Override
+        public void onEnd() {
+        }
+    };
+
+    private VCardEntry parseVcard(String str) throws IOException, ParseException {
+        VCardEntry vcard = null;
+
+        try {
+            VCardParser p = new VCardParser_V21();
+            VCardEntryConstructor c = new VCardEntryConstructor();
+            VcardHandler handler = new VcardHandler();
+            c.addEntryHandler(handler);
+            p.addInterpreter(c);
+            p.parse(new ByteArrayInputStream(str.getBytes()));
+
+            vcard = handler.vcard;
+
+        } catch (VCardVersionException e1) {
+
+            try {
+                VCardParser p = new VCardParser_V30();
+                VCardEntryConstructor c = new VCardEntryConstructor();
+                VcardHandler handler = new VcardHandler();
+                c.addEntryHandler(handler);
+                p.addInterpreter(c);
+                p.parse(new ByteArrayInputStream(str.getBytes()));
+
+                vcard = handler.vcard;
+
+            } catch (VCardVersionException e2) {
+                // will throw below
+            } catch (VCardException e2) {
+                // will throw below
+            }
+
+        } catch (VCardException e1) {
+            // will throw below
+        }
+
+        if (vcard == null) {
+            throw new ParseException("Cannot parse vCard object (neither 2.1 nor 3.0?)",
+                    mParser.pos());
+        }
+
+        return vcard;
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMapEventReport.java b/src/android/bluetooth/client/map/BluetoothMapEventReport.java
new file mode 100644
index 0000000..5963db4
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMapEventReport.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.HashMap;
+
+/**
+ * Object representation of event report received by MNS
+ * <p>
+ * This object will be received in {@link BluetoothMasClient#EVENT_EVENT_REPORT}
+ * callback message.
+ */
+public class BluetoothMapEventReport {
+
+    private final static String TAG = "BluetoothMapEventReport";
+
+    public enum Type {
+        NEW_MESSAGE("NewMessage"), DELIVERY_SUCCESS("DeliverySuccess"),
+        SENDING_SUCCESS("SendingSuccess"), DELIVERY_FAILURE("DeliveryFailure"),
+        SENDING_FAILURE("SendingFailure"), MEMORY_FULL("MemoryFull"),
+        MEMORY_AVAILABLE("MemoryAvailable"), MESSAGE_DELETED("MessageDeleted"),
+        MESSAGE_SHIFT("MessageShift");
+
+        private final String mSpecName;
+
+        private Type(String specName) {
+            mSpecName = specName;
+        }
+
+        @Override
+        public String toString() {
+            return mSpecName;
+        }
+    }
+
+    private final Type mType;
+
+    private final String mHandle;
+
+    private final String mFolder;
+
+    private final String mOldFolder;
+
+    private final BluetoothMapBmessage.Type mMsgType;
+
+    private BluetoothMapEventReport(HashMap<String, String> attrs) throws IllegalArgumentException {
+        mType = parseType(attrs.get("type"));
+
+        if (mType != Type.MEMORY_FULL && mType != Type.MEMORY_AVAILABLE) {
+            String handle = attrs.get("handle");
+            try {
+                /* just to validate */
+                new BigInteger(attrs.get("handle"), 16);
+
+                mHandle = attrs.get("handle");
+            } catch (NumberFormatException e) {
+                throw new IllegalArgumentException("Invalid value for handle:" + handle);
+            }
+        } else {
+            mHandle = null;
+        }
+
+        mFolder = attrs.get("folder");
+
+        mOldFolder = attrs.get("old_folder");
+
+        if (mType != Type.MEMORY_FULL && mType != Type.MEMORY_AVAILABLE) {
+            String s = attrs.get("msg_type");
+
+            if ("".equals(s)) {
+                // Some phones (e.g. SGS3 for MessageDeleted) send empty
+                // msg_type, in such case leave it as null rather than throw
+                // parse exception
+                mMsgType = null;
+            } else {
+                mMsgType = parseMsgType(s);
+            }
+        } else {
+            mMsgType = null;
+        }
+    }
+
+    private Type parseType(String type) throws IllegalArgumentException {
+        for (Type t : Type.values()) {
+            if (t.toString().equals(type)) {
+                return t;
+            }
+        }
+
+        throw new IllegalArgumentException("Invalid value for type: " + type);
+    }
+
+    private BluetoothMapBmessage.Type parseMsgType(String msgType) throws IllegalArgumentException {
+        for (BluetoothMapBmessage.Type t : BluetoothMapBmessage.Type.values()) {
+            if (t.name().equals(msgType)) {
+                return t;
+            }
+        }
+
+        throw new IllegalArgumentException("Invalid value for msg_type: " + msgType);
+    }
+
+    /**
+     * @return {@link BluetoothMapEventReport.Type} object corresponding to
+     *         <code>type</code> application parameter in MAP specification
+     */
+    public Type getType() {
+        return mType;
+    }
+
+    /**
+     * @return value corresponding to <code>handle</code> parameter in MAP
+     *         specification
+     */
+    public String getHandle() {
+        return mHandle;
+    }
+
+    /**
+     * @return value corresponding to <code>folder</code> parameter in MAP
+     *         specification
+     */
+    public String getFolder() {
+        return mFolder;
+    }
+
+    /**
+     * @return value corresponding to <code>old_folder</code> parameter in MAP
+     *         specification
+     */
+    public String getOldFolder() {
+        return mOldFolder;
+    }
+
+    /**
+     * @return {@link BluetoothMapBmessage.Type} object corresponding to
+     *         <code>msg_type</code> application parameter in MAP specification
+     */
+    public BluetoothMapBmessage.Type getMsgType() {
+        return mMsgType;
+    }
+
+    @Override
+    public String toString() {
+        JSONObject json = new JSONObject();
+
+        try {
+            json.put("type", mType);
+            json.put("handle", mHandle);
+            json.put("folder", mFolder);
+            json.put("old_folder", mOldFolder);
+            json.put("msg_type", mMsgType);
+        } catch (JSONException e) {
+            // do nothing
+        }
+
+        return json.toString();
+    }
+
+    static BluetoothMapEventReport fromStream(DataInputStream in) {
+        BluetoothMapEventReport ev = null;
+
+        try {
+            XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
+            xpp.setInput(in, "utf-8");
+
+            int event = xpp.getEventType();
+            while (event != XmlPullParser.END_DOCUMENT) {
+                switch (event) {
+                    case XmlPullParser.START_TAG:
+                        if (xpp.getName().equals("event")) {
+                            HashMap<String, String> attrs = new HashMap<String, String>();
+
+                            for (int i = 0; i < xpp.getAttributeCount(); i++) {
+                                attrs.put(xpp.getAttributeName(i), xpp.getAttributeValue(i));
+                            }
+
+                            ev = new BluetoothMapEventReport(attrs);
+
+                            // return immediately, only one event should be here
+                            return ev;
+                        }
+                        break;
+                }
+
+                event = xpp.next();
+            }
+
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "XML parser error when parsing XML", e);
+        } catch (IOException e) {
+            Log.e(TAG, "I/O error when parsing XML", e);
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Invalid event received", e);
+        }
+
+        return ev;
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMapFolderListing.java b/src/android/bluetooth/client/map/BluetoothMapFolderListing.java
new file mode 100644
index 0000000..f0494b3
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMapFolderListing.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+import android.util.Log;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+class BluetoothMapFolderListing {
+
+    private static final String TAG = "BluetoothMasFolderListing";
+
+    private final ArrayList<String> mFolders;
+
+    public BluetoothMapFolderListing(InputStream in) {
+        mFolders = new ArrayList<String>();
+
+        parse(in);
+    }
+
+    public void parse(InputStream in) {
+
+        try {
+            XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
+            xpp.setInput(in, "utf-8");
+
+            int event = xpp.getEventType();
+            while (event != XmlPullParser.END_DOCUMENT) {
+                switch (event) {
+                    case XmlPullParser.START_TAG:
+                        if (xpp.getName().equals("folder")) {
+                            mFolders.add(xpp.getAttributeValue(null, "name"));
+                        }
+                        break;
+                }
+
+                event = xpp.next();
+            }
+
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "XML parser error when parsing XML", e);
+        } catch (IOException e) {
+            Log.e(TAG, "I/O error when parsing XML", e);
+        }
+    }
+
+    public ArrayList<String> getList() {
+        return mFolders;
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMapMessage.java b/src/android/bluetooth/client/map/BluetoothMapMessage.java
new file mode 100644
index 0000000..6c76bbe
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMapMessage.java
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+import android.bluetooth.client.map.utils.ObexTime;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.math.BigInteger;
+import java.util.Date;
+import java.util.HashMap;
+
+/**
+ * Object representation of message received in messages listing
+ * <p>
+ * This object will be received in
+ * {@link BluetoothMasClient#EVENT_GET_MESSAGES_LISTING} callback message.
+ */
+public class BluetoothMapMessage {
+
+    private final String mHandle;
+
+    private final String mSubject;
+
+    private final Date mDateTime;
+
+    private final String mSenderName;
+
+    private final String mSenderAddressing;
+
+    private final String mReplytoAddressing;
+
+    private final String mRecipientName;
+
+    private final String mRecipientAddressing;
+
+    private final Type mType;
+
+    private final int mSize;
+
+    private final boolean mText;
+
+    private final ReceptionStatus mReceptionStatus;
+
+    private final int mAttachmentSize;
+
+    private final boolean mPriority;
+
+    private final boolean mRead;
+
+    private final boolean mSent;
+
+    private final boolean mProtected;
+
+    public enum Type {
+        UNKNOWN, EMAIL, SMS_GSM, SMS_CDMA, MMS
+    };
+
+    public enum ReceptionStatus {
+        UNKNOWN, COMPLETE, FRACTIONED, NOTIFICATION
+    }
+
+    BluetoothMapMessage(HashMap<String, String> attrs) throws IllegalArgumentException {
+        int size;
+
+        try {
+            /* just to validate */
+            new BigInteger(attrs.get("handle"), 16);
+
+            mHandle = attrs.get("handle");
+        } catch (NumberFormatException e) {
+            /*
+             * handle MUST have proper value, if it does not then throw
+             * something here
+             */
+            throw new IllegalArgumentException(e);
+        }
+
+        mSubject = attrs.get("subject");
+
+        mDateTime = (new ObexTime(attrs.get("datetime"))).getTime();
+
+        mSenderName = attrs.get("sender_name");
+
+        mSenderAddressing = attrs.get("sender_addressing");
+
+        mReplytoAddressing = attrs.get("replyto_addressing");
+
+        mRecipientName = attrs.get("recipient_name");
+
+        mRecipientAddressing = attrs.get("recipient_addressing");
+
+        mType = strToType(attrs.get("type"));
+
+        try {
+            size = Integer.parseInt(attrs.get("size"));
+        } catch (NumberFormatException e) {
+            size = 0;
+        }
+
+        mSize = size;
+
+        mText = yesnoToBoolean(attrs.get("text"));
+
+        mReceptionStatus = strToReceptionStatus(attrs.get("reception_status"));
+
+        try {
+            size = Integer.parseInt(attrs.get("attachment_size"));
+        } catch (NumberFormatException e) {
+            size = 0;
+        }
+
+        mAttachmentSize = size;
+
+        mPriority = yesnoToBoolean(attrs.get("priority"));
+
+        mRead = yesnoToBoolean(attrs.get("read"));
+
+        mSent = yesnoToBoolean(attrs.get("sent"));
+
+        mProtected = yesnoToBoolean(attrs.get("protected"));
+    }
+
+    private boolean yesnoToBoolean(String yesno) {
+        return "yes".equals(yesno);
+    }
+
+    private Type strToType(String s) {
+        if ("EMAIL".equals(s)) {
+            return Type.EMAIL;
+        } else if ("SMS_GSM".equals(s)) {
+            return Type.SMS_GSM;
+        } else if ("SMS_CDMA".equals(s)) {
+            return Type.SMS_CDMA;
+        } else if ("MMS".equals(s)) {
+            return Type.MMS;
+        }
+
+        return Type.UNKNOWN;
+    }
+
+    private ReceptionStatus strToReceptionStatus(String s) {
+        if ("complete".equals(s)) {
+            return ReceptionStatus.COMPLETE;
+        } else if ("fractioned".equals(s)) {
+            return ReceptionStatus.FRACTIONED;
+        } else if ("notification".equals(s)) {
+            return ReceptionStatus.NOTIFICATION;
+        }
+
+        return ReceptionStatus.UNKNOWN;
+    }
+
+    @Override
+    public String toString() {
+        JSONObject json = new JSONObject();
+
+        try {
+            json.put("handle", mHandle);
+            json.put("subject", mSubject);
+            json.put("datetime", mDateTime);
+            json.put("sender_name", mSenderName);
+            json.put("sender_addressing", mSenderAddressing);
+            json.put("replyto_addressing", mReplytoAddressing);
+            json.put("recipient_name", mRecipientName);
+            json.put("recipient_addressing", mRecipientAddressing);
+            json.put("type", mType);
+            json.put("size", mSize);
+            json.put("text", mText);
+            json.put("reception_status", mReceptionStatus);
+            json.put("attachment_size", mAttachmentSize);
+            json.put("priority", mPriority);
+            json.put("read", mRead);
+            json.put("sent", mSent);
+            json.put("protected", mProtected);
+        } catch (JSONException e) {
+            // do nothing
+        }
+
+        return json.toString();
+    }
+
+    /**
+     * @return value corresponding to <code>handle</code> parameter in MAP
+     *         specification
+     */
+    public String getHandle() {
+        return mHandle;
+    }
+
+    /**
+     * @return value corresponding to <code>subject</code> parameter in MAP
+     *         specification
+     */
+    public String getSubject() {
+        return mSubject;
+    }
+
+    /**
+     * @return <code>Date</code> object corresponding to <code>datetime</code>
+     *         parameter in MAP specification
+     */
+    public Date getDateTime() {
+        return mDateTime;
+    }
+
+    /**
+     * @return value corresponding to <code>sender_name</code> parameter in MAP
+     *         specification
+     */
+    public String getSenderName() {
+        return mSenderName;
+    }
+
+    /**
+     * @return value corresponding to <code>sender_addressing</code> parameter
+     *         in MAP specification
+     */
+    public String getSenderAddressing() {
+        return mSenderAddressing;
+    }
+
+    /**
+     * @return value corresponding to <code>replyto_addressing</code> parameter
+     *         in MAP specification
+     */
+    public String getReplytoAddressing() {
+        return mReplytoAddressing;
+    }
+
+    /**
+     * @return value corresponding to <code>recipient_name</code> parameter in
+     *         MAP specification
+     */
+    public String getRecipientName() {
+        return mRecipientName;
+    }
+
+    /**
+     * @return value corresponding to <code>recipient_addressing</code>
+     *         parameter in MAP specification
+     */
+    public String getRecipientAddressing() {
+        return mRecipientAddressing;
+    }
+
+    /**
+     * @return {@link Type} object corresponding to <code>type</code> parameter
+     *         in MAP specification
+     */
+    public Type getType() {
+        return mType;
+    }
+
+    /**
+     * @return value corresponding to <code>size</code> parameter in MAP
+     *         specification
+     */
+    public int getSize() {
+        return mSize;
+    }
+
+    /**
+     * @return {@link .ReceptionStatus} object corresponding to
+     *         <code>reception_status</code> parameter in MAP specification
+     */
+    public ReceptionStatus getReceptionStatus() {
+        return mReceptionStatus;
+    }
+
+    /**
+     * @return value corresponding to <code>attachment_size</code> parameter in
+     *         MAP specification
+     */
+    public int getAttachmentSize() {
+        return mAttachmentSize;
+    }
+
+    /**
+     * @return value corresponding to <code>text</code> parameter in MAP
+     *         specification
+     */
+    public boolean isText() {
+        return mText;
+    }
+
+    /**
+     * @return value corresponding to <code>priority</code> parameter in MAP
+     *         specification
+     */
+    public boolean isPriority() {
+        return mPriority;
+    }
+
+    /**
+     * @return value corresponding to <code>read</code> parameter in MAP
+     *         specification
+     */
+    public boolean isRead() {
+        return mRead;
+    }
+
+    /**
+     * @return value corresponding to <code>sent</code> parameter in MAP
+     *         specification
+     */
+    public boolean isSent() {
+        return mSent;
+    }
+
+    /**
+     * @return value corresponding to <code>protected</code> parameter in MAP
+     *         specification
+     */
+    public boolean isProtected() {
+        return mProtected;
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMapMessagesListing.java b/src/android/bluetooth/client/map/BluetoothMapMessagesListing.java
new file mode 100644
index 0000000..2fb3dea
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMapMessagesListing.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.util.Log;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+class BluetoothMapMessagesListing {
+
+    private static final String TAG = "BluetoothMapMessagesListing";
+
+    private final ArrayList<BluetoothMapMessage> mMessages;
+
+    public BluetoothMapMessagesListing(InputStream in) {
+        mMessages = new ArrayList<BluetoothMapMessage>();
+
+        parse(in);
+    }
+
+    public void parse(InputStream in) {
+
+        try {
+            XmlPullParser xpp = XmlPullParserFactory.newInstance().newPullParser();
+            xpp.setInput(in, "utf-8");
+
+            int event = xpp.getEventType();
+            while (event != XmlPullParser.END_DOCUMENT) {
+                switch (event) {
+                    case XmlPullParser.START_TAG:
+                        if (xpp.getName().equals("msg")) {
+
+                            HashMap<String, String> attrs = new HashMap<String, String>();
+
+                            for (int i = 0; i < xpp.getAttributeCount(); i++) {
+                                attrs.put(xpp.getAttributeName(i), xpp.getAttributeValue(i));
+                            }
+
+                            try {
+                                BluetoothMapMessage msg = new BluetoothMapMessage(attrs);
+                                mMessages.add(msg);
+                            } catch (IllegalArgumentException e) {
+                                /* TODO: provide something more useful here */
+                                Log.w(TAG, "Invalid <msg/>");
+                            }
+                        }
+                        break;
+                }
+
+                event = xpp.next();
+            }
+
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "XML parser error when parsing XML", e);
+        } catch (IOException e) {
+            Log.e(TAG, "I/O error when parsing XML", e);
+        }
+    }
+
+    public ArrayList<BluetoothMapMessage> getList() {
+        return mMessages;
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMapRfcommTransport.java b/src/android/bluetooth/client/map/BluetoothMapRfcommTransport.java
new file mode 100644
index 0000000..0b1b624
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMapRfcommTransport.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.bluetooth.BluetoothSocket;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.obex.ObexTransport;
+
+class BluetoothMapRfcommTransport implements ObexTransport {
+    private final BluetoothSocket mSocket;
+
+    public BluetoothMapRfcommTransport(BluetoothSocket socket) {
+        super();
+        mSocket = socket;
+    }
+
+    @Override
+    public void create() throws IOException {
+    }
+
+    @Override
+    public void listen() throws IOException {
+    }
+
+    @Override
+    public void close() throws IOException {
+        mSocket.close();
+    }
+
+    @Override
+    public void connect() throws IOException {
+    }
+
+    @Override
+    public void disconnect() throws IOException {
+    }
+
+    @Override
+    public InputStream openInputStream() throws IOException {
+        return mSocket.getInputStream();
+    }
+
+    @Override
+    public OutputStream openOutputStream() throws IOException {
+        return mSocket.getOutputStream();
+    }
+
+    @Override
+    public DataInputStream openDataInputStream() throws IOException {
+        return new DataInputStream(openInputStream());
+    }
+
+    @Override
+    public DataOutputStream openDataOutputStream() throws IOException {
+        return new DataOutputStream(openOutputStream());
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasClient.java b/src/android/bluetooth/client/map/BluetoothMasClient.java
new file mode 100644
index 0000000..7d50e5b
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasClient.java
@@ -0,0 +1,1102 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothMasInstance;
+import android.bluetooth.BluetoothSocket;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import android.bluetooth.client.map.BluetoothMasRequestSetMessageStatus.StatusIndicator;
+import android.bluetooth.client.map.utils.ObexTime;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.math.BigInteger;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+
+import javax.obex.ObexTransport;
+
+public class BluetoothMasClient {
+
+    private final static String TAG = "BluetoothMasClient";
+
+    private static final int SOCKET_CONNECTED = 10;
+
+    private static final int SOCKET_ERROR = 11;
+
+    /**
+     * Callback message sent when connection state changes
+     * <p>
+     * <code>arg1</code> is set to {@link #STATUS_OK} when connection is
+     * established successfully and {@link #STATUS_FAILED} when connection
+     * either failed or was disconnected (depends on request from application)
+     *
+     * @see #connect()
+     * @see #disconnect()
+     */
+    public static final int EVENT_CONNECT = 1;
+
+    /**
+     * Callback message sent when MSE accepted update inbox request
+     *
+     * @see #updateInbox()
+     */
+    public static final int EVENT_UPDATE_INBOX = 2;
+
+    /**
+     * Callback message sent when path is changed
+     * <p>
+     * <code>obj</code> is set to path currently set on MSE
+     *
+     * @see #setFolderRoot()
+     * @see #setFolderUp()
+     * @see #setFolderDown(String)
+     */
+    public static final int EVENT_SET_PATH = 3;
+
+    /**
+     * Callback message sent when folder listing is received
+     * <p>
+     * <code>obj</code> contains ArrayList of sub-folder names
+     *
+     * @see #getFolderListing()
+     * @see #getFolderListing(int, int)
+     */
+    public static final int EVENT_GET_FOLDER_LISTING = 4;
+
+    /**
+     * Callback message sent when folder listing size is received
+     * <p>
+     * <code>obj</code> contains number of items in folder listing
+     *
+     * @see #getFolderListingSize()
+     */
+    public static final int EVENT_GET_FOLDER_LISTING_SIZE = 5;
+
+    /**
+     * Callback message sent when messages listing is received
+     * <p>
+     * <code>obj</code> contains ArrayList of {@link BluetoothMapBmessage}
+     *
+     * @see #getMessagesListing(String, int)
+     * @see #getMessagesListing(String, int, MessagesFilter, int)
+     * @see #getMessagesListing(String, int, MessagesFilter, int, int, int)
+     */
+    public static final int EVENT_GET_MESSAGES_LISTING = 6;
+
+    /**
+     * Callback message sent when message is received
+     * <p>
+     * <code>obj</code> contains {@link BluetoothMapBmessage}
+     *
+     * @see #getMessage(String, CharsetType, boolean)
+     */
+    public static final int EVENT_GET_MESSAGE = 7;
+
+    /**
+     * Callback message sent when message status is changed
+     *
+     * @see #setMessageDeletedStatus(String, boolean)
+     * @see #setMessageReadStatus(String, boolean)
+     */
+    public static final int EVENT_SET_MESSAGE_STATUS = 8;
+
+    /**
+     * Callback message sent when message is pushed to MSE
+     * <p>
+     * <code>obj</code> contains handle of message as allocated by MSE
+     *
+     * @see #pushMessage(String, BluetoothMapBmessage, CharsetType)
+     * @see #pushMessage(String, BluetoothMapBmessage, CharsetType, boolean,
+     *      boolean)
+     */
+    public static final int EVENT_PUSH_MESSAGE = 9;
+
+    /**
+     * Callback message sent when notification status is changed
+     * <p>
+     * <code>obj</code> contains <code>1</code> if notifications are enabled and
+     * <code>0</code> otherwise
+     *
+     * @see #setNotificationRegistration(boolean)
+     */
+    public static final int EVENT_SET_NOTIFICATION_REGISTRATION = 10;
+
+    /**
+     * Callback message sent when event report is received from MSE to MNS
+     * <p>
+     * <code>obj</code> contains {@link BluetoothMapEventReport}
+     *
+     * @see #setNotificationRegistration(boolean)
+     */
+    public static final int EVENT_EVENT_REPORT = 11;
+
+    /**
+     * Callback message sent when messages listing size is received
+     * <p>
+     * <code>obj</code> contains number of items in messages listing
+     *
+     * @see #getMessagesListingSize()
+     */
+    public static final int EVENT_GET_MESSAGES_LISTING_SIZE = 12;
+
+    /**
+     * Status for callback message when request is successful
+     */
+    public static final int STATUS_OK = 0;
+
+    /**
+     * Status for callback message when request is not successful
+     */
+    public static final int STATUS_FAILED = 1;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_DEFAULT = 0x00000000;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_SUBJECT = 0x00000001;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_DATETIME = 0x00000002;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_SENDER_NAME = 0x00000004;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_SENDER_ADDRESSING = 0x00000008;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_RECIPIENT_NAME = 0x00000010;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_RECIPIENT_ADDRESSING = 0x00000020;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_TYPE = 0x00000040;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_SIZE = 0x00000080;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_RECEPTION_STATUS = 0x00000100;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_TEXT = 0x00000200;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_ATTACHMENT_SIZE = 0x00000400;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_PRIORITY = 0x00000800;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_READ = 0x00001000;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_SENT = 0x00002000;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_PROTECTED = 0x00004000;
+
+    /**
+     * Constant corresponding to <code>ParameterMask</code> application
+     * parameter value in MAP specification
+     */
+    public static final int PARAMETER_REPLYTO_ADDRESSING = 0x00008000;
+
+    public enum ConnectionState {
+        DISCONNECTED, CONNECTING, CONNECTED, DISCONNECTING;
+    }
+
+    public enum CharsetType {
+        NATIVE, UTF_8;
+    }
+
+    /** device associated with client */
+    private final BluetoothDevice mDevice;
+
+    /** MAS instance associated with client */
+    private final BluetoothMasInstance mMas;
+
+    /** callback handler to application */
+    private final Handler mCallback;
+
+    private ConnectionState mConnectionState = ConnectionState.DISCONNECTED;
+
+    private boolean mNotificationEnabled = false;
+
+    private SocketConnectThread mConnectThread = null;
+
+    private ObexTransport mObexTransport = null;
+
+    private BluetoothMasObexClientSession mObexSession = null;
+
+    private SessionHandler mSessionHandler = null;
+
+    private BluetoothMnsService mMnsService = null;
+
+    private ArrayDeque<String> mPath = null;
+
+    private static class SessionHandler extends Handler {
+
+        private final WeakReference<BluetoothMasClient> mClient;
+
+        public SessionHandler(BluetoothMasClient client) {
+            super();
+
+            mClient = new WeakReference<BluetoothMasClient>(client);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+
+            BluetoothMasClient client = mClient.get();
+            if (client == null) {
+                return;
+            }
+            Log.v(TAG, "handleMessage  "+msg.what);
+
+            switch (msg.what) {
+                case SOCKET_ERROR:
+                    client.mConnectThread = null;
+                    client.sendToClient(EVENT_CONNECT, false);
+                    break;
+
+                case SOCKET_CONNECTED:
+                    client.mConnectThread = null;
+
+                    client.mObexTransport = (ObexTransport) msg.obj;
+
+                    client.mObexSession = new BluetoothMasObexClientSession(client.mObexTransport,
+                            client.mSessionHandler);
+                    client.mObexSession.start();
+                    break;
+
+                case BluetoothMasObexClientSession.MSG_OBEX_CONNECTED:
+                    client.mPath.clear(); // we're in root after connected
+                    client.mConnectionState = ConnectionState.CONNECTED;
+                    client.sendToClient(EVENT_CONNECT, true);
+                    break;
+
+                case BluetoothMasObexClientSession.MSG_OBEX_DISCONNECTED:
+                    client.mConnectionState = ConnectionState.DISCONNECTED;
+                    client.mNotificationEnabled = false;
+                    client.mObexSession = null;
+                    client.sendToClient(EVENT_CONNECT, false);
+                    break;
+
+                case BluetoothMasObexClientSession.MSG_REQUEST_COMPLETED:
+                    BluetoothMasRequest request = (BluetoothMasRequest) msg.obj;
+                    int status = request.isSuccess() ? STATUS_OK : STATUS_FAILED;
+
+                    Log.v(TAG, "MSG_REQUEST_COMPLETED (" + status + ") for "
+                            + request.getClass().getName());
+
+                    if (request instanceof BluetoothMasRequestUpdateInbox) {
+                        client.sendToClient(EVENT_UPDATE_INBOX, request.isSuccess());
+
+                    } else if (request instanceof BluetoothMasRequestSetPath) {
+                        if (request.isSuccess()) {
+                            BluetoothMasRequestSetPath req = (BluetoothMasRequestSetPath) request;
+                            switch (req.mDir) {
+                                case UP:
+                                    if (client.mPath.size() > 0) {
+                                        client.mPath.removeLast();
+                                    }
+                                    break;
+
+                                case ROOT:
+                                    client.mPath.clear();
+                                    break;
+
+                                case DOWN:
+                                    client.mPath.addLast(req.mName);
+                                    break;
+                            }
+                        }
+
+                        client.sendToClient(EVENT_SET_PATH, request.isSuccess(),
+                                client.getCurrentPath());
+
+                    } else if (request instanceof BluetoothMasRequestGetFolderListing) {
+                        BluetoothMasRequestGetFolderListing req = (BluetoothMasRequestGetFolderListing) request;
+                        ArrayList<String> folders = req.getList();
+
+                        client.sendToClient(EVENT_GET_FOLDER_LISTING, request.isSuccess(), folders);
+
+                    } else if (request instanceof BluetoothMasRequestGetFolderListingSize) {
+                        int size = ((BluetoothMasRequestGetFolderListingSize) request).getSize();
+
+                        client.sendToClient(EVENT_GET_FOLDER_LISTING_SIZE, request.isSuccess(),
+                                size);
+
+                    } else if (request instanceof BluetoothMasRequestGetMessagesListing) {
+                        BluetoothMasRequestGetMessagesListing req = (BluetoothMasRequestGetMessagesListing) request;
+                        ArrayList<BluetoothMapMessage> msgs = req.getList();
+
+                        client.sendToClient(EVENT_GET_MESSAGES_LISTING, request.isSuccess(), msgs);
+
+                    } else if (request instanceof BluetoothMasRequestGetMessage) {
+                        BluetoothMasRequestGetMessage req = (BluetoothMasRequestGetMessage) request;
+                        BluetoothMapBmessage bmsg = req.getMessage();
+
+                        client.sendToClient(EVENT_GET_MESSAGE, request.isSuccess(), bmsg);
+
+                    } else if (request instanceof BluetoothMasRequestSetMessageStatus) {
+                        client.sendToClient(EVENT_SET_MESSAGE_STATUS, request.isSuccess());
+
+                    } else if (request instanceof BluetoothMasRequestPushMessage) {
+                        BluetoothMasRequestPushMessage req = (BluetoothMasRequestPushMessage) request;
+                        String handle = req.getMsgHandle();
+
+                        client.sendToClient(EVENT_PUSH_MESSAGE, request.isSuccess(), handle);
+
+                    } else if (request instanceof BluetoothMasRequestSetNotificationRegistration) {
+                        BluetoothMasRequestSetNotificationRegistration req = (BluetoothMasRequestSetNotificationRegistration) request;
+
+                        client.mNotificationEnabled = req.isSuccess() ? req.getStatus()
+                                : client.mNotificationEnabled;
+
+                        client.sendToClient(EVENT_SET_NOTIFICATION_REGISTRATION,
+                                request.isSuccess(),
+                                client.mNotificationEnabled ? 1 : 0);
+                    } else if (request instanceof BluetoothMasRequestGetMessagesListingSize) {
+                        int size = ((BluetoothMasRequestGetMessagesListingSize) request).getSize();
+                        client.sendToClient(EVENT_GET_MESSAGES_LISTING_SIZE, request.isSuccess(),
+                                size);
+                    }
+                    break;
+
+                case BluetoothMnsService.EVENT_REPORT:
+                    /* pass event report directly to app */
+                    client.sendToClient(EVENT_EVENT_REPORT, true, msg.obj);
+                    break;
+            }
+        }
+    }
+
+    private void sendToClient(int event, boolean success) {
+        sendToClient(event, success, null);
+    }
+
+    private void sendToClient(int event, boolean success, int param) {
+        sendToClient(event, success, Integer.valueOf(param));
+    }
+
+    private void sendToClient(int event, boolean success, Object param) {
+        if (success) {
+            mCallback.obtainMessage(event, STATUS_OK, mMas.getId(), param).sendToTarget();
+        } else {
+            mCallback.obtainMessage(event, STATUS_FAILED, mMas.getId(), null).sendToTarget();
+        }
+    }
+
+    private class SocketConnectThread extends Thread {
+        private BluetoothSocket socket = null;
+
+        public SocketConnectThread() {
+            super("SocketConnectThread");
+        }
+
+        @Override
+        public void run() {
+            try {
+                socket = mDevice.createRfcommSocket(mMas.getChannel());
+                socket.connect();
+
+                BluetoothMapRfcommTransport transport;
+                transport = new BluetoothMapRfcommTransport(socket);
+
+                mSessionHandler.obtainMessage(SOCKET_CONNECTED, transport).sendToTarget();
+            } catch (IOException e) {
+                Log.e(TAG, "Error when creating/connecting socket", e);
+
+                closeSocket();
+                mSessionHandler.obtainMessage(SOCKET_ERROR).sendToTarget();
+            }
+        }
+
+        @Override
+        public void interrupt() {
+            closeSocket();
+        }
+
+        private void closeSocket() {
+            try {
+                if (socket != null) {
+                    socket.close();
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error when closing socket", e);
+            }
+        }
+    }
+
+    /**
+     * Object representation of filters to be applied on message listing
+     *
+     * @see #getMessagesListing(String, int, MessagesFilter, int)
+     * @see #getMessagesListing(String, int, MessagesFilter, int, int, int)
+     */
+    public static final class MessagesFilter {
+
+        public final static byte MESSAGE_TYPE_ALL = 0x00;
+        public final static byte MESSAGE_TYPE_SMS_GSM = 0x01;
+        public final static byte MESSAGE_TYPE_SMS_CDMA = 0x02;
+        public final static byte MESSAGE_TYPE_EMAIL = 0x04;
+        public final static byte MESSAGE_TYPE_MMS = 0x08;
+
+        public final static byte READ_STATUS_ANY = 0x00;
+        public final static byte READ_STATUS_UNREAD = 0x01;
+        public final static byte READ_STATUS_READ = 0x02;
+
+        public final static byte PRIORITY_ANY = 0x00;
+        public final static byte PRIORITY_HIGH = 0x01;
+        public final static byte PRIORITY_NON_HIGH = 0x02;
+
+        byte messageType = MESSAGE_TYPE_ALL;
+
+        String periodBegin = null;
+
+        String periodEnd = null;
+
+        byte readStatus = READ_STATUS_ANY;
+
+        String recipient = null;
+
+        String originator = null;
+
+        byte priority = PRIORITY_ANY;
+
+        public MessagesFilter() {
+        }
+
+        public void setMessageType(byte filter) {
+            messageType = filter;
+        }
+
+        public void setPeriod(Date filterBegin, Date filterEnd) {
+            periodBegin = (new ObexTime(filterBegin)).toString();
+            periodEnd = (new ObexTime(filterEnd)).toString();
+        }
+
+        public void setReadStatus(byte readfilter) {
+            readStatus = readfilter;
+        }
+
+        public void setRecipient(String filter) {
+            if ("".equals(filter)) {
+                recipient = null;
+            } else {
+                recipient = filter;
+            }
+        }
+
+        public void setOriginator(String filter) {
+            if ("".equals(filter)) {
+                originator = null;
+            } else {
+                originator = filter;
+            }
+        }
+
+        public void setPriority(byte filter) {
+            priority = filter;
+        }
+    }
+
+    /**
+     * Constructs client object to communicate with single MAS instance on MSE
+     *
+     * @param device {@link BluetoothDevice} corresponding to remote device
+     *            acting as MSE
+     * @param mas {@link BluetoothMasInstance} object describing MAS instance on
+     *            remote device
+     * @param callback {@link Handler} object to which callback messages will be
+     *            sent Each message will have <code>arg1</code> set to either
+     *            {@link #STATUS_OK} or {@link #STATUS_FAILED} and
+     *            <code>arg2</code> to MAS instance ID. <code>obj</code> in
+     *            message is event specific.
+     */
+    public BluetoothMasClient(BluetoothDevice device, BluetoothMasInstance mas,
+            Handler callback) {
+        mDevice = device;
+        mMas = mas;
+        mCallback = callback;
+
+        mPath = new ArrayDeque<String>();
+    }
+
+    /**
+     * Retrieves MAS instance data associated with client
+     *
+     * @return instance data object
+     */
+    public BluetoothMasInstance getInstanceData() {
+        return mMas;
+    }
+
+    /**
+     * Connects to MAS instance
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_CONNECT}
+     */
+    public void connect() {
+        if (mSessionHandler == null) {
+            mSessionHandler = new SessionHandler(this);
+        }
+
+        if (mConnectThread == null && mObexSession == null) {
+            mConnectionState = ConnectionState.CONNECTING;
+
+            mConnectThread = new SocketConnectThread();
+            mConnectThread.start();
+        }
+    }
+
+    /**
+     * Disconnects from MAS instance
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_CONNECT}
+     */
+    public void disconnect() {
+        if (mConnectThread == null && mObexSession == null) {
+            return;
+        }
+
+        mConnectionState = ConnectionState.DISCONNECTING;
+
+        if (mConnectThread != null) {
+            mConnectThread.interrupt();
+        }
+
+        if (mObexSession != null) {
+            mObexSession.stop();
+        }
+    }
+
+    @Override
+    public void finalize() {
+        disconnect();
+    }
+
+    /**
+     * Gets current connection state
+     *
+     * @return current connection state
+     * @see ConnectionState
+     */
+    public ConnectionState getState() {
+        return mConnectionState;
+    }
+
+    private boolean enableNotifications() {
+        Log.v(TAG, "enableNotifications()");
+
+        if (mMnsService == null) {
+            mMnsService = new BluetoothMnsService();
+        }
+
+        mMnsService.registerCallback(mMas.getId(), mSessionHandler);
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetNotificationRegistration(true);
+        return mObexSession.makeRequest(request);
+    }
+
+    private boolean disableNotifications() {
+        Log.v(TAG, "enableNotifications()");
+
+        if (mMnsService != null) {
+            mMnsService.unregisterCallback(mMas.getId());
+        }
+
+        mMnsService = null;
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetNotificationRegistration(false);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Sets state of notifications for MAS instance
+     * <p>
+     * Once notifications are enabled, callback handler will receive
+     * {@link #EVENT_EVENT_REPORT} when new notification is received
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_SET_NOTIFICATION_REGISTRATION}
+     *
+     * @param status <code>true</code> if notifications shall be enabled,
+     *            <code>false</code> otherwise
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setNotificationRegistration(boolean status) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        if (status) {
+            return enableNotifications();
+        } else {
+            return disableNotifications();
+        }
+    }
+
+    /**
+     * Gets current state of notifications for MAS instance
+     *
+     * @return <code>true</code> if notifications are enabled,
+     *         <code>false</code> otherwise
+     */
+    public boolean getNotificationRegistration() {
+        return mNotificationEnabled;
+    }
+
+    /**
+     * Goes back to root of folder hierarchy
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_SET_PATH}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setFolderRoot() {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetPath(true);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Goes back to parent folder in folder hierarchy
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_SET_PATH}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setFolderUp() {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetPath(false);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Goes down to specified sub-folder in folder hierarchy
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_SET_PATH}
+     *
+     * @param name name of sub-folder
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setFolderDown(String name) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        if (name == null || name.isEmpty() || name.contains("/")) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetPath(name);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Gets current path in folder hierarchy
+     *
+     * @return current path
+     */
+    public String getCurrentPath() {
+        if (mPath.size() == 0) {
+            return "";
+        }
+
+        Iterator<String> iter = mPath.iterator();
+
+        StringBuilder sb = new StringBuilder(iter.next());
+
+        while (iter.hasNext()) {
+            sb.append("/").append(iter.next());
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Gets list of sub-folders in current folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_FOLDER_LISTING}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean getFolderListing() {
+        return getFolderListing((short) 0, (short) 0);
+    }
+
+    /**
+     * Gets list of sub-folders in current folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_FOLDER_LISTING}
+     *
+     * @param maxListCount maximum number of items returned or <code>0</code>
+     *            for default value
+     * @param listStartOffset index of first item returned or <code>0</code> for
+     *            default value
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     * @throws IllegalArgumentException if either maxListCount or
+     *             listStartOffset are outside allowed range [0..65535]
+     */
+    public boolean getFolderListing(int maxListCount, int listStartOffset) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestGetFolderListing(maxListCount,
+                listStartOffset);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Gets number of sub-folders in current folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_FOLDER_LISTING_SIZE}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean getFolderListingSize() {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestGetFolderListingSize();
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Gets list of messages in specified sub-folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_MESSAGES_LISTING}
+     *
+     * @param folder name of sub-folder or <code>null</code> for current folder
+     * @param parameters bit-mask specifying requested parameters in listing or
+     *            <code>0</code> for default value
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean getMessagesListing(String folder, int parameters) {
+        return getMessagesListing(folder, parameters, null, (byte) 0, 0, 0);
+    }
+
+    /**
+     * Gets list of messages in specified sub-folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_MESSAGES_LISTING}
+     *
+     * @param folder name of sub-folder or <code>null</code> for current folder
+     * @param parameters corresponds to <code>ParameterMask</code> application
+     *            parameter in MAP specification
+     * @param filter {@link MessagesFilter} object describing filters to be
+     *            applied on listing by MSE
+     * @param subjectLength maximum length of message subject in returned
+     *            listing or <code>0</code> for default value
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     * @throws IllegalArgumentException if subjectLength is outside allowed
+     *             range [0..255]
+     */
+    public boolean getMessagesListing(String folder, int parameters, MessagesFilter filter,
+            int subjectLength) {
+
+        return getMessagesListing(folder, parameters, filter, subjectLength, 0, 0);
+    }
+
+    /**
+     * Gets list of messages in specified sub-folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_MESSAGES_LISTING}
+     *
+     * @param folder name of sub-folder or <code>null</code> for current folder
+     * @param parameters corresponds to <code>ParameterMask</code> application
+     *            parameter in MAP specification
+     * @param filter {@link MessagesFilter} object describing filters to be
+     *            applied on listing by MSE
+     * @param subjectLength maximum length of message subject in returned
+     *            listing or <code>0</code> for default value
+     * @param maxListCount maximum number of items returned or <code>0</code>
+     *            for default value
+     * @param listStartOffset index of first item returned or <code>0</code> for
+     *            default value
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     * @throws IllegalArgumentException if subjectLength is outside allowed
+     *             range [0..255] or either maxListCount or listStartOffset are
+     *             outside allowed range [0..65535]
+     */
+    public boolean getMessagesListing(String folder, int parameters, MessagesFilter filter,
+            int subjectLength, int maxListCount, int listStartOffset) {
+
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestGetMessagesListing(folder,
+                parameters, filter, subjectLength, maxListCount, listStartOffset);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Gets number of messages in current folder
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_GET_MESSAGES_LISTING_SIZE}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean getMessagesListingSize() {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestGetMessagesListingSize();
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Retrieves message from MSE
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_GET_MESSAGE}
+     *
+     * @param handle handle of message to retrieve
+     * @param charset {@link CharsetType} object corresponding to
+     *            <code>Charset</code> application parameter in MAP
+     *            specification
+     * @param attachment corresponds to <code>Attachment</code> application
+     *            parameter in MAP specification
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean getMessage(String handle, CharsetType charset, boolean attachment) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        try {
+            /* just to validate */
+            new BigInteger(handle, 16);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestGetMessage(handle, charset,
+                attachment);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Sets read status of message on MSE
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_SET_MESSAGE_STATUS}
+     *
+     * @param handle handle of message
+     * @param read <code>true</code> for "read", <code>false</code> for "unread"
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setMessageReadStatus(String handle, boolean read) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        try {
+            /* just to validate */
+            new BigInteger(handle, 16);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetMessageStatus(handle,
+                StatusIndicator.READ, read);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Sets deleted status of message on MSE
+     * <p>
+     * Upon completion callback handler will receive
+     * {@link #EVENT_SET_MESSAGE_STATUS}
+     *
+     * @param handle handle of message
+     * @param deleted <code>true</code> for "deleted", <code>false</code> for
+     *            "undeleted"
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean setMessageDeletedStatus(String handle, boolean deleted) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        try {
+            /* just to validate */
+            new BigInteger(handle, 16);
+        } catch (NumberFormatException e) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestSetMessageStatus(handle,
+                StatusIndicator.DELETED, deleted);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Pushes new message to MSE
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_PUSH_MESSAGE}
+     *
+     * @param folder name of sub-folder to push to or <code>null</code> for
+     *            current folder
+     * @param charset {@link CharsetType} object corresponding to
+     *            <code>Charset</code> application parameter in MAP
+     *            specification
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean pushMessage(String folder, BluetoothMapBmessage bmsg, CharsetType charset) {
+        return pushMessage(folder, bmsg, charset, false, false);
+    }
+
+    /**
+     * Pushes new message to MSE
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_PUSH_MESSAGE}
+     *
+     * @param folder name of sub-folder to push to or <code>null</code> for
+     *            current folder
+     * @param bmsg {@link BluetoothMapBmessage} object representing message to
+     *            be pushed
+     * @param charset {@link CharsetType} object corresponding to
+     *            <code>Charset</code> application parameter in MAP
+     *            specification
+     * @param transparent corresponds to <code>Transparent</code> application
+     *            parameter in MAP specification
+     * @param retry corresponds to <code>Transparent</code> application
+     *            parameter in MAP specification
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean pushMessage(String folder, BluetoothMapBmessage bmsg, CharsetType charset,
+            boolean transparent, boolean retry) {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        String bmsgString = BluetoothMapBmessageBuilder.createBmessage(bmsg);
+
+        BluetoothMasRequest request =
+                new BluetoothMasRequestPushMessage(folder, bmsgString, charset, transparent, retry);
+        return mObexSession.makeRequest(request);
+    }
+
+    /**
+     * Requests MSE to initiate ubdate of inbox
+     * <p>
+     * Upon completion callback handler will receive {@link #EVENT_UPDATE_INBOX}
+     *
+     * @return <code>true</code> if request has been sent, <code>false</code>
+     *         otherwise
+     */
+    public boolean updateInbox() {
+        if (mObexSession == null) {
+            return false;
+        }
+
+        BluetoothMasRequest request = new BluetoothMasRequestUpdateInbox();
+        return mObexSession.makeRequest(request);
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasObexClientSession.java b/src/android/bluetooth/client/map/BluetoothMasObexClientSession.java
new file mode 100644
index 0000000..f949b8d
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasObexClientSession.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.os.Handler;
+import android.os.Process;
+import android.util.Log;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ObexTransport;
+import javax.obex.ResponseCodes;
+
+class BluetoothMasObexClientSession {
+    private static final String TAG = "BluetoothMasObexClientSession";
+
+    private static final byte[] MAS_TARGET = new byte[] {
+            (byte) 0xbb, 0x58, 0x2b, 0x40, 0x42, 0x0c, 0x11, (byte) 0xdb, (byte) 0xb0, (byte) 0xde,
+            0x08, 0x00, 0x20, 0x0c, (byte) 0x9a, 0x66
+    };
+
+    static final int MSG_OBEX_CONNECTED = 100;
+    static final int MSG_OBEX_DISCONNECTED = 101;
+    static final int MSG_REQUEST_COMPLETED = 102;
+
+    private final ObexTransport mTransport;
+
+    private final Handler mSessionHandler;
+
+    private ClientThread mClientThread;
+
+    private volatile boolean mInterrupted;
+
+    private class ClientThread extends Thread {
+        private final ObexTransport mTransport;
+
+        private ClientSession mSession;
+
+        private BluetoothMasRequest mRequest;
+
+        private boolean mConnected;
+
+        public ClientThread(ObexTransport transport) {
+            super("MAS ClientThread");
+
+            mTransport = transport;
+            mConnected = false;
+        }
+
+        @Override
+        public void run() {
+            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+
+            connect();
+
+            if (mConnected) {
+                mSessionHandler.obtainMessage(MSG_OBEX_CONNECTED).sendToTarget();
+            } else {
+                mSessionHandler.obtainMessage(MSG_OBEX_DISCONNECTED).sendToTarget();
+                return;
+            }
+
+            while (!mInterrupted) {
+                synchronized (this) {
+                    if (mRequest == null) {
+                        try {
+                            this.wait();
+                        } catch (InterruptedException e) {
+                            mInterrupted = true;
+                        }
+                    }
+                }
+
+                if (!mInterrupted && mRequest != null) {
+                    try {
+                        mRequest.execute(mSession);
+                    } catch (IOException e) {
+                        // this will "disconnect" to cleanup
+                        mInterrupted = true;
+                    }
+
+                    BluetoothMasRequest oldReq = mRequest;
+                    mRequest = null;
+
+                    mSessionHandler.obtainMessage(MSG_REQUEST_COMPLETED, oldReq).sendToTarget();
+                }
+            }
+
+            disconnect();
+
+            mSessionHandler.obtainMessage(MSG_OBEX_DISCONNECTED).sendToTarget();
+        }
+
+        private void connect() {
+            try {
+                mSession = new ClientSession(mTransport);
+
+                HeaderSet headerset = new HeaderSet();
+                headerset.setHeader(HeaderSet.TARGET, MAS_TARGET);
+
+                headerset = mSession.connect(headerset);
+
+                if (headerset.getResponseCode() == ResponseCodes.OBEX_HTTP_OK) {
+                    mConnected = true;
+                } else {
+                    disconnect();
+                }
+            } catch (IOException e) {
+            }
+        }
+
+        private void disconnect() {
+            try {
+                mSession.disconnect(null);
+            } catch (IOException e) {
+            }
+
+            try {
+                mSession.close();
+            } catch (IOException e) {
+            }
+
+            mConnected = false;
+        }
+
+        public synchronized boolean schedule(BluetoothMasRequest request) {
+            if (mRequest != null) {
+                return false;
+            }
+
+            mRequest = request;
+            notify();
+
+            return true;
+        }
+    }
+
+    public BluetoothMasObexClientSession(ObexTransport transport, Handler handler) {
+        mTransport = transport;
+        mSessionHandler = handler;
+    }
+
+    public void start() {
+        if (mClientThread == null) {
+            mClientThread = new ClientThread(mTransport);
+            mClientThread.start();
+        }
+
+    }
+
+    public void stop() {
+        if (mClientThread != null) {
+            mClientThread.interrupt();
+
+            (new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        mClientThread.join();
+                        mClientThread = null;
+                    } catch (InterruptedException e) {
+                        Log.w(TAG, "Interrupted while waiting for thread to join");
+                    }
+                }
+            }).run();
+        }
+    }
+
+    public boolean makeRequest(BluetoothMasRequest request) {
+        if (mClientThread == null) {
+            return false;
+        }
+
+        return mClientThread.schedule(request);
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequest.java b/src/android/bluetooth/client/map/BluetoothMasRequest.java
new file mode 100644
index 0000000..658a344
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.obex.ClientOperation;
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.Operation;
+import javax.obex.ResponseCodes;
+
+abstract class BluetoothMasRequest {
+
+    protected static final byte OAP_TAGID_MAX_LIST_COUNT = 0x01;
+    protected static final byte OAP_TAGID_START_OFFSET = 0x02;
+    protected static final byte OAP_TAGID_FILTER_MESSAGE_TYPE = 0x03;
+    protected static final byte OAP_TAGID_FILTER_PERIOD_BEGIN = 0x04;
+    protected static final byte OAP_TAGID_FILTER_PERIOD_END = 0x05;
+    protected static final byte OAP_TAGID_FILTER_READ_STATUS = 0x06;
+    protected static final byte OAP_TAGID_FILTER_RECIPIENT = 0x07;
+    protected static final byte OAP_TAGID_FILTER_ORIGINATOR = 0x08;
+    protected static final byte OAP_TAGID_FILTER_PRIORITY = 0x09;
+    protected static final byte OAP_TAGID_ATTACHMENT = 0x0a;
+    protected static final byte OAP_TAGID_TRANSPARENT = 0xb;
+    protected static final byte OAP_TAGID_RETRY = 0xc;
+    protected static final byte OAP_TAGID_NEW_MESSAGE = 0x0d;
+    protected static final byte OAP_TAGID_NOTIFICATION_STATUS = 0x0e;
+    protected static final byte OAP_TAGID_MAS_INSTANCE_ID = 0x0f;
+    protected static final byte OAP_TAGID_FOLDER_LISTING_SIZE = 0x11;
+    protected static final byte OAP_TAGID_MESSAGES_LISTING_SIZE = 0x12;
+    protected static final byte OAP_TAGID_SUBJECT_LENGTH = 0x13;
+    protected static final byte OAP_TAGID_CHARSET = 0x14;
+    protected static final byte OAP_TAGID_STATUS_INDICATOR = 0x17;
+    protected static final byte OAP_TAGID_STATUS_VALUE = 0x18;
+    protected static final byte OAP_TAGID_MSE_TIME = 0x19;
+
+    protected static byte NOTIFICATION_ON = 0x01;
+    protected static byte NOTIFICATION_OFF = 0x00;
+
+    protected static byte ATTACHMENT_ON = 0x01;
+    protected static byte ATTACHMENT_OFF = 0x00;
+
+    protected static byte CHARSET_NATIVE = 0x00;
+    protected static byte CHARSET_UTF8 = 0x01;
+
+    protected static byte STATUS_INDICATOR_READ = 0x00;
+    protected static byte STATUS_INDICATOR_DELETED = 0x01;
+
+    protected static byte STATUS_NO = 0x00;
+    protected static byte STATUS_YES = 0x01;
+
+    protected static byte TRANSPARENT_OFF = 0x00;
+    protected static byte TRANSPARENT_ON = 0x01;
+
+    protected static byte RETRY_OFF = 0x00;
+    protected static byte RETRY_ON = 0x01;
+
+    /* used for PUT requests which require filler byte */
+    protected static final byte[] FILLER_BYTE = {
+        0x30
+    };
+
+    protected HeaderSet mHeaderSet;
+
+    protected int mResponseCode;
+
+    public BluetoothMasRequest() {
+        mHeaderSet = new HeaderSet();
+    }
+
+    abstract public void execute(ClientSession session) throws IOException;
+
+    protected void executeGet(ClientSession session) throws IOException {
+        ClientOperation op = null;
+
+        try {
+            op = (ClientOperation) session.get(mHeaderSet);
+
+            /*
+             * MAP spec does not explicitly require that GET request should be
+             * sent in single packet but for some reason PTS complains when
+             * final GET packet with no headers follows non-final GET with all
+             * headers. So this is workaround, at least temporary. TODO: check
+             * with PTS
+             */
+            op.setGetFinalFlag(true);
+
+            /*
+             * this will trigger ClientOperation to use non-buffered stream so
+             * we can abort operation
+             */
+            op.continueOperation(true, false);
+
+            readResponseHeaders(op.getReceivedHeader());
+
+            InputStream is = op.openInputStream();
+            readResponse(is);
+            is.close();
+
+            op.close();
+
+            mResponseCode = op.getResponseCode();
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+
+            throw e;
+        }
+    }
+
+    protected void executePut(ClientSession session, byte[] body) throws IOException {
+        Operation op = null;
+
+        mHeaderSet.setHeader(HeaderSet.LENGTH, Long.valueOf(body.length));
+
+        try {
+            op = session.put(mHeaderSet);
+
+            DataOutputStream out = op.openDataOutputStream();
+            out.write(body);
+            out.close();
+
+            readResponseHeaders(op.getReceivedHeader());
+
+            op.close();
+            mResponseCode = op.getResponseCode();
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+
+            throw e;
+        }
+    }
+
+    final public boolean isSuccess() {
+        return (mResponseCode == ResponseCodes.OBEX_HTTP_OK);
+    }
+
+    protected void readResponse(InputStream stream) throws IOException {
+        /* nothing here by default */
+    }
+
+    protected void readResponseHeaders(HeaderSet headerset) {
+        /* nothing here by default */
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestGetFolderListing.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetFolderListing.java
new file mode 100644
index 0000000..bd5a2dd
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestGetFolderListing.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+import android.bluetooth.client.map.utils.ObexAppParameters;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestGetFolderListing extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-obex/folder-listing";
+
+    private BluetoothMapFolderListing mResponse = null;
+
+    public BluetoothMasRequestGetFolderListing(int maxListCount, int listStartOffset) {
+
+        if (maxListCount < 0 || maxListCount > 65535) {
+            throw new IllegalArgumentException("maxListCount should be [0..65535]");
+        }
+
+        if (listStartOffset < 0 || listStartOffset > 65535) {
+            throw new IllegalArgumentException("listStartOffset should be [0..65535]");
+        }
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        if (maxListCount > 0) {
+            oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) maxListCount);
+        }
+
+        if (listStartOffset > 0) {
+            oap.add(OAP_TAGID_START_OFFSET, (short) listStartOffset);
+        }
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) {
+        mResponse = new BluetoothMapFolderListing(stream);
+    }
+
+    public ArrayList<String> getList() {
+        if (mResponse == null) {
+            return null;
+        }
+
+        return mResponse.getList();
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestGetFolderListingSize.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetFolderListingSize.java
new file mode 100644
index 0000000..910c036
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestGetFolderListingSize.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.bluetooth.client.map.utils.ObexAppParameters;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestGetFolderListingSize extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-obex/folder-listing";
+
+    private int mSize;
+
+    public BluetoothMasRequestGetFolderListingSize() {
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+        oap.add(OAP_TAGID_MAX_LIST_COUNT, 0);
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+        mSize = oap.getShort(OAP_TAGID_FOLDER_LISTING_SIZE);
+    }
+
+    public int getSize() {
+        return mSize;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestGetMessage.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessage.java
new file mode 100644
index 0000000..b50fd0f
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessage.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.util.Log;
+
+
+import android.bluetooth.client.map.BluetoothMasClient.CharsetType;
+import android.bluetooth.client.map.utils.ObexAppParameters;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+final class BluetoothMasRequestGetMessage extends BluetoothMasRequest {
+
+    private static final String TAG = "BluetoothMasRequestGetMessage";
+
+    private static final String TYPE = "x-bt/message";
+
+    private BluetoothMapBmessage mBmessage;
+
+    public BluetoothMasRequestGetMessage(String handle, CharsetType charset, boolean attachment) {
+
+        mHeaderSet.setHeader(HeaderSet.NAME, handle);
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        oap.add(OAP_TAGID_CHARSET, CharsetType.UTF_8.equals(charset) ? CHARSET_UTF8
+                : CHARSET_NATIVE);
+
+        oap.add(OAP_TAGID_ATTACHMENT, attachment ? ATTACHMENT_ON : ATTACHMENT_OFF);
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) {
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] buf = new byte[1024];
+
+        try {
+            int len;
+            while ((len = stream.read(buf)) != -1) {
+                baos.write(buf, 0, len);
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "I/O exception while reading response", e);
+        }
+
+        String bmsg = baos.toString();
+
+        mBmessage = BluetoothMapBmessageParser.createBmessage(bmsg);
+
+        if (mBmessage == null) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+    }
+
+    public BluetoothMapBmessage getMessage() {
+        return mBmessage;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListing.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListing.java
new file mode 100644
index 0000000..d5460f9
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListing.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.bluetooth.client.map.BluetoothMasClient.MessagesFilter;
+import android.bluetooth.client.map.utils.ObexAppParameters;
+import android.bluetooth.client.map.utils.ObexTime;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Date;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestGetMessagesListing extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-bt/MAP-msg-listing";
+
+    private BluetoothMapMessagesListing mResponse = null;
+
+    private boolean mNewMessage = false;
+
+    private Date mServerTime = null;
+
+    public BluetoothMasRequestGetMessagesListing(String folderName, int parameters,
+            BluetoothMasClient.MessagesFilter filter, int subjectLength, int maxListCount,
+            int listStartOffset) {
+
+        if (subjectLength < 0 || subjectLength > 255) {
+            throw new IllegalArgumentException("subjectLength should be [0..255]");
+        }
+
+        if (maxListCount < 0 || maxListCount > 65535) {
+            throw new IllegalArgumentException("maxListCount should be [0..65535]");
+        }
+
+        if (listStartOffset < 0 || listStartOffset > 65535) {
+            throw new IllegalArgumentException("listStartOffset should be [0..65535]");
+        }
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        if (folderName == null) {
+            mHeaderSet.setHeader(HeaderSet.NAME, "");
+        } else {
+            mHeaderSet.setHeader(HeaderSet.NAME, folderName);
+        }
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        if (filter != null) {
+            if (filter.messageType != MessagesFilter.MESSAGE_TYPE_ALL) {
+                oap.add(OAP_TAGID_FILTER_MESSAGE_TYPE, filter.messageType);
+            }
+
+            if (filter.periodBegin != null) {
+                oap.add(OAP_TAGID_FILTER_PERIOD_BEGIN, filter.periodBegin);
+            }
+
+            if (filter.periodEnd != null) {
+                oap.add(OAP_TAGID_FILTER_PERIOD_END, filter.periodEnd);
+            }
+
+            if (filter.readStatus != MessagesFilter.READ_STATUS_ANY) {
+                oap.add(OAP_TAGID_FILTER_READ_STATUS, filter.readStatus);
+            }
+
+            if (filter.recipient != null) {
+                oap.add(OAP_TAGID_FILTER_RECIPIENT, filter.recipient);
+            }
+
+            if (filter.originator != null) {
+                oap.add(OAP_TAGID_FILTER_ORIGINATOR, filter.originator);
+            }
+
+            if (filter.priority != MessagesFilter.PRIORITY_ANY) {
+                oap.add(OAP_TAGID_FILTER_PRIORITY, filter.priority);
+            }
+        }
+
+        if (subjectLength != 0) {
+            oap.add(OAP_TAGID_SUBJECT_LENGTH, (byte) subjectLength);
+        }
+
+        if (maxListCount != 0) {
+            oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) maxListCount);
+        }
+
+        if (listStartOffset != 0) {
+            oap.add(OAP_TAGID_START_OFFSET, (short) listStartOffset);
+        }
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) {
+        mResponse = new BluetoothMapMessagesListing(stream);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+        mNewMessage = ((oap.getByte(OAP_TAGID_NEW_MESSAGE) & 0x01) == 1);
+
+        if (oap.exists(OAP_TAGID_MSE_TIME)) {
+            String mseTime = oap.getString(OAP_TAGID_MSE_TIME);
+
+            mServerTime = (new ObexTime(mseTime)).getTime();
+        }
+    }
+
+    public ArrayList<BluetoothMapMessage> getList() {
+        if (mResponse == null) {
+            return null;
+        }
+
+        return mResponse.getList();
+    }
+
+    public boolean getNewMessageStatus() {
+        return mNewMessage;
+    }
+
+    public Date getMseTime() {
+        return mServerTime;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListingSize.java b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListingSize.java
new file mode 100644
index 0000000..cdadb2e
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestGetMessagesListingSize.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import  android.bluetooth.client.map.utils.ObexAppParameters;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestGetMessagesListingSize extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-bt/MAP-msg-listing";
+
+    private int mSize;
+
+    public BluetoothMasRequestGetMessagesListingSize() {
+        mHeaderSet.setHeader(HeaderSet.NAME, "");
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+        oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) 0);
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+        mSize = oap.getShort(OAP_TAGID_MESSAGES_LISTING_SIZE);
+    }
+
+    public int getSize() {
+        return mSize;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executeGet(session);
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestPushMessage.java b/src/android/bluetooth/client/map/BluetoothMasRequestPushMessage.java
new file mode 100644
index 0000000..8fc9bd4
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestPushMessage.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import java.io.IOException;
+import java.math.BigInteger;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+import android.bluetooth.client.map.BluetoothMasClient.CharsetType;
+import android.bluetooth.client.map.utils.ObexAppParameters;
+
+final class BluetoothMasRequestPushMessage extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-bt/message";
+    private String mMsg;
+    private String mMsgHandle;
+
+    private BluetoothMasRequestPushMessage(String folder) {
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+        if (folder == null) {
+            folder = "";
+        }
+        mHeaderSet.setHeader(HeaderSet.NAME, folder);
+    }
+
+    public BluetoothMasRequestPushMessage(String folder, String msg, CharsetType charset,
+            boolean transparent, boolean retry) {
+        this(folder);
+        mMsg = msg;
+        ObexAppParameters oap = new ObexAppParameters();
+        oap.add(OAP_TAGID_TRANSPARENT, transparent ? TRANSPARENT_ON : TRANSPARENT_OFF);
+        oap.add(OAP_TAGID_RETRY, retry ? RETRY_ON : RETRY_OFF);
+        oap.add(OAP_TAGID_CHARSET, charset == CharsetType.NATIVE ? CHARSET_NATIVE : CHARSET_UTF8);
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        try {
+            String handle = (String) headerset.getHeader(HeaderSet.NAME);
+            if (handle != null) {
+                /* just to validate */
+                new BigInteger(handle, 16);
+
+                mMsgHandle = handle;
+            }
+        } catch (NumberFormatException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+    }
+
+    public String getMsgHandle() {
+        return mMsgHandle;
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executePut(session, mMsg.getBytes());
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestSetMessageStatus.java b/src/android/bluetooth/client/map/BluetoothMasRequestSetMessageStatus.java
new file mode 100644
index 0000000..140312e
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestSetMessageStatus.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.bluetooth.client.map.utils.ObexAppParameters;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestSetMessageStatus extends BluetoothMasRequest {
+
+    public enum StatusIndicator {
+        READ, DELETED;
+    }
+
+    private static final String TYPE = "x-bt/messageStatus";
+
+    public BluetoothMasRequestSetMessageStatus(String handle, StatusIndicator statusInd,
+            boolean statusValue) {
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+        mHeaderSet.setHeader(HeaderSet.NAME, handle);
+
+        ObexAppParameters oap = new ObexAppParameters();
+        oap.add(OAP_TAGID_STATUS_INDICATOR,
+                statusInd == StatusIndicator.READ ? STATUS_INDICATOR_READ
+                        : STATUS_INDICATOR_DELETED);
+        oap.add(OAP_TAGID_STATUS_VALUE, statusValue ? STATUS_YES : STATUS_NO);
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executePut(session, FILLER_BYTE);
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestSetNotificationRegistration.java b/src/android/bluetooth/client/map/BluetoothMasRequestSetNotificationRegistration.java
new file mode 100644
index 0000000..debb508
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestSetNotificationRegistration.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.bluetooth.client.map.utils.ObexAppParameters;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestSetNotificationRegistration extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-bt/MAP-NotificationRegistration";
+
+    private final boolean mStatus;
+
+    public BluetoothMasRequestSetNotificationRegistration(boolean status) {
+        mStatus = status;
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        oap.add(OAP_TAGID_NOTIFICATION_STATUS, status ? NOTIFICATION_ON : NOTIFICATION_OFF);
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executePut(session, FILLER_BYTE);
+    }
+
+    public boolean getStatus() {
+        return mStatus;
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestSetPath.java b/src/android/bluetooth/client/map/BluetoothMasRequestSetPath.java
new file mode 100644
index 0000000..71e2dbe
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestSetPath.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+class BluetoothMasRequestSetPath extends BluetoothMasRequest {
+
+    enum SetPathDir {
+        ROOT, UP, DOWN
+    };
+
+    SetPathDir mDir;
+
+    String mName;
+
+    public BluetoothMasRequestSetPath(String name) {
+        mDir = SetPathDir.DOWN;
+        mName = name;
+
+        mHeaderSet.setHeader(HeaderSet.NAME, name);
+    }
+
+    public BluetoothMasRequestSetPath(boolean goRoot) {
+        mHeaderSet.setEmptyNameHeader();
+        if (goRoot) {
+            mDir = SetPathDir.ROOT;
+        } else {
+            mDir = SetPathDir.UP;
+        }
+    }
+
+    @Override
+    public void execute(ClientSession session) {
+        HeaderSet hs = null;
+
+        try {
+            switch (mDir) {
+                case ROOT:
+                case DOWN:
+                    hs = session.setPath(mHeaderSet, false, false);
+                    break;
+                case UP:
+                    hs = session.setPath(mHeaderSet, true, false);
+                    break;
+            }
+
+            mResponseCode = hs.getResponseCode();
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMasRequestUpdateInbox.java b/src/android/bluetooth/client/map/BluetoothMasRequestUpdateInbox.java
new file mode 100644
index 0000000..aeec632
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMasRequestUpdateInbox.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+
+final class BluetoothMasRequestUpdateInbox extends BluetoothMasRequest {
+
+    private static final String TYPE = "x-bt/MAP-messageUpdate";
+
+    public BluetoothMasRequestUpdateInbox() {
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+    }
+
+    @Override
+    public void execute(ClientSession session) throws IOException {
+        executePut(session, FILLER_BYTE);
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMnsObexServer.java b/src/android/bluetooth/client/map/BluetoothMnsObexServer.java
new file mode 100644
index 0000000..672e9cf
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMnsObexServer.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.os.Handler;
+import android.util.Log;
+
+import android.bluetooth.client.map.utils.ObexAppParameters;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import javax.obex.HeaderSet;
+import javax.obex.Operation;
+import javax.obex.ResponseCodes;
+import javax.obex.ServerRequestHandler;
+
+class BluetoothMnsObexServer extends ServerRequestHandler {
+
+    private final static String TAG = "BluetoothMnsObexServer";
+
+    private static final byte[] MNS_TARGET = new byte[] {
+            (byte) 0xbb, 0x58, 0x2b, 0x41, 0x42, 0x0c, 0x11, (byte) 0xdb, (byte) 0xb0, (byte) 0xde,
+            0x08, 0x00, 0x20, 0x0c, (byte) 0x9a, 0x66
+    };
+
+    private final static String TYPE = "x-bt/MAP-event-report";
+
+    private final Handler mCallback;
+
+    public BluetoothMnsObexServer(Handler callback) {
+        super();
+
+        mCallback = callback;
+    }
+
+    @Override
+    public int onConnect(final HeaderSet request, HeaderSet reply) {
+        Log.v(TAG, "onConnect");
+
+        try {
+            byte[] uuid = (byte[]) request.getHeader(HeaderSet.TARGET);
+
+            if (!Arrays.equals(uuid, MNS_TARGET)) {
+                return ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE;
+            }
+
+        } catch (IOException e) {
+            // this should never happen since getHeader won't throw exception it
+            // declares to throw
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+
+        reply.setHeader(HeaderSet.WHO, MNS_TARGET);
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    @Override
+    public void onDisconnect(final HeaderSet request, HeaderSet reply) {
+        Log.v(TAG, "onDisconnect");
+    }
+
+    @Override
+    public int onGet(final Operation op) {
+        Log.v(TAG, "onGet");
+
+        return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+    }
+
+    @Override
+    public int onPut(final Operation op) {
+        Log.v(TAG, "onPut");
+
+        try {
+            HeaderSet headerset;
+            headerset = op.getReceivedHeader();
+
+            String type = (String) headerset.getHeader(HeaderSet.TYPE);
+            ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+            if (!TYPE.equals(type) || !oap.exists(BluetoothMasRequest.OAP_TAGID_MAS_INSTANCE_ID)) {
+                return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+            }
+
+            Byte inst = oap.getByte(BluetoothMasRequest.OAP_TAGID_MAS_INSTANCE_ID);
+
+            BluetoothMapEventReport ev = BluetoothMapEventReport.fromStream(op
+                    .openDataInputStream());
+
+            op.close();
+
+            mCallback.obtainMessage(BluetoothMnsService.MSG_EVENT, inst, 0, ev).sendToTarget();
+        } catch (IOException e) {
+            Log.e(TAG, "I/O exception when handling PUT request", e);
+            return ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+
+        return ResponseCodes.OBEX_HTTP_OK;
+    }
+
+    @Override
+    public int onAbort(final HeaderSet request, HeaderSet reply) {
+        Log.v(TAG, "onAbort");
+
+        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
+    }
+
+    @Override
+    public int onSetPath(final HeaderSet request, HeaderSet reply,
+            final boolean backup, final boolean create) {
+        Log.v(TAG, "onSetPath");
+
+        return ResponseCodes.OBEX_HTTP_BAD_REQUEST;
+    }
+
+    @Override
+    public void onClose() {
+        Log.v(TAG, "onClose");
+
+        // TODO: call session handler so it can disconnect
+    }
+}
diff --git a/src/android/bluetooth/client/map/BluetoothMnsService.java b/src/android/bluetooth/client/map/BluetoothMnsService.java
new file mode 100644
index 0000000..42175e0
--- /dev/null
+++ b/src/android/bluetooth/client/map/BluetoothMnsService.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothSocket;
+import android.os.Handler;
+import android.os.Message;
+import android.os.ParcelUuid;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.lang.ref.WeakReference;
+
+import javax.obex.ServerSession;
+
+class BluetoothMnsService {
+
+    private static final String TAG = "BluetoothMnsService";
+
+    private static final ParcelUuid MAP_MNS =
+            ParcelUuid.fromString("00001133-0000-1000-8000-00805F9B34FB");
+
+    static final int MSG_EVENT = 1;
+
+    /* for BluetoothMasClient */
+    static final int EVENT_REPORT = 1001;
+
+    /* these are shared across instances */
+    static private SparseArray<Handler> mCallbacks = null;
+    static private SocketAcceptThread mAcceptThread = null;
+    static private Handler mSessionHandler = null;
+    static private BluetoothServerSocket mServerSocket = null;
+
+    private static class SessionHandler extends Handler {
+
+        private final WeakReference<BluetoothMnsService> mService;
+
+        SessionHandler(BluetoothMnsService service) {
+            mService = new WeakReference<BluetoothMnsService>(service);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            Log.d(TAG, "Handler: msg: " + msg.what);
+
+            switch (msg.what) {
+                case MSG_EVENT:
+                    int instanceId = msg.arg1;
+
+                    synchronized (mCallbacks) {
+                        Handler cb = mCallbacks.get(instanceId);
+
+                        if (cb != null) {
+                            BluetoothMapEventReport ev = (BluetoothMapEventReport) msg.obj;
+                            cb.obtainMessage(EVENT_REPORT, ev).sendToTarget();
+                        } else {
+                            Log.w(TAG, "Got event for instance which is not registered: "
+                                    + instanceId);
+                        }
+                    }
+                    break;
+            }
+        }
+    }
+
+    private static class SocketAcceptThread extends Thread {
+
+        private boolean mInterrupted = false;
+
+        @Override
+        public void run() {
+
+            if (mServerSocket != null) {
+                Log.w(TAG, "Socket already created, exiting");
+                return;
+            }
+
+            try {
+                BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+                mServerSocket = adapter.listenUsingEncryptedRfcommWithServiceRecord(
+                        "MAP Message Notification Service", MAP_MNS.getUuid());
+            } catch (IOException e) {
+                mInterrupted = true;
+                Log.e(TAG, "I/O exception when trying to create server socket", e);
+            }
+
+            while (!mInterrupted) {
+                try {
+                    Log.v(TAG, "waiting to accept connection...");
+
+                    BluetoothSocket sock = mServerSocket.accept();
+
+                    Log.v(TAG, "new incoming connection from "
+                            + sock.getRemoteDevice().getName());
+
+                    // session will live until closed by remote
+                    BluetoothMnsObexServer srv = new BluetoothMnsObexServer(mSessionHandler);
+                    BluetoothMapRfcommTransport transport = new BluetoothMapRfcommTransport(
+                            sock);
+                    new ServerSession(transport, srv, null);
+                } catch (IOException ex) {
+                    Log.v(TAG, "I/O exception when waiting to accept (aborted?)");
+                    mInterrupted = true;
+                }
+            }
+
+            if (mServerSocket != null) {
+                try {
+                    mServerSocket.close();
+                } catch (IOException e) {
+                    // do nothing
+                }
+
+                mServerSocket = null;
+            }
+        }
+    }
+
+    BluetoothMnsService() {
+        Log.v(TAG, "BluetoothMnsService()");
+
+        if (mCallbacks == null) {
+            Log.v(TAG, "BluetoothMnsService(): allocating callbacks");
+            mCallbacks = new SparseArray<Handler>();
+        }
+
+        if (mSessionHandler == null) {
+            Log.v(TAG, "BluetoothMnsService(): allocating session handler");
+            mSessionHandler = new SessionHandler(this);
+        }
+    }
+
+    public void registerCallback(int instanceId, Handler callback) {
+        Log.v(TAG, "registerCallback()");
+
+        synchronized (mCallbacks) {
+            mCallbacks.put(instanceId, callback);
+
+            if (mAcceptThread == null) {
+                Log.v(TAG, "registerCallback(): starting MNS server");
+                mAcceptThread = new SocketAcceptThread();
+                mAcceptThread.setName("BluetoothMnsAcceptThread");
+                mAcceptThread.start();
+            }
+        }
+    }
+
+    public void unregisterCallback(int instanceId) {
+        Log.v(TAG, "unregisterCallback()");
+
+        synchronized (mCallbacks) {
+            mCallbacks.remove(instanceId);
+
+            if (mCallbacks.size() == 0) {
+                Log.v(TAG, "unregisterCallback(): shutting down MNS server");
+
+                if (mServerSocket != null) {
+                    try {
+                        mServerSocket.close();
+                    } catch (IOException e) {
+                    }
+
+                    mServerSocket = null;
+                }
+
+                mAcceptThread.interrupt();
+
+                try {
+                    mAcceptThread.join(5000);
+                } catch (InterruptedException e) {
+                }
+
+                mAcceptThread = null;
+            }
+        }
+    }
+}
diff --git a/src/android/bluetooth/client/map/utils/BmsgTokenizer.java b/src/android/bluetooth/client/map/utils/BmsgTokenizer.java
new file mode 100644
index 0000000..9f23961
--- /dev/null
+++ b/src/android/bluetooth/client/map/utils/BmsgTokenizer.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map.utils;
+
+import android.util.Log;
+
+import java.text.ParseException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class BmsgTokenizer {
+
+    private final String mStr;
+
+    private final Matcher mMatcher;
+
+    private int mPos = 0;
+
+    private final int mOffset;
+
+    static public class Property {
+        public final String name;
+        public final String value;
+
+        public Property(String name, String value) {
+            if (name == null || value == null) {
+                throw new IllegalArgumentException();
+            }
+
+            this.name = name;
+            this.value = value;
+
+            Log.v("BMSG >> ", toString());
+        }
+
+        @Override
+        public String toString() {
+            return name + ":" + value;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            return ((o instanceof Property) && ((Property) o).name.equals(name) && ((Property) o).value
+                    .equals(value));
+        }
+    };
+
+    public BmsgTokenizer(String str) {
+        this(str, 0);
+    }
+
+    public BmsgTokenizer(String str, int offset) {
+        mStr = str;
+        mOffset = offset;
+        mMatcher = Pattern.compile("(([^:]*):(.*))?\r\n").matcher(str);
+        mPos = mMatcher.regionStart();
+    }
+
+    public Property next(boolean alwaysReturn) throws ParseException {
+        boolean found = false;
+
+        do {
+            mMatcher.region(mPos, mMatcher.regionEnd());
+
+            if (!mMatcher.lookingAt()) {
+                if (alwaysReturn) {
+                    return null;
+                }
+
+                throw new ParseException("Property or empty line expected", pos());
+            }
+
+            mPos = mMatcher.end();
+
+            if (mMatcher.group(1) != null) {
+                found = true;
+            }
+        } while (!found);
+
+        return new Property(mMatcher.group(2), mMatcher.group(3));
+    }
+
+    public Property next() throws ParseException {
+        return next(false);
+    }
+
+    public String remaining() {
+        return mStr.substring(mPos);
+    }
+
+    public int pos() {
+        return mPos + mOffset;
+    }
+}
diff --git a/src/android/bluetooth/client/map/utils/ObexAppParameters.java b/src/android/bluetooth/client/map/utils/ObexAppParameters.java
new file mode 100644
index 0000000..cae379b
--- /dev/null
+++ b/src/android/bluetooth/client/map/utils/ObexAppParameters.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map.utils;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.obex.HeaderSet;
+
+public final class ObexAppParameters {
+
+    private final HashMap<Byte, byte[]> mParams;
+
+    public ObexAppParameters() {
+        mParams = new HashMap<Byte, byte[]>();
+    }
+
+    public ObexAppParameters(byte[] raw) {
+        mParams = new HashMap<Byte, byte[]>();
+
+        if (raw != null) {
+            for (int i = 0; i < raw.length;) {
+                if (raw.length - i < 2) {
+                    break;
+                }
+
+                byte tag = raw[i++];
+                byte len = raw[i++];
+
+                if (raw.length - i - len < 0) {
+                    break;
+                }
+
+                byte[] val = new byte[len];
+
+                System.arraycopy(raw, i, val, 0, len);
+                this.add(tag, val);
+
+                i += len;
+            }
+        }
+    }
+
+    public static ObexAppParameters fromHeaderSet(HeaderSet headerset) {
+        try {
+            byte[] raw = (byte[]) headerset.getHeader(HeaderSet.APPLICATION_PARAMETER);
+            return new ObexAppParameters(raw);
+        } catch (IOException e) {
+            // won't happen
+        }
+
+        return null;
+    }
+
+    public byte[] getHeader() {
+        int length = 0;
+
+        for (Map.Entry<Byte, byte[]> entry : mParams.entrySet()) {
+            length += (entry.getValue().length + 2);
+        }
+
+        byte[] ret = new byte[length];
+
+        int idx = 0;
+        for (Map.Entry<Byte, byte[]> entry : mParams.entrySet()) {
+            length = entry.getValue().length;
+
+            ret[idx++] = entry.getKey();
+            ret[idx++] = (byte) length;
+            System.arraycopy(entry.getValue(), 0, ret, idx, length);
+            idx += length;
+        }
+
+        return ret;
+    }
+
+    public void addToHeaderSet(HeaderSet headerset) {
+        if (mParams.size() > 0) {
+            headerset.setHeader(HeaderSet.APPLICATION_PARAMETER, getHeader());
+        }
+    }
+
+    public boolean exists(byte tag) {
+        return mParams.containsKey(tag);
+    }
+
+    public void add(byte tag, byte val) {
+        byte[] bval = ByteBuffer.allocate(1).put(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, short val) {
+        byte[] bval = ByteBuffer.allocate(2).putShort(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, int val) {
+        byte[] bval = ByteBuffer.allocate(4).putInt(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, long val) {
+        byte[] bval = ByteBuffer.allocate(8).putLong(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, String val) {
+        byte[] bval = val.getBytes();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, byte[] bval) {
+        mParams.put(tag, bval);
+    }
+
+    public byte getByte(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null || bval.length < 1) {
+            return 0;
+        }
+
+        return ByteBuffer.wrap(bval).get();
+    }
+
+    public short getShort(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null || bval.length < 2) {
+            return 0;
+        }
+
+        return ByteBuffer.wrap(bval).getShort();
+    }
+
+    public int getInt(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null || bval.length < 4) {
+            return 0;
+        }
+
+        return ByteBuffer.wrap(bval).getInt();
+    }
+
+    public String getString(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null) {
+            return null;
+        }
+
+        return new String(bval);
+    }
+
+    public byte[] getByteArray(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        return bval;
+    }
+
+    @Override
+    public String toString() {
+        return mParams.toString();
+    }
+}
diff --git a/src/android/bluetooth/client/map/utils/ObexTime.java b/src/android/bluetooth/client/map/utils/ObexTime.java
new file mode 100644
index 0000000..b35ce81
--- /dev/null
+++ b/src/android/bluetooth/client/map/utils/ObexTime.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.map.utils;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class ObexTime {
+
+    private Date mDate;
+
+    public ObexTime(String time) {
+        /*
+         * match OBEX time string: YYYYMMDDTHHMMSS with optional UTF offset
+         * +/-hhmm
+         */
+        Pattern p = Pattern
+                .compile("(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})(([+-])(\\d{2})(\\d{2}))?");
+        Matcher m = p.matcher(time);
+
+        if (m.matches()) {
+
+            /*
+             * matched groups are numberes as follows: YYYY MM DD T HH MM SS +
+             * hh mm ^^^^ ^^ ^^ ^^ ^^ ^^ ^ ^^ ^^ 1 2 3 4 5 6 8 9 10 all groups
+             * are guaranteed to be numeric so conversion will always succeed
+             * (except group 8 which is either + or -)
+             */
+
+            Calendar cal = Calendar.getInstance();
+            cal.set(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)) - 1,
+                    Integer.parseInt(m.group(3)), Integer.parseInt(m.group(4)),
+                    Integer.parseInt(m.group(5)), Integer.parseInt(m.group(6)));
+
+            /*
+             * if 7th group is matched then we have UTC offset information
+             * included
+             */
+            if (m.group(7) != null) {
+                int ohh = Integer.parseInt(m.group(9));
+                int omm = Integer.parseInt(m.group(10));
+
+                /* time zone offset is specified in miliseconds */
+                int offset = (ohh * 60 + omm) * 60 * 1000;
+
+                if (m.group(8).equals("-")) {
+                    offset = -offset;
+                }
+
+                TimeZone tz = TimeZone.getTimeZone("UTC");
+                tz.setRawOffset(offset);
+
+                cal.setTimeZone(tz);
+            }
+
+            mDate = cal.getTime();
+        }
+    }
+
+    public ObexTime(Date date) {
+        mDate = date;
+    }
+
+    public Date getTime() {
+        return mDate;
+    }
+
+    @Override
+    public String toString() {
+        if (mDate == null) {
+            return null;
+        }
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(mDate);
+
+        /* note that months are numbered stating from 0 */
+        return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02d",
+                cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1,
+                cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY),
+                cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapCard.java b/src/android/bluetooth/client/pbap/BluetoothPbapCard.java
new file mode 100644
index 0000000..6c4fadc
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapCard.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import com.android.vcard.VCardEntry;
+import com.android.vcard.VCardEntry.EmailData;
+import com.android.vcard.VCardEntry.NameData;
+import com.android.vcard.VCardEntry.PhoneData;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.List;
+
+/**
+ * Entry representation of folder listing
+ */
+public class BluetoothPbapCard {
+
+    public final String handle;
+
+    public final String N;
+    public final String lastName;
+    public final String firstName;
+    public final String middleName;
+    public final String prefix;
+    public final String suffix;
+
+    public BluetoothPbapCard(String handle, String name) {
+        this.handle = handle;
+
+        N = name;
+
+        /*
+         * format is as for vCard N field, so we have up to 5 tokens: LastName;
+         * FirstName; MiddleName; Prefix; Suffix
+         */
+        String[] parsedName = name.split(";", 5);
+
+        lastName = parsedName.length < 1 ? null : parsedName[0];
+        firstName = parsedName.length < 2 ? null : parsedName[1];
+        middleName = parsedName.length < 3 ? null : parsedName[2];
+        prefix = parsedName.length < 4 ? null : parsedName[3];
+        suffix = parsedName.length < 5 ? null : parsedName[4];
+    }
+
+    @Override
+    public String toString() {
+        JSONObject json = new JSONObject();
+
+        try {
+            json.put("handle", handle);
+            json.put("N", N);
+            json.put("lastName", lastName);
+            json.put("firstName", firstName);
+            json.put("middleName", middleName);
+            json.put("prefix", prefix);
+            json.put("suffix", suffix);
+        } catch (JSONException e) {
+            // do nothing
+        }
+
+        return json.toString();
+    }
+
+    static public String jsonifyVcardEntry(VCardEntry vcard) {
+        JSONObject json = new JSONObject();
+
+        try {
+            NameData name = vcard.getNameData();
+            json.put("formatted", name.getFormatted());
+            json.put("family", name.getFamily());
+            json.put("given", name.getGiven());
+            json.put("middle", name.getMiddle());
+            json.put("prefix", name.getPrefix());
+            json.put("suffix", name.getSuffix());
+        } catch (JSONException e) {
+            // do nothing
+        }
+
+        try {
+            JSONArray jsonPhones = new JSONArray();
+
+            List<PhoneData> phones = vcard.getPhoneList();
+
+            if (phones != null) {
+                for (PhoneData phone : phones) {
+                    JSONObject jsonPhone = new JSONObject();
+                    jsonPhone.put("type", phone.getType());
+                    jsonPhone.put("number", phone.getNumber());
+                    jsonPhone.put("label", phone.getLabel());
+                    jsonPhone.put("is_primary", phone.isPrimary());
+
+                    jsonPhones.put(jsonPhone);
+                }
+
+                json.put("phones", jsonPhones);
+            }
+        } catch (JSONException e) {
+            // do nothing
+        }
+
+        try {
+            JSONArray jsonEmails = new JSONArray();
+
+            List<EmailData> emails = vcard.getEmailList();
+
+            if (emails != null) {
+                for (EmailData email : emails) {
+                    JSONObject jsonEmail = new JSONObject();
+                    jsonEmail.put("type", email.getType());
+                    jsonEmail.put("address", email.getAddress());
+                    jsonEmail.put("label", email.getLabel());
+                    jsonEmail.put("is_primary", email.isPrimary());
+
+                    jsonEmails.put(jsonEmail);
+                }
+
+                json.put("emails", jsonEmails);
+            }
+        } catch (JSONException e) {
+            // do nothing
+        }
+
+        return json.toString();
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapClient.java b/src/android/bluetooth/client/pbap/BluetoothPbapClient.java
new file mode 100644
index 0000000..5e212e8
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapClient.java
@@ -0,0 +1,846 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.bluetooth.BluetoothDevice;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Public API to control Phone Book Profile (PCE role only).
+ * <p>
+ * This class defines methods that shall be used by application for the
+ * retrieval of phone book objects from remote device.
+ * <p>
+ * How to connect to remote device which is acting in PSE role:
+ * <ul>
+ * <li>Create a <code>BluetoothDevice</code> object which corresponds to remote
+ * device in PSE role;
+ * <li>Create an instance of <code>BluetoothPbapClient</code> class, passing
+ * <code>BluetothDevice</code> object along with a <code>Handler</code> to it;
+ * <li>Use {@link #setPhoneBookFolderRoot}, {@link #setPhoneBookFolderUp} and
+ * {@link #setPhoneBookFolderDown} to navigate in virtual phone book folder
+ * structure
+ * <li>Use {@link #pullPhoneBookSize} or {@link #pullVcardListingSize} to
+ * retrieve the size of selected phone book
+ * <li>Use {@link #pullPhoneBook} to retrieve phone book entries
+ * <li>Use {@link #pullVcardListing} to retrieve list of entries in the phone
+ * book
+ * <li>Use {@link #pullVcardEntry} to pull single entry from the phone book
+ * </ul>
+ * Upon completion of each call above PCE will notify application if operation
+ * completed successfully (along with results) or failed.
+ * <p>
+ * Therefore, application should handle following events in its message queue
+ * handler:
+ * <ul>
+ * <li><code>EVENT_PULL_PHONE_BOOK_SIZE_DONE</code>
+ * <li><code>EVENT_PULL_VCARD_LISTING_SIZE_DONE</code>
+ * <li><code>EVENT_PULL_PHONE_BOOK_DONE</code>
+ * <li><code>EVENT_PULL_VCARD_LISTING_DONE</code>
+ * <li><code>EVENT_PULL_VCARD_ENTRY_DONE</code>
+ * <li><code>EVENT_SET_PHONE_BOOK_DONE</code>
+ * </ul>
+ * and
+ * <ul>
+ * <li><code>EVENT_PULL_PHONE_BOOK_SIZE_ERROR</code>
+ * <li><code>EVENT_PULL_VCARD_LISTING_SIZE_ERROR</code>
+ * <li><code>EVENT_PULL_PHONE_BOOK_ERROR</code>
+ * <li><code>EVENT_PULL_VCARD_LISTING_ERROR</code>
+ * <li><code>EVENT_PULL_VCARD_ENTRY_ERROR</code>
+ * <li><code>EVENT_SET_PHONE_BOOK_ERROR</code>
+ * </ul>
+ * <code>connect</code> and <code>disconnect</code> methods are introduced for
+ * testing purposes. An application does not need to use them as the session
+ * connection and disconnection happens automatically internally.
+ */
+public class BluetoothPbapClient {
+    private static final String TAG = "BluetoothPbapClient";
+
+    /**
+     * Path to local incoming calls history object
+     */
+    public static final String ICH_PATH = "telecom/ich.vcf";
+
+    /**
+     * Path to local outgoing calls history object
+     */
+    public static final String OCH_PATH = "telecom/och.vcf";
+
+    /**
+     * Path to local missed calls history object
+     */
+    public static final String MCH_PATH = "telecom/mch.vcf";
+
+    /**
+     * Path to local combined calls history object
+     */
+    public static final String CCH_PATH = "telecom/cch.vcf";
+
+    /**
+     * Path to local main phone book object
+     */
+    public static final String PB_PATH = "telecom/pb.vcf";
+
+    /**
+     * Path to incoming calls history object stored on the phone's SIM card
+     */
+    public static final String SIM_ICH_PATH = "SIM1/telecom/ich.vcf";
+
+    /**
+     * Path to outgoing calls history object stored on the phone's SIM card
+     */
+    public static final String SIM_OCH_PATH = "SIM1/telecom/och.vcf";
+
+    /**
+     * Path to missed calls history object stored on the phone's SIM card
+     */
+    public static final String SIM_MCH_PATH = "SIM1/telecom/mch.vcf";
+
+    /**
+     * Path to combined calls history object stored on the phone's SIM card
+     */
+    public static final String SIM_CCH_PATH = "SIM1/telecom/cch.vcf";
+
+    /**
+     * Path to main phone book object stored on the phone's SIM card
+     */
+    public static final String SIM_PB_PATH = "SIM1/telecom/pb.vcf";
+
+    /**
+     * Indicates to server that default sorting order shall be used for vCard
+     * listing.
+     */
+    public static final byte ORDER_BY_DEFAULT = -1;
+
+    /**
+     * Indicates to server that indexed sorting order shall be used for vCard
+     * listing.
+     */
+    public static final byte ORDER_BY_INDEXED = 0;
+
+    /**
+     * Indicates to server that alphabetical sorting order shall be used for the
+     * vCard listing.
+     */
+    public static final byte ORDER_BY_ALPHABETICAL = 1;
+
+    /**
+     * Indicates to server that phonetical (based on sound attribute) sorting
+     * order shall be used for the vCard listing.
+     */
+    public static final byte ORDER_BY_PHONETIC = 2;
+
+    /**
+     * Indicates to server that Name attribute of vCard shall be used to carry
+     * out the search operation on
+     */
+    public static final byte SEARCH_ATTR_NAME = 0;
+
+    /**
+     * Indicates to server that Number attribute of vCard shall be used to carry
+     * out the search operation on
+     */
+    public static final byte SEARCH_ATTR_NUMBER = 1;
+
+    /**
+     * Indicates to server that Sound attribute of vCard shall be used to carry
+     * out the search operation
+     */
+    public static final byte SEARCH_ATTR_SOUND = 2;
+
+    /**
+     * VCard format version 2.1
+     */
+    public static final byte VCARD_TYPE_21 = 0;
+
+    /**
+     * VCard format version 3.0
+     */
+    public static final byte VCARD_TYPE_30 = 1;
+
+    /* 64-bit mask used to filter out VCard fields */
+    // TODO: Think of extracting to separate class
+    public static final long VCARD_ATTR_VERSION = 0x000000000000000001;
+    public static final long VCARD_ATTR_FN = 0x000000000000000002;
+    public static final long VCARD_ATTR_N = 0x000000000000000004;
+    public static final long VCARD_ATTR_PHOTO = 0x000000000000000008;
+    public static final long VCARD_ATTR_BDAY = 0x000000000000000010;
+    public static final long VCARD_ATTR_ADDR = 0x000000000000000020;
+    public static final long VCARD_ATTR_LABEL = 0x000000000000000040;
+    public static final long VCARD_ATTR_TEL = 0x000000000000000080;
+    public static final long VCARD_ATTR_EMAIL = 0x000000000000000100;
+    public static final long VCARD_ATTR_MAILER = 0x000000000000000200;
+    public static final long VCARD_ATTR_TZ = 0x000000000000000400;
+    public static final long VCARD_ATTR_GEO = 0x000000000000000800;
+    public static final long VCARD_ATTR_TITLE = 0x000000000000001000;
+    public static final long VCARD_ATTR_ROLE = 0x000000000000002000;
+    public static final long VCARD_ATTR_LOGO = 0x000000000000004000;
+    public static final long VCARD_ATTR_AGENT = 0x000000000000008000;
+    public static final long VCARD_ATTR_ORG = 0x000000000000010000;
+    public static final long VCARD_ATTR_NOTE = 0x000000000000020000;
+    public static final long VCARD_ATTR_REV = 0x000000000000040000;
+    public static final long VCARD_ATTR_SOUND = 0x000000000000080000;
+    public static final long VCARD_ATTR_URL = 0x000000000000100000;
+    public static final long VCARD_ATTR_UID = 0x000000000000200000;
+    public static final long VCARD_ATTR_KEY = 0x000000000000400000;
+    public static final long VCARD_ATTR_NICKNAME = 0x000000000000800000;
+    public static final long VCARD_ATTR_CATEGORIES = 0x000000000001000000;
+    public static final long VCARD_ATTR_PROID = 0x000000000002000000;
+    public static final long VCARD_ATTR_CLASS = 0x000000000004000000;
+    public static final long VCARD_ATTR_SORT_STRING = 0x000000000008000000;
+    public static final long VCARD_ATTR_X_IRMC_CALL_DATETIME =
+            0x000000000010000000;
+
+    /**
+     * Maximal number of entries of the phone book that PCE can handle
+     */
+    public static final short MAX_LIST_COUNT = (short) 0xFFFF;
+
+    /**
+     * Event propagated upon completion of <code>setPhoneBookFolderRoot</code>,
+     * <code>setPhoneBookFolderUp</code> or <code>setPhoneBookFolderDown</code>
+     * request.
+     * <p>
+     * This event indicates that request completed successfully.
+     * @see #setPhoneBookFolderRoot
+     * @see #setPhoneBookFolderUp
+     * @see #setPhoneBookFolderDown
+     */
+    public static final int EVENT_SET_PHONE_BOOK_DONE = 1;
+
+    /**
+     * Event propagated upon completion of <code>pullPhoneBook</code> request.
+     * <p>
+     * This event carry on results of the request.
+     * <p>
+     * The resulting message contains:
+     * <table>
+     * <tr>
+     * <td><code>msg.arg1</code></td>
+     * <td>newMissedCalls parameter (only in case of missed calls history object
+     * request)</td>
+     * </tr>
+     * <tr>
+     * <td><code>msg.obj</code></td>
+     * <td>which is a list of <code>VCardEntry</code> objects</td>
+     * </tr>
+     * </table>
+     * @see #pullPhoneBook
+     */
+    public static final int EVENT_PULL_PHONE_BOOK_DONE = 2;
+
+    /**
+     * Event propagated upon completion of <code>pullVcardListing</code>
+     * request.
+     * <p>
+     * This event carry on results of the request.
+     * <p>
+     * The resulting message contains:
+     * <table>
+     * <tr>
+     * <td><code>msg.arg1</code></td>
+     * <td>newMissedCalls parameter (only in case of missed calls history object
+     * request)</td>
+     * </tr>
+     * <tr>
+     * <td><code>msg.obj</code></td>
+     * <td>which is a list of <code>BluetoothPbapCard</code> objects</td>
+     * </tr>
+     * </table>
+     * @see #pullVcardListing
+     */
+    public static final int EVENT_PULL_VCARD_LISTING_DONE = 3;
+
+    /**
+     * Event propagated upon completion of <code>pullVcardEntry</code> request.
+     * <p>
+     * This event carry on results of the request.
+     * <p>
+     * The resulting message contains:
+     * <table>
+     * <tr>
+     * <td><code>msg.obj</code></td>
+     * <td>vCard as and object of type <code>VCardEntry</code></td>
+     * </tr>
+     * </table>
+     * @see #pullVcardEntry
+     */
+    public static final int EVENT_PULL_VCARD_ENTRY_DONE = 4;
+
+    /**
+     * Event propagated upon completion of <code>pullPhoneBookSize</code>
+     * request.
+     * <p>
+     * This event carry on results of the request.
+     * <p>
+     * The resulting message contains:
+     * <table>
+     * <tr>
+     * <td><code>msg.arg1</code></td>
+     * <td>size of the phone book</td>
+     * </tr>
+     * </table>
+     * @see #pullPhoneBookSize
+     */
+    public static final int EVENT_PULL_PHONE_BOOK_SIZE_DONE = 5;
+
+    /**
+     * Event propagated upon completion of <code>pullVcardListingSize</code>
+     * request.
+     * <p>
+     * This event carry on results of the request.
+     * <p>
+     * The resulting message contains:
+     * <table>
+     * <tr>
+     * <td><code>msg.arg1</code></td>
+     * <td>size of the phone book listing</td>
+     * </tr>
+     * </table>
+     * @see #pullVcardListingSize
+     */
+    public static final int EVENT_PULL_VCARD_LISTING_SIZE_DONE = 6;
+
+    /**
+     * Event propagated upon completion of <code>setPhoneBookFolderRoot</code>,
+     * <code>setPhoneBookFolderUp</code> or <code>setPhoneBookFolderDown</code>
+     * request. This event indicates an error during operation.
+     */
+    public static final int EVENT_SET_PHONE_BOOK_ERROR = 101;
+
+    /**
+     * Event propagated upon completion of <code>pullPhoneBook</code> request.
+     * This event indicates an error during operation.
+     */
+    public static final int EVENT_PULL_PHONE_BOOK_ERROR = 102;
+
+    /**
+     * Event propagated upon completion of <code>pullVcardListing</code>
+     * request. This event indicates an error during operation.
+     */
+    public static final int EVENT_PULL_VCARD_LISTING_ERROR = 103;
+
+    /**
+     * Event propagated upon completion of <code>pullVcardEntry</code> request.
+     * This event indicates an error during operation.
+     */
+    public static final int EVENT_PULL_VCARD_ENTRY_ERROR = 104;
+
+    /**
+     * Event propagated upon completion of <code>pullPhoneBookSize</code>
+     * request. This event indicates an error during operation.
+     */
+    public static final int EVENT_PULL_PHONE_BOOK_SIZE_ERROR = 105;
+
+    /**
+     * Event propagated upon completion of <code>pullVcardListingSize</code>
+     * request. This event indicates an error during operation.
+     */
+    public static final int EVENT_PULL_VCARD_LISTING_SIZE_ERROR = 106;
+
+    /**
+     * Event propagated when PCE has been connected to PSE
+     */
+    public static final int EVENT_SESSION_CONNECTED = 201;
+
+    /**
+     * Event propagated when PCE has been disconnected from PSE
+     */
+    public static final int EVENT_SESSION_DISCONNECTED = 202;
+    public static final int EVENT_SESSION_AUTH_REQUESTED = 203;
+    public static final int EVENT_SESSION_AUTH_TIMEOUT = 204;
+
+    public enum ConnectionState {
+        DISCONNECTED, CONNECTING, CONNECTED, DISCONNECTING;
+    }
+
+    private final Handler mClientHandler;
+    private final BluetoothPbapSession mSession;
+    private ConnectionState mConnectionState = ConnectionState.DISCONNECTED;
+
+    private SessionHandler mSessionHandler;
+
+    private static class SessionHandler extends Handler {
+
+        private final WeakReference<BluetoothPbapClient> mClient;
+
+        SessionHandler(BluetoothPbapClient client) {
+            mClient = new WeakReference<BluetoothPbapClient>(client);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            Log.d(TAG, "handleMessage: what=" + msg.what);
+
+            BluetoothPbapClient client = mClient.get();
+            if (client == null) {
+                return;
+            }
+
+            switch (msg.what) {
+                case BluetoothPbapSession.REQUEST_FAILED:
+                {
+                    BluetoothPbapRequest req = (BluetoothPbapRequest) msg.obj;
+
+                    if (req instanceof BluetoothPbapRequestPullPhoneBookSize) {
+                        client.sendToClient(EVENT_PULL_PHONE_BOOK_SIZE_ERROR);
+                    } else if (req instanceof BluetoothPbapRequestPullVcardListingSize) {
+                        client.sendToClient(EVENT_PULL_VCARD_LISTING_SIZE_ERROR);
+                    } else if (req instanceof BluetoothPbapRequestPullPhoneBook) {
+                        client.sendToClient(EVENT_PULL_PHONE_BOOK_ERROR);
+                    } else if (req instanceof BluetoothPbapRequestPullVcardListing) {
+                        client.sendToClient(EVENT_PULL_VCARD_LISTING_ERROR);
+                    } else if (req instanceof BluetoothPbapRequestPullVcardEntry) {
+                        client.sendToClient(EVENT_PULL_VCARD_ENTRY_ERROR);
+                    } else if (req instanceof BluetoothPbapRequestSetPath) {
+                        client.sendToClient(EVENT_SET_PHONE_BOOK_ERROR);
+                    }
+
+                    break;
+                }
+
+                case BluetoothPbapSession.REQUEST_COMPLETED:
+                {
+                    BluetoothPbapRequest req = (BluetoothPbapRequest) msg.obj;
+
+                    if (req instanceof BluetoothPbapRequestPullPhoneBookSize) {
+                        int size = ((BluetoothPbapRequestPullPhoneBookSize) req).getSize();
+                        client.sendToClient(EVENT_PULL_PHONE_BOOK_SIZE_DONE, size);
+
+                    } else if (req instanceof BluetoothPbapRequestPullVcardListingSize) {
+                        int size = ((BluetoothPbapRequestPullVcardListingSize) req).getSize();
+                        client.sendToClient(EVENT_PULL_VCARD_LISTING_SIZE_DONE, size);
+
+                    } else if (req instanceof BluetoothPbapRequestPullPhoneBook) {
+                        BluetoothPbapRequestPullPhoneBook r = (BluetoothPbapRequestPullPhoneBook) req;
+                        client.sendToClient(EVENT_PULL_PHONE_BOOK_DONE, r.getNewMissedCalls(),
+                                r.getList());
+
+                    } else if (req instanceof BluetoothPbapRequestPullVcardListing) {
+                        BluetoothPbapRequestPullVcardListing r = (BluetoothPbapRequestPullVcardListing) req;
+                        client.sendToClient(EVENT_PULL_VCARD_LISTING_DONE, r.getNewMissedCalls(),
+                                r.getList());
+
+                    } else if (req instanceof BluetoothPbapRequestPullVcardEntry) {
+                        BluetoothPbapRequestPullVcardEntry r = (BluetoothPbapRequestPullVcardEntry) req;
+                        client.sendToClient(EVENT_PULL_VCARD_ENTRY_DONE, r.getVcard());
+
+                    } else if (req instanceof BluetoothPbapRequestSetPath) {
+                        client.sendToClient(EVENT_SET_PHONE_BOOK_DONE);
+                    }
+
+                    break;
+                }
+
+                case BluetoothPbapSession.AUTH_REQUESTED:
+                    client.sendToClient(EVENT_SESSION_AUTH_REQUESTED);
+                    break;
+
+                case BluetoothPbapSession.AUTH_TIMEOUT:
+                    client.sendToClient(EVENT_SESSION_AUTH_TIMEOUT);
+                    break;
+
+                /*
+                 * app does not need to know when session is connected since
+                 * OBEX session is managed inside BluetoothPbapSession
+                 * automatically - we add this only so app can visualize PBAP
+                 * connection status in case it wants to
+                 */
+
+                case BluetoothPbapSession.SESSION_CONNECTING:
+                    client.mConnectionState = ConnectionState.CONNECTING;
+                    break;
+
+                case BluetoothPbapSession.SESSION_CONNECTED:
+                    client.mConnectionState = ConnectionState.CONNECTED;
+                    client.sendToClient(EVENT_SESSION_CONNECTED);
+                    break;
+
+                case BluetoothPbapSession.SESSION_DISCONNECTED:
+                    client.mConnectionState = ConnectionState.DISCONNECTED;
+                    client.sendToClient(EVENT_SESSION_DISCONNECTED);
+                    break;
+            }
+        }
+    };
+
+    private void sendToClient(int eventId) {
+        sendToClient(eventId, 0, null);
+    }
+
+    private void sendToClient(int eventId, int param) {
+        sendToClient(eventId, param, null);
+    }
+
+    private void sendToClient(int eventId, Object param) {
+        sendToClient(eventId, 0, param);
+    }
+
+    private void sendToClient(int eventId, int param1, Object param2) {
+        mClientHandler.obtainMessage(eventId, param1, 0, param2).sendToTarget();
+    }
+
+    /**
+     * Constructs PCE object
+     *
+     * @param device BluetoothDevice that corresponds to remote acting in PSE
+     *            role
+     * @param handler the handle that will be used by PCE to notify events and
+     *            results to application
+     * @throws NullPointerException
+     */
+    public BluetoothPbapClient(BluetoothDevice device, Handler handler) {
+        if (device == null) {
+            throw new NullPointerException("BluetothDevice is null");
+        }
+
+        mClientHandler = handler;
+
+        mSessionHandler = new SessionHandler(this);
+
+        mSession = new BluetoothPbapSession(device, mSessionHandler);
+    }
+
+    /**
+     * Starts a pbap session. <pb> This method set up rfcomm session, obex
+     * session and waits for requests to be transfered to PSE.
+     */
+    public void connect() {
+        mSession.start();
+    }
+
+    @Override
+    public void finalize() {
+        if (mSession != null) {
+            mSession.stop();
+        }
+    }
+
+    /**
+     * Stops all the active transactions and disconnects from the server.
+     */
+    public void disconnect() {
+        mSession.stop();
+    }
+
+    /**
+     * Aborts current request, if any
+     */
+    public void abort() {
+        mSession.abort();
+    }
+
+    public ConnectionState getState() {
+        return mConnectionState;
+    }
+
+    /**
+     * Sets current folder to root
+     *
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_SET_PHONE_BOOK_DONE} or
+     *         {@link #EVENT_SET_PHONE_BOOK_ERROR} in case of failure
+     */
+    public boolean setPhoneBookFolderRoot() {
+        BluetoothPbapRequest req = new BluetoothPbapRequestSetPath(false);
+        return mSession.makeRequest(req);
+    }
+
+    /**
+     * Sets current folder to parent
+     *
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_SET_PHONE_BOOK_DONE} or
+     *         {@link #EVENT_SET_PHONE_BOOK_ERROR} in case of failure
+     */
+    public boolean setPhoneBookFolderUp() {
+        BluetoothPbapRequest req = new BluetoothPbapRequestSetPath(true);
+        return mSession.makeRequest(req);
+    }
+
+    /**
+     * Sets current folder to selected sub-folder
+     *
+     * @param folder the name of the sub-folder
+     * @return @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_SET_PHONE_BOOK_DONE} or
+     *         {@link #EVENT_SET_PHONE_BOOK_ERROR} in case of failure
+     */
+    public boolean setPhoneBookFolderDown(String folder) {
+        BluetoothPbapRequest req = new BluetoothPbapRequestSetPath(folder);
+        return mSession.makeRequest(req);
+    }
+
+    /**
+     * Requests for the number of entries in the phone book.
+     *
+     * @param pbName absolute path to the phone book
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_PHONE_BOOK_SIZE_DONE} or
+     *         {@link #EVENT_PULL_PHONE_BOOK_SIZE_ERROR} in case of failure
+     */
+    public boolean pullPhoneBookSize(String pbName) {
+        BluetoothPbapRequestPullPhoneBookSize req = new BluetoothPbapRequestPullPhoneBookSize(
+                pbName);
+
+        return mSession.makeRequest(req);
+    }
+
+    /**
+     * Requests for the number of entries in the phone book listing.
+     *
+     * @param folder the name of the folder to be retrieved
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_VCARD_LISTING_SIZE_DONE} or
+     *         {@link #EVENT_PULL_VCARD_LISTING_SIZE_ERROR} in case of failure
+     */
+    public boolean pullVcardListingSize(String folder) {
+        BluetoothPbapRequestPullVcardListingSize req = new BluetoothPbapRequestPullVcardListingSize(
+                folder);
+
+        return mSession.makeRequest(req);
+    }
+
+    /**
+     * Pulls complete phone book. This method pulls phone book which entries are
+     * of <code>VCARD_TYPE_21</code> type and each single vCard contains minimal
+     * required set of fields and the number of entries in response is not
+     * limited.
+     *
+     * @param pbName absolute path to the phone book
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_PHONE_BOOK_DONE} or
+     *         {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure
+     */
+    public boolean pullPhoneBook(String pbName) {
+        return pullPhoneBook(pbName, 0, VCARD_TYPE_21, 0, 0);
+    }
+
+    /**
+     * Pulls complete phone book. This method pulls all entries from the phone
+     * book.
+     *
+     * @param pbName absolute path to the phone book
+     * @param filter bit mask which indicates which fields of the vCard shall be
+     *            included in each entry of the resulting list
+     * @param format vCard format of entries in the resulting list
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_PHONE_BOOK_DONE} or
+     *         {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure
+     */
+    public boolean pullPhoneBook(String pbName, long filter, byte format) {
+        return pullPhoneBook(pbName, filter, format, 0, 0);
+    }
+
+    /**
+     * Pulls complete phone book. This method pulls entries from the phone book
+     * limited to the number of <code>maxListCount</code> starting from the
+     * position of <code>listStartOffset</code>.
+     * <p>
+     * The resulting list contains vCard objects in version
+     * <code>VCARD_TYPE_21</code> which in turns contain minimal required set of
+     * vCard fields.
+     *
+     * @param pbName absolute path to the phone book
+     * @param maxListCount limits number of entries in the response
+     * @param listStartOffset offset to the first entry of the list that would
+     *            be returned
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_PHONE_BOOK_DONE} or
+     *         {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure
+     */
+    public boolean pullPhoneBook(String pbName, int maxListCount, int listStartOffset) {
+        return pullPhoneBook(pbName, 0, VCARD_TYPE_21, maxListCount, listStartOffset);
+    }
+
+    /**
+     * Pulls complete phone book.
+     *
+     * @param pbName absolute path to the phone book
+     * @param filter bit mask which indicates which fields of the vCard hall be
+     *            included in each entry of the resulting list
+     * @param format vCard format of entries in the resulting list
+     * @param maxListCount limits number of entries in the response
+     * @param listStartOffset offset to the first entry of the list that would
+     *            be returned
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_PHONE_BOOK_DONE} or
+     *         {@link #EVENT_PULL_PHONE_BOOK_ERROR} in case of failure
+     */
+    public boolean pullPhoneBook(String pbName, long filter, byte format, int maxListCount,
+            int listStartOffset) {
+        BluetoothPbapRequest req = new BluetoothPbapRequestPullPhoneBook(pbName, filter, format,
+                maxListCount, listStartOffset);
+        return mSession.makeRequest(req);
+    }
+
+    /**
+     * Pulls list of entries in the phone book.
+     * <p>
+     * This method pulls the list of entries in the <code>folder</code>.
+     *
+     * @param folder the name of the folder to be retrieved
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
+     *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
+     */
+    public boolean pullVcardListing(String folder) {
+        return pullVcardListing(folder, ORDER_BY_DEFAULT, SEARCH_ATTR_NAME, null, 0, 0);
+    }
+
+    /**
+     * Pulls list of entries in the <code>folder</code>.
+     *
+     * @param folder the name of the folder to be retrieved
+     * @param order the sorting order of the resulting list of entries
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
+     *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
+     */
+    public boolean pullVcardListing(String folder, byte order) {
+        return pullVcardListing(folder, order, SEARCH_ATTR_NAME, null, 0, 0);
+    }
+
+    /**
+     * Pulls list of entries in the <code>folder</code>. Only entries where
+     * <code>searchAttr</code> attribute of vCard matches <code>searchVal</code>
+     * will be listed.
+     *
+     * @param folder the name of the folder to be retrieved
+     * @param searchAttr vCard attribute which shall be used to carry out search
+     *            operation on
+     * @param searchVal text string used by matching routine to match the value
+     *            of the attribute indicated by SearchAttr
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
+     *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
+     */
+    public boolean pullVcardListing(String folder, byte searchAttr, String searchVal) {
+        return pullVcardListing(folder, ORDER_BY_DEFAULT, searchAttr, searchVal, 0, 0);
+    }
+
+    /**
+     * Pulls list of entries in the <code>folder</code>.
+     *
+     * @param folder the name of the folder to be retrieved
+     * @param order the sorting order of the resulting list of entries
+     * @param maxListCount limits number of entries in the response
+     * @param listStartOffset offset to the first entry of the list that would
+     *            be returned
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
+     *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
+     */
+    public boolean pullVcardListing(String folder, byte order, int maxListCount,
+            int listStartOffset) {
+        return pullVcardListing(folder, order, SEARCH_ATTR_NAME, null, maxListCount,
+                listStartOffset);
+    }
+
+    /**
+     * Pulls list of entries in the <code>folder</code>.
+     *
+     * @param folder the name of the folder to be retrieved
+     * @param maxListCount limits number of entries in the response
+     * @param listStartOffset offset to the first entry of the list that would
+     *            be returned
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
+     *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
+     */
+    public boolean pullVcardListing(String folder, int maxListCount, int listStartOffset) {
+        return pullVcardListing(folder, ORDER_BY_DEFAULT, SEARCH_ATTR_NAME, null, maxListCount,
+                listStartOffset);
+    }
+
+    /**
+     * Pulls list of entries in the <code>folder</code>.
+     *
+     * @param folder the name of the folder to be retrieved
+     * @param order the sorting order of the resulting list of entries
+     * @param searchAttr vCard attribute which shall be used to carry out search
+     *            operation on
+     * @param searchVal text string used by matching routine to match the value
+     *            of the attribute indicated by SearchAttr
+     * @param maxListCount limits number of entries in the response
+     * @param listStartOffset offset to the first entry of the list that would
+     *            be returned
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_VCARD_LISTING_DONE} or
+     *         {@link #EVENT_PULL_VCARD_LISTING_ERROR} in case of failure
+     */
+    public boolean pullVcardListing(String folder, byte order, byte searchAttr,
+            String searchVal, int maxListCount, int listStartOffset) {
+        BluetoothPbapRequest req = new BluetoothPbapRequestPullVcardListing(folder, order,
+                searchAttr, searchVal, maxListCount, listStartOffset);
+        return mSession.makeRequest(req);
+    }
+
+    /**
+     * Pulls single vCard object
+     *
+     * @param handle handle to the vCard which shall be pulled
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_VCARD_DONE} or
+     * @link #EVENT_PULL_VCARD_ERROR} in case of failure
+     */
+    public boolean pullVcardEntry(String handle) {
+        return pullVcardEntry(handle, (byte) 0, VCARD_TYPE_21);
+    }
+
+    /**
+     * Pulls single vCard object
+     *
+     * @param handle handle to the vCard which shall be pulled
+     * @param filter bit mask of the vCard fields that shall be included in the
+     *            resulting vCard
+     * @param format resulting vCard version
+     * @return <code>true</code> if request has been sent successfully;
+     *         <code>false</code> otherwise; upon completion PCE sends
+     *         {@link #EVENT_PULL_VCARD_DONE}
+     * @link #EVENT_PULL_VCARD_ERROR} in case of failure
+     */
+    public boolean pullVcardEntry(String handle, long filter, byte format) {
+        BluetoothPbapRequest req = new BluetoothPbapRequestPullVcardEntry(handle, filter, format);
+        return mSession.makeRequest(req);
+    }
+
+    public boolean setAuthResponse(String key) {
+        Log.d(TAG, " setAuthResponse key=" + key);
+        return mSession.setAuthResponse(key);
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapObexAuthenticator.java b/src/android/bluetooth/client/pbap/BluetoothPbapObexAuthenticator.java
new file mode 100644
index 0000000..9402e81
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapObexAuthenticator.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.os.Handler;
+import android.util.Log;
+
+import javax.obex.Authenticator;
+import javax.obex.PasswordAuthentication;
+
+class BluetoothPbapObexAuthenticator implements Authenticator {
+
+    private final static String TAG = "BluetoothPbapObexAuthenticator";
+
+    private String mSessionKey;
+
+    private boolean mReplied;
+
+    private final Handler mCallback;
+
+    public BluetoothPbapObexAuthenticator(Handler callback) {
+        mCallback = callback;
+    }
+
+    public synchronized void setReply(String key) {
+        Log.d(TAG, "setReply key=" + key);
+
+        mSessionKey = key;
+        mReplied = true;
+
+        notify();
+    }
+
+    @Override
+    public PasswordAuthentication onAuthenticationChallenge(String description,
+            boolean isUserIdRequired, boolean isFullAccess) {
+        PasswordAuthentication pa = null;
+
+        mReplied = false;
+
+        Log.d(TAG, "onAuthenticationChallenge: sending request");
+        mCallback.obtainMessage(BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_REQUEST)
+                .sendToTarget();
+
+        synchronized (this) {
+            while (!mReplied) {
+                try {
+                    Log.v(TAG, "onAuthenticationChallenge: waiting for response");
+                    this.wait();
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "Interrupted while waiting for challenge response");
+                }
+            }
+        }
+
+        if (mSessionKey != null && mSessionKey.length() != 0) {
+            Log.v(TAG, "onAuthenticationChallenge: mSessionKey=" + mSessionKey);
+            pa = new PasswordAuthentication(null, mSessionKey.getBytes());
+        } else {
+            Log.v(TAG, "onAuthenticationChallenge: mSessionKey is empty, timeout/cancel occured");
+        }
+
+        return pa;
+    }
+
+    @Override
+    public byte[] onAuthenticationResponse(byte[] userName) {
+        /* required only in case PCE challenges PSE which we don't do now */
+        return null;
+    }
+
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapObexSession.java b/src/android/bluetooth/client/pbap/BluetoothPbapObexSession.java
new file mode 100644
index 0000000..f558cc4
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapObexSession.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.os.Handler;
+import android.util.Log;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ObexTransport;
+import javax.obex.ResponseCodes;
+
+final class BluetoothPbapObexSession {
+    private static final String TAG = "BluetoothPbapObexSession";
+
+    private static final byte[] PBAP_TARGET = new byte[] {
+            0x79, 0x61, 0x35, (byte) 0xf0, (byte) 0xf0, (byte) 0xc5, 0x11, (byte) 0xd8, 0x09, 0x66,
+            0x08, 0x00, 0x20, 0x0c, (byte) 0x9a, 0x66
+    };
+
+    final static int OBEX_SESSION_CONNECTED = 100;
+    final static int OBEX_SESSION_FAILED = 101;
+    final static int OBEX_SESSION_DISCONNECTED = 102;
+    final static int OBEX_SESSION_REQUEST_COMPLETED = 103;
+    final static int OBEX_SESSION_REQUEST_FAILED = 104;
+    final static int OBEX_SESSION_AUTHENTICATION_REQUEST = 105;
+    final static int OBEX_SESSION_AUTHENTICATION_TIMEOUT = 106;
+
+    private Handler mSessionHandler;
+    private final ObexTransport mTransport;
+    private ObexClientThread mObexClientThread;
+    private BluetoothPbapObexAuthenticator mAuth = null;
+
+    public BluetoothPbapObexSession(ObexTransport transport) {
+        mTransport = transport;
+    }
+
+    public void start(Handler handler) {
+        Log.d(TAG, "start");
+        mSessionHandler = handler;
+
+        mAuth = new BluetoothPbapObexAuthenticator(mSessionHandler);
+
+        mObexClientThread = new ObexClientThread();
+        mObexClientThread.start();
+    }
+
+    public void stop() {
+        Log.d(TAG, "stop");
+
+        if (mObexClientThread != null) {
+            try {
+                mObexClientThread.interrupt();
+                mObexClientThread.join();
+                mObexClientThread = null;
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    public void abort() {
+        Log.d(TAG, "abort");
+
+        if (mObexClientThread != null && mObexClientThread.mRequest != null) {
+            /*
+             * since abort may block until complete GET is processed inside OBEX
+             * session, let's run it in separate thread so it won't block UI
+             */
+            (new Thread() {
+                @Override
+                public void run() {
+                    mObexClientThread.mRequest.abort();
+                }
+            }).run();
+        }
+    }
+
+    public boolean schedule(BluetoothPbapRequest request) {
+        Log.d(TAG, "schedule: " + request.getClass().getSimpleName());
+
+        if (mObexClientThread == null) {
+            Log.e(TAG, "OBEX session not started");
+            return false;
+        }
+
+        return mObexClientThread.schedule(request);
+    }
+
+    public boolean setAuthReply(String key) {
+        Log.d(TAG, "setAuthReply key=" + key);
+
+        if (mAuth == null) {
+            return false;
+        }
+
+        mAuth.setReply(key);
+
+        return true;
+    }
+
+    private class ObexClientThread extends Thread {
+
+        private static final String TAG = "ObexClientThread";
+
+        private ClientSession mClientSession;
+        private BluetoothPbapRequest mRequest;
+
+        private volatile boolean mRunning = true;
+
+        public ObexClientThread() {
+
+            mClientSession = null;
+            mRequest = null;
+        }
+
+        @Override
+        public void run() {
+            super.run();
+
+            if (!connect()) {
+                mSessionHandler.obtainMessage(OBEX_SESSION_FAILED).sendToTarget();
+                return;
+            }
+
+            mSessionHandler.obtainMessage(OBEX_SESSION_CONNECTED).sendToTarget();
+
+            while (mRunning) {
+                synchronized (this) {
+                    try {
+                        if (mRequest == null) {
+                            this.wait();
+                        }
+                    } catch (InterruptedException e) {
+                        mRunning = false;
+                        break;
+                    }
+                }
+
+                if (mRunning && mRequest != null) {
+                    try {
+                        mRequest.execute(mClientSession);
+                    } catch (IOException e) {
+                        // this will "disconnect" for cleanup
+                        mRunning = false;
+                    }
+
+                    if (mRequest.isSuccess()) {
+                        mSessionHandler.obtainMessage(OBEX_SESSION_REQUEST_COMPLETED, mRequest)
+                                .sendToTarget();
+                    } else {
+                        mSessionHandler.obtainMessage(OBEX_SESSION_REQUEST_FAILED, mRequest)
+                                .sendToTarget();
+                    }
+                }
+
+                mRequest = null;
+            }
+
+            disconnect();
+
+            mSessionHandler.obtainMessage(OBEX_SESSION_DISCONNECTED).sendToTarget();
+        }
+
+        public synchronized boolean schedule(BluetoothPbapRequest request) {
+            Log.d(TAG, "schedule: " + request.getClass().getSimpleName());
+
+            if (mRequest != null) {
+                return false;
+            }
+
+            mRequest = request;
+            notify();
+
+            return true;
+        }
+
+        private boolean connect() {
+            Log.d(TAG, "connect");
+
+            try {
+                mClientSession = new ClientSession(mTransport);
+                mClientSession.setAuthenticator(mAuth);
+            } catch (IOException e) {
+                return false;
+            }
+
+            HeaderSet hs = new HeaderSet();
+            hs.setHeader(HeaderSet.TARGET, PBAP_TARGET);
+
+            try {
+                hs = mClientSession.connect(hs);
+
+                if (hs.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
+                    disconnect();
+                    return false;
+                }
+            } catch (IOException e) {
+                return false;
+            }
+
+            return true;
+        }
+
+        private void disconnect() {
+            Log.d(TAG, "disconnect");
+
+            if (mClientSession != null) {
+                try {
+                    mClientSession.disconnect(null);
+                    mClientSession.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapObexTransport.java b/src/android/bluetooth/client/pbap/BluetoothPbapObexTransport.java
new file mode 100644
index 0000000..98fd9db
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapObexTransport.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.bluetooth.BluetoothSocket;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.obex.ObexTransport;
+
+class BluetoothPbapObexTransport implements ObexTransport {
+
+    private BluetoothSocket mSocket = null;
+
+    public BluetoothPbapObexTransport(BluetoothSocket rfs) {
+        super();
+        mSocket = rfs;
+    }
+
+    @Override
+    public void close() throws IOException {
+        mSocket.close();
+    }
+
+    @Override
+    public DataInputStream openDataInputStream() throws IOException {
+        return new DataInputStream(openInputStream());
+    }
+
+    @Override
+    public DataOutputStream openDataOutputStream() throws IOException {
+        return new DataOutputStream(openOutputStream());
+    }
+
+    @Override
+    public InputStream openInputStream() throws IOException {
+        return mSocket.getInputStream();
+    }
+
+    @Override
+    public OutputStream openOutputStream() throws IOException {
+        return mSocket.getOutputStream();
+    }
+
+    @Override
+    public void connect() throws IOException {
+    }
+
+    @Override
+    public void create() throws IOException {
+    }
+
+    @Override
+    public void disconnect() throws IOException {
+    }
+
+    @Override
+    public void listen() throws IOException {
+    }
+
+    public boolean isConnected() throws IOException {
+        // return true;
+        return mSocket.isConnected();
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequest.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequest.java
new file mode 100644
index 0000000..0974c75
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapRequest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.obex.ClientOperation;
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+abstract class BluetoothPbapRequest {
+
+    private static final String TAG = "BluetoothPbapRequest";
+
+    protected static final byte OAP_TAGID_ORDER = 0x01;
+    protected static final byte OAP_TAGID_SEARCH_VALUE = 0x02;
+    protected static final byte OAP_TAGID_SEARCH_ATTRIBUTE = 0x03;
+    protected static final byte OAP_TAGID_MAX_LIST_COUNT = 0x04;
+    protected static final byte OAP_TAGID_LIST_START_OFFSET = 0x05;
+    protected static final byte OAP_TAGID_FILTER = 0x06;
+    protected static final byte OAP_TAGID_FORMAT = 0x07;
+    protected static final byte OAP_TAGID_PHONEBOOK_SIZE = 0x08;
+    protected static final byte OAP_TAGID_NEW_MISSED_CALLS = 0x09;
+
+    protected HeaderSet mHeaderSet;
+
+    protected int mResponseCode;
+
+    private boolean mAborted = false;
+
+    private ClientOperation mOp = null;
+
+    public BluetoothPbapRequest() {
+        mHeaderSet = new HeaderSet();
+    }
+
+    final public boolean isSuccess() {
+        return (mResponseCode == ResponseCodes.OBEX_HTTP_OK);
+    }
+
+    public void execute(ClientSession session) throws IOException {
+        Log.v(TAG, "execute");
+
+        /* in case request is aborted before can be executed */
+        if (mAborted) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+            return;
+        }
+
+        try {
+            mOp = (ClientOperation) session.get(mHeaderSet);
+
+            /* make sure final flag for GET is used (PBAP spec 6.2.2) */
+            mOp.setGetFinalFlag(true);
+
+            /*
+             * this will trigger ClientOperation to use non-buffered stream so
+             * we can abort operation
+             */
+            mOp.continueOperation(true, false);
+
+            readResponseHeaders(mOp.getReceivedHeader());
+
+            InputStream is = mOp.openInputStream();
+            readResponse(is);
+            is.close();
+
+            mOp.close();
+
+            mResponseCode = mOp.getResponseCode();
+
+            Log.d(TAG, "mResponseCode=" + mResponseCode);
+
+            checkResponseCode(mResponseCode);
+        } catch (IOException e) {
+            Log.e(TAG, "IOException occured when processing request", e);
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+
+            throw e;
+        }
+    }
+
+    public void abort() {
+        mAborted = true;
+
+        if (mOp != null) {
+            try {
+                mOp.abort();
+            } catch (IOException e) {
+                Log.e(TAG, "Exception occured when trying to abort", e);
+            }
+        }
+    }
+
+    protected void readResponse(InputStream stream) throws IOException {
+        Log.v(TAG, "readResponse");
+
+        /* nothing here by default */
+    }
+
+    protected void readResponseHeaders(HeaderSet headerset) {
+        Log.v(TAG, "readResponseHeaders");
+
+        /* nothing here by dafault */
+    }
+
+    protected void checkResponseCode(int responseCode) throws IOException {
+        Log.v(TAG, "checkResponseCode");
+
+        /* nothing here by dafault */
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBook.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBook.java
new file mode 100644
index 0000000..15954b1
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBook.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.util.Log;
+
+import com.android.vcard.VCardEntry;
+import android.bluetooth.client.pbap.utils.ObexAppParameters;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import javax.obex.HeaderSet;
+
+final class BluetoothPbapRequestPullPhoneBook extends BluetoothPbapRequest {
+
+    private static final String TAG = "BluetoothPbapRequestPullPhoneBook";
+
+    private static final String TYPE = "x-bt/phonebook";
+
+    private BluetoothPbapVcardList mResponse;
+
+    private int mNewMissedCalls = -1;
+
+    private final byte mFormat;
+
+    public BluetoothPbapRequestPullPhoneBook(String pbName, long filter, byte format,
+            int maxListCount, int listStartOffset) {
+
+        if (maxListCount < 0 || maxListCount > 65535) {
+            throw new IllegalArgumentException("maxListCount should be [0..65535]");
+        }
+
+        if (listStartOffset < 0 || listStartOffset > 65535) {
+            throw new IllegalArgumentException("listStartOffset should be [0..65535]");
+        }
+
+        mHeaderSet.setHeader(HeaderSet.NAME, pbName);
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        /* make sure format is one of allowed values */
+        if (format != BluetoothPbapClient.VCARD_TYPE_21
+                && format != BluetoothPbapClient.VCARD_TYPE_30) {
+            format = BluetoothPbapClient.VCARD_TYPE_21;
+        }
+
+        if (filter != 0) {
+            oap.add(OAP_TAGID_FILTER, filter);
+        }
+
+        oap.add(OAP_TAGID_FORMAT, format);
+
+        /*
+         * maxListCount is a special case which is handled in
+         * BluetoothPbapRequestPullPhoneBookSize
+         */
+        if (maxListCount > 0) {
+            oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) maxListCount);
+        } else {
+            oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) 65535);
+        }
+
+        if (listStartOffset > 0) {
+            oap.add(OAP_TAGID_LIST_START_OFFSET, (short) listStartOffset);
+        }
+
+        oap.addToHeaderSet(mHeaderSet);
+
+        mFormat = format;
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) throws IOException {
+        Log.v(TAG, "readResponse");
+
+        mResponse = new BluetoothPbapVcardList(stream, mFormat);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        Log.v(TAG, "readResponse");
+
+        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+        if (oap.exists(OAP_TAGID_NEW_MISSED_CALLS)) {
+            mNewMissedCalls = oap.getByte(OAP_TAGID_NEW_MISSED_CALLS);
+        }
+    }
+
+    public ArrayList<VCardEntry> getList() {
+        return mResponse.getList();
+    }
+
+    public int getNewMissedCalls() {
+        return mNewMissedCalls;
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBookSize.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBookSize.java
new file mode 100644
index 0000000..664f081
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullPhoneBookSize.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.util.Log;
+
+import android.bluetooth.client.pbap.utils.ObexAppParameters;
+
+import javax.obex.HeaderSet;
+
+class BluetoothPbapRequestPullPhoneBookSize extends BluetoothPbapRequest {
+
+    private static final String TAG = "BluetoothPbapRequestPullPhoneBookSize";
+
+    private static final String TYPE = "x-bt/phonebook";
+
+    private int mSize;
+
+    public BluetoothPbapRequestPullPhoneBookSize(String pbName) {
+        mHeaderSet.setHeader(HeaderSet.NAME, pbName);
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+        oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) 0);
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        Log.v(TAG, "readResponseHeaders");
+
+        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+        mSize = oap.getShort(OAP_TAGID_PHONEBOOK_SIZE);
+    }
+
+    public int getSize() {
+        return mSize;
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardEntry.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardEntry.java
new file mode 100644
index 0000000..009ec15
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardEntry.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.util.Log;
+
+import com.android.vcard.VCardEntry;
+import android.bluetooth.client.pbap.utils.ObexAppParameters;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+final class BluetoothPbapRequestPullVcardEntry extends BluetoothPbapRequest {
+
+    private static final String TAG = "BluetoothPbapRequestPullVcardEntry";
+
+    private static final String TYPE = "x-bt/vcard";
+
+    private BluetoothPbapVcardList mResponse;
+
+    private final byte mFormat;
+
+    public BluetoothPbapRequestPullVcardEntry(String handle, long filter, byte format) {
+        mHeaderSet.setHeader(HeaderSet.NAME, handle);
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        /* make sure format is one of allowed values */
+        if (format != BluetoothPbapClient.VCARD_TYPE_21
+                && format != BluetoothPbapClient.VCARD_TYPE_30) {
+            format = BluetoothPbapClient.VCARD_TYPE_21;
+        }
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        if (filter != 0) {
+            oap.add(OAP_TAGID_FILTER, filter);
+        }
+
+        oap.add(OAP_TAGID_FORMAT, format);
+        oap.addToHeaderSet(mHeaderSet);
+
+        mFormat = format;
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) throws IOException {
+        Log.v(TAG, "readResponse");
+
+        mResponse = new BluetoothPbapVcardList(stream, mFormat);
+    }
+    @Override
+    protected void checkResponseCode(int responseCode) throws IOException {
+        Log.v(TAG, "checkResponseCode");
+
+        if (mResponse.getCount() == 0) {
+            if (responseCode != ResponseCodes.OBEX_HTTP_NOT_FOUND) {
+                throw new IOException("Invalid response received");
+            } else {
+                Log.v(TAG, "Vcard Entry not found");
+            }
+        }
+    }
+
+    public VCardEntry getVcard() {
+        return mResponse.getFirst();
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListing.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListing.java
new file mode 100644
index 0000000..5f042ba
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListing.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.util.Log;
+
+import android.bluetooth.client.pbap.utils.ObexAppParameters;
+import android.bluetooth.client.pbap.BluetoothPbapVcardListing;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+import javax.obex.HeaderSet;
+
+final class BluetoothPbapRequestPullVcardListing extends BluetoothPbapRequest {
+
+    private static final String TAG = "BluetoothPbapRequestPullVcardListing";
+
+    private static final String TYPE = "x-bt/vcard-listing";
+
+    private BluetoothPbapVcardListing mResponse = null;
+
+    private int mNewMissedCalls = -1;
+
+    public BluetoothPbapRequestPullVcardListing(String folder, byte order, byte searchAttr,
+            String searchVal, int maxListCount, int listStartOffset) {
+
+        if (maxListCount < 0 || maxListCount > 65535) {
+            throw new IllegalArgumentException("maxListCount should be [0..65535]");
+        }
+
+        if (listStartOffset < 0 || listStartOffset > 65535) {
+            throw new IllegalArgumentException("listStartOffset should be [0..65535]");
+        }
+
+        if (folder == null) {
+            folder = "";
+        }
+
+        mHeaderSet.setHeader(HeaderSet.NAME, folder);
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+
+        if (order >= 0) {
+            oap.add(OAP_TAGID_ORDER, order);
+        }
+
+        if (searchVal != null) {
+            oap.add(OAP_TAGID_SEARCH_ATTRIBUTE, searchAttr);
+            oap.add(OAP_TAGID_SEARCH_VALUE, searchVal);
+        }
+
+        /*
+         * maxListCount is a special case which is handled in
+         * BluetoothPbapRequestPullVcardListingSize
+         */
+        if (maxListCount > 0) {
+            oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) maxListCount);
+        }
+
+        if (listStartOffset > 0) {
+            oap.add(OAP_TAGID_LIST_START_OFFSET, (short) listStartOffset);
+        }
+
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponse(InputStream stream) throws IOException {
+        Log.v(TAG, "readResponse");
+
+        mResponse = new BluetoothPbapVcardListing(stream);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        Log.v(TAG, "readResponseHeaders");
+
+        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+        if (oap.exists(OAP_TAGID_NEW_MISSED_CALLS)) {
+            mNewMissedCalls = oap.getByte(OAP_TAGID_NEW_MISSED_CALLS);
+        }
+    }
+
+    public ArrayList<BluetoothPbapCard> getList() {
+        return mResponse.getList();
+    }
+
+    public int getNewMissedCalls() {
+        return mNewMissedCalls;
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListingSize.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListingSize.java
new file mode 100644
index 0000000..ab276c3
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapRequestPullVcardListingSize.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.util.Log;
+
+import android.bluetooth.client.pbap.utils.ObexAppParameters;
+
+import javax.obex.HeaderSet;
+
+class BluetoothPbapRequestPullVcardListingSize extends BluetoothPbapRequest {
+
+    private static final String TAG = "BluetoothPbapRequestPullVcardListingSize";
+
+    private static final String TYPE = "x-bt/vcard-listing";
+
+    private int mSize;
+
+    public BluetoothPbapRequestPullVcardListingSize(String folder) {
+        mHeaderSet.setHeader(HeaderSet.NAME, folder);
+
+        mHeaderSet.setHeader(HeaderSet.TYPE, TYPE);
+
+        ObexAppParameters oap = new ObexAppParameters();
+        oap.add(OAP_TAGID_MAX_LIST_COUNT, (short) 0);
+        oap.addToHeaderSet(mHeaderSet);
+    }
+
+    @Override
+    protected void readResponseHeaders(HeaderSet headerset) {
+        Log.v(TAG, "readResponseHeaders");
+
+        ObexAppParameters oap = ObexAppParameters.fromHeaderSet(headerset);
+
+        mSize = oap.getShort(OAP_TAGID_PHONEBOOK_SIZE);
+    }
+
+    public int getSize() {
+        return mSize;
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapRequestSetPath.java b/src/android/bluetooth/client/pbap/BluetoothPbapRequestSetPath.java
new file mode 100644
index 0000000..60f5244
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapRequestSetPath.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.util.Log;
+
+import java.io.IOException;
+
+import javax.obex.ClientSession;
+import javax.obex.HeaderSet;
+import javax.obex.ResponseCodes;
+
+final class BluetoothPbapRequestSetPath extends BluetoothPbapRequest {
+
+    private final static String TAG = "BluetoothPbapRequestSetPath";
+
+    private enum SetPathDir {
+        ROOT, UP, DOWN
+    };
+
+    private SetPathDir mDir;
+
+    public BluetoothPbapRequestSetPath(String name) {
+        mDir = SetPathDir.DOWN;
+        mHeaderSet.setHeader(HeaderSet.NAME, name);
+    }
+
+    public BluetoothPbapRequestSetPath(boolean goUp) {
+        mHeaderSet.setEmptyNameHeader();
+        if (goUp) {
+            mDir = SetPathDir.UP;
+        } else {
+            mDir = SetPathDir.ROOT;
+        }
+    }
+
+    @Override
+    public void execute(ClientSession session) {
+        Log.v(TAG, "execute");
+
+        HeaderSet hs = null;
+
+        try {
+            switch (mDir) {
+                case ROOT:
+                case DOWN:
+                    hs = session.setPath(mHeaderSet, false, false);
+                    break;
+                case UP:
+                    hs = session.setPath(mHeaderSet, true, false);
+                    break;
+            }
+
+            mResponseCode = hs.getResponseCode();
+        } catch (IOException e) {
+            mResponseCode = ResponseCodes.OBEX_HTTP_INTERNAL_ERROR;
+        }
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapSession.java b/src/android/bluetooth/client/pbap/BluetoothPbapSession.java
new file mode 100644
index 0000000..70e0ac8
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapSession.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSocket;
+import android.os.Handler;
+import android.os.Handler.Callback;
+import android.os.HandlerThread;
+import android.os.Message;
+import android.os.Process;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.UUID;
+
+class BluetoothPbapSession implements Callback {
+    private static final String TAG = "android.bluetooth.client.pbap.BluetoothPbapSession";
+
+    /* local use only */
+    private static final int RFCOMM_CONNECTED = 1;
+    private static final int RFCOMM_FAILED = 2;
+
+    /* to BluetoothPbapClient */
+    public static final int REQUEST_COMPLETED = 3;
+    public static final int REQUEST_FAILED = 4;
+    public static final int SESSION_CONNECTING = 5;
+    public static final int SESSION_CONNECTED = 6;
+    public static final int SESSION_DISCONNECTED = 7;
+    public static final int AUTH_REQUESTED = 8;
+    public static final int AUTH_TIMEOUT = 9;
+
+    public static final int ACTION_LISTING = 14;
+    public static final int ACTION_VCARD = 15;
+    public static final int ACTION_PHONEBOOK_SIZE = 16;
+
+    private static final String PBAP_UUID =
+            "0000112f-0000-1000-8000-00805f9b34fb";
+
+    private final BluetoothAdapter mAdapter;
+    private final BluetoothDevice mDevice;
+
+    private final Handler mParentHandler;
+
+    private final HandlerThread mHandlerThread;
+    private final Handler mSessionHandler;
+
+    private RfcommConnectThread mConnectThread;
+    private BluetoothPbapObexTransport mTransport;
+
+    private BluetoothPbapObexSession mObexSession;
+
+    private BluetoothPbapRequest mPendingRequest = null;
+
+    public BluetoothPbapSession(BluetoothDevice device, Handler handler) {
+
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        if (mAdapter == null) {
+            throw new NullPointerException("No Bluetooth adapter in the system");
+        }
+
+        mDevice = device;
+        mParentHandler = handler;
+        mConnectThread = null;
+        mTransport = null;
+        mObexSession = null;
+
+        mHandlerThread = new HandlerThread("PBAP session handler",
+                Process.THREAD_PRIORITY_BACKGROUND);
+        mHandlerThread.start();
+        mSessionHandler = new Handler(mHandlerThread.getLooper(), this);
+    }
+
+    @Override
+    public boolean handleMessage(Message msg) {
+        Log.d(TAG, "Handler: msg: " + msg.what);
+
+        switch (msg.what) {
+            case RFCOMM_FAILED:
+                mConnectThread = null;
+
+                mParentHandler.obtainMessage(SESSION_DISCONNECTED).sendToTarget();
+
+                if (mPendingRequest != null) {
+                    mParentHandler.obtainMessage(REQUEST_FAILED, mPendingRequest).sendToTarget();
+                    mPendingRequest = null;
+                }
+                break;
+
+            case RFCOMM_CONNECTED:
+                mConnectThread = null;
+                mTransport = (BluetoothPbapObexTransport) msg.obj;
+                startObexSession();
+                break;
+
+            case BluetoothPbapObexSession.OBEX_SESSION_FAILED:
+                stopObexSession();
+
+                mParentHandler.obtainMessage(SESSION_DISCONNECTED).sendToTarget();
+
+                if (mPendingRequest != null) {
+                    mParentHandler.obtainMessage(REQUEST_FAILED, mPendingRequest).sendToTarget();
+                    mPendingRequest = null;
+                }
+                break;
+
+            case BluetoothPbapObexSession.OBEX_SESSION_CONNECTED:
+                mParentHandler.obtainMessage(SESSION_CONNECTED).sendToTarget();
+
+                if (mPendingRequest != null) {
+                    mObexSession.schedule(mPendingRequest);
+                    mPendingRequest = null;
+                }
+                break;
+
+            case BluetoothPbapObexSession.OBEX_SESSION_DISCONNECTED:
+                mParentHandler.obtainMessage(SESSION_DISCONNECTED).sendToTarget();
+                stopRfcomm();
+                break;
+
+            case BluetoothPbapObexSession.OBEX_SESSION_REQUEST_COMPLETED:
+                /* send to parent, process there */
+                mParentHandler.obtainMessage(REQUEST_COMPLETED, msg.obj).sendToTarget();
+                break;
+
+            case BluetoothPbapObexSession.OBEX_SESSION_REQUEST_FAILED:
+                /* send to parent, process there */
+                mParentHandler.obtainMessage(REQUEST_FAILED, msg.obj).sendToTarget();
+                break;
+
+            case BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_REQUEST:
+                /* send to parent, process there */
+                mParentHandler.obtainMessage(AUTH_REQUESTED).sendToTarget();
+
+                mSessionHandler
+                        .sendMessageDelayed(
+                                mSessionHandler
+                                        .obtainMessage(BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_TIMEOUT),
+                                30000);
+                break;
+
+            case BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_TIMEOUT:
+                /* stop authentication */
+                setAuthResponse(null);
+
+                mParentHandler.obtainMessage(AUTH_TIMEOUT).sendToTarget();
+                break;
+
+            default:
+                return false;
+        }
+
+        return true;
+    }
+
+    public void start() {
+        Log.d(TAG, "start");
+
+        startRfcomm();
+    }
+
+    public void stop() {
+        Log.d(TAG, "Stop");
+
+        stopObexSession();
+        stopRfcomm();
+    }
+
+    public void abort() {
+        Log.d(TAG, "abort");
+
+        /* fail pending request immediately */
+        if (mPendingRequest != null) {
+            mParentHandler.obtainMessage(REQUEST_FAILED, mPendingRequest).sendToTarget();
+            mPendingRequest = null;
+        }
+
+        if (mObexSession != null) {
+            mObexSession.abort();
+        }
+    }
+
+    public boolean makeRequest(BluetoothPbapRequest request) {
+        Log.v(TAG, "makeRequest: " + request.getClass().getSimpleName());
+
+        if (mPendingRequest != null) {
+            Log.w(TAG, "makeRequest: request already queued, exiting");
+            return false;
+        }
+
+        if (mObexSession == null) {
+            mPendingRequest = request;
+
+            /*
+             * since there is no pending request and no session it's safe to
+             * assume that RFCOMM does not exist either and we should start
+             * connecting it
+             */
+            startRfcomm();
+
+            return true;
+        }
+
+        return mObexSession.schedule(request);
+    }
+
+    public boolean setAuthResponse(String key) {
+        Log.d(TAG, "setAuthResponse key=" + key);
+
+        mSessionHandler
+                .removeMessages(BluetoothPbapObexSession.OBEX_SESSION_AUTHENTICATION_TIMEOUT);
+
+        /* does not make sense to set auth response when OBEX session is down */
+        if (mObexSession == null) {
+            return false;
+        }
+
+        return mObexSession.setAuthReply(key);
+    }
+
+    private void startRfcomm() {
+        Log.d(TAG, "startRfcomm");
+
+        if (mConnectThread == null && mObexSession == null) {
+            mParentHandler.obtainMessage(SESSION_CONNECTING).sendToTarget();
+
+            mConnectThread = new RfcommConnectThread();
+            mConnectThread.start();
+        }
+
+        /*
+         * don't care if mConnectThread is not null - it means RFCOMM is being
+         * connected anyway
+         */
+    }
+
+    private void stopRfcomm() {
+        Log.d(TAG, "stopRfcomm");
+
+        if (mConnectThread != null) {
+            try {
+                mConnectThread.join();
+            } catch (InterruptedException e) {
+            }
+
+            mConnectThread = null;
+        }
+
+        if (mTransport != null) {
+            try {
+                mTransport.close();
+            } catch (IOException e) {
+            }
+
+            mTransport = null;
+        }
+    }
+
+    private void startObexSession() {
+        Log.d(TAG, "startObexSession");
+
+        mObexSession = new BluetoothPbapObexSession(mTransport);
+        mObexSession.start(mSessionHandler);
+    }
+
+    private void stopObexSession() {
+        Log.d(TAG, "stopObexSession");
+
+        if (mObexSession != null) {
+            mObexSession.stop();
+            mObexSession = null;
+        }
+    }
+
+    private class RfcommConnectThread extends Thread {
+        private static final String TAG = "RfcommConnectThread";
+
+        private BluetoothSocket mSocket;
+
+        public RfcommConnectThread() {
+            super("RfcommConnectThread");
+        }
+
+        @Override
+        public void run() {
+            if (mAdapter.isDiscovering()) {
+                mAdapter.cancelDiscovery();
+            }
+
+            try {
+                mSocket = mDevice.createRfcommSocketToServiceRecord(UUID.fromString(PBAP_UUID));
+                mSocket.connect();
+
+                BluetoothPbapObexTransport transport;
+                transport = new BluetoothPbapObexTransport(mSocket);
+
+                mSessionHandler.obtainMessage(RFCOMM_CONNECTED, transport).sendToTarget();
+            } catch (IOException e) {
+                closeSocket();
+                mSessionHandler.obtainMessage(RFCOMM_FAILED).sendToTarget();
+            }
+
+        }
+
+        private void closeSocket() {
+            try {
+                if (mSocket != null) {
+                    mSocket.close();
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error when closing socket", e);
+            }
+        }
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapVcardList.java b/src/android/bluetooth/client/pbap/BluetoothPbapVcardList.java
new file mode 100644
index 0000000..8e23e1a
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapVcardList.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import com.android.vcard.VCardEntry;
+import com.android.vcard.VCardEntryConstructor;
+import com.android.vcard.VCardEntryCounter;
+import com.android.vcard.VCardEntryHandler;
+import com.android.vcard.VCardParser;
+import com.android.vcard.VCardParser_V21;
+import com.android.vcard.VCardParser_V30;
+import com.android.vcard.exception.VCardException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+class BluetoothPbapVcardList {
+
+    private final ArrayList<VCardEntry> mCards = new ArrayList<VCardEntry>();
+
+    class CardEntryHandler implements VCardEntryHandler {
+        @Override
+        public void onStart() {
+        }
+
+        @Override
+        public void onEntryCreated(VCardEntry entry) {
+            mCards.add(entry);
+        }
+
+        @Override
+        public void onEnd() {
+        }
+    }
+
+    public BluetoothPbapVcardList(InputStream in, byte format) throws IOException {
+        parse(in, format);
+    }
+
+    private void parse(InputStream in, byte format) throws IOException {
+        VCardParser parser;
+
+        if (format == BluetoothPbapClient.VCARD_TYPE_30) {
+            parser = new VCardParser_V30();
+        } else {
+            parser = new VCardParser_V21();
+        }
+
+        VCardEntryConstructor constructor = new VCardEntryConstructor();
+        VCardEntryCounter counter = new VCardEntryCounter();
+        CardEntryHandler handler = new CardEntryHandler();
+
+        constructor.addEntryHandler(handler);
+
+        parser.addInterpreter(constructor);
+        parser.addInterpreter(counter);
+
+        try {
+            parser.parse(in);
+        } catch (VCardException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public int getCount() {
+        return mCards.size();
+    }
+
+    public ArrayList<VCardEntry> getList() {
+        return mCards;
+    }
+
+    public VCardEntry getFirst() {
+        return mCards.get(0);
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/BluetoothPbapVcardListing.java b/src/android/bluetooth/client/pbap/BluetoothPbapVcardListing.java
new file mode 100644
index 0000000..d963c94
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/BluetoothPbapVcardListing.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap;
+
+import android.util.Log;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+class BluetoothPbapVcardListing {
+
+    private static final String TAG = "BluetoothPbapVcardListing";
+
+    ArrayList<BluetoothPbapCard> mCards = new ArrayList<BluetoothPbapCard>();
+
+    public BluetoothPbapVcardListing(InputStream in) throws IOException {
+        parse(in);
+    }
+
+    private void parse(InputStream in) throws IOException {
+        XmlPullParser parser = Xml.newPullParser();
+
+        try {
+            parser.setInput(in, "UTF-8");
+
+            int eventType = parser.getEventType();
+
+            while (eventType != XmlPullParser.END_DOCUMENT) {
+
+                if (eventType == XmlPullParser.START_TAG && parser.getName().equals("card")) {
+                    BluetoothPbapCard card = new BluetoothPbapCard(
+                            parser.getAttributeValue(null, "handle"),
+                            parser.getAttributeValue(null, "name"));
+                    mCards.add(card);
+                }
+
+                eventType = parser.next();
+            }
+        } catch (XmlPullParserException e) {
+            Log.e(TAG, "XML parser error when parsing XML", e);
+        }
+    }
+
+    public ArrayList<BluetoothPbapCard> getList() {
+        return mCards;
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/utils/BmsgTokenizer.java b/src/android/bluetooth/client/pbap/utils/BmsgTokenizer.java
new file mode 100644
index 0000000..cf138c9
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/utils/BmsgTokenizer.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap.utils;
+
+import android.util.Log;
+
+import java.text.ParseException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class BmsgTokenizer {
+
+    private final String mStr;
+
+    private final Matcher mMatcher;
+
+    private int mPos = 0;
+
+    private final int mOffset;
+
+    static public class Property {
+        public final String name;
+        public final String value;
+
+        public Property(String name, String value) {
+            if (name == null || value == null) {
+                throw new IllegalArgumentException();
+            }
+
+            this.name = name;
+            this.value = value;
+
+            Log.v("BMSG >> ", toString());
+        }
+
+        @Override
+        public String toString() {
+            return name + ":" + value;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            return ((o instanceof Property) && ((Property) o).name.equals(name) && ((Property) o).value
+                    .equals(value));
+        }
+    };
+
+    public BmsgTokenizer(String str) {
+        this(str, 0);
+    }
+
+    public BmsgTokenizer(String str, int offset) {
+        mStr = str;
+        mOffset = offset;
+        mMatcher = Pattern.compile("(([^:]*):(.*))?\r\n").matcher(str);
+        mPos = mMatcher.regionStart();
+    }
+
+    public Property next(boolean alwaysReturn) throws ParseException {
+        boolean found = false;
+
+        do {
+            mMatcher.region(mPos, mMatcher.regionEnd());
+
+            if (!mMatcher.lookingAt()) {
+                if (alwaysReturn) {
+                    return null;
+                }
+
+                throw new ParseException("Property or empty line expected", pos());
+            }
+
+            mPos = mMatcher.end();
+
+            if (mMatcher.group(1) != null) {
+                found = true;
+            }
+        } while (!found);
+
+        return new Property(mMatcher.group(2), mMatcher.group(3));
+    }
+
+    public Property next() throws ParseException {
+        return next(false);
+    }
+
+    public String remaining() {
+        return mStr.substring(mPos);
+    }
+
+    public int pos() {
+        return mPos + mOffset;
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/utils/ObexAppParameters.java b/src/android/bluetooth/client/pbap/utils/ObexAppParameters.java
new file mode 100644
index 0000000..d70d1e4
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/utils/ObexAppParameters.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap.utils;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.obex.HeaderSet;
+
+public final class ObexAppParameters {
+
+    private final HashMap<Byte, byte[]> mParams;
+
+    public ObexAppParameters() {
+        mParams = new HashMap<Byte, byte[]>();
+    }
+
+    public ObexAppParameters(byte[] raw) {
+        mParams = new HashMap<Byte, byte[]>();
+
+        if (raw != null) {
+            for (int i = 0; i < raw.length;) {
+                if (raw.length - i < 2) {
+                    break;
+                }
+
+                byte tag = raw[i++];
+                byte len = raw[i++];
+
+                if (raw.length - i - len < 0) {
+                    break;
+                }
+
+                byte[] val = new byte[len];
+
+                System.arraycopy(raw, i, val, 0, len);
+                this.add(tag, val);
+
+                i += len;
+            }
+        }
+    }
+
+    public static ObexAppParameters fromHeaderSet(HeaderSet headerset) {
+        try {
+            byte[] raw = (byte[]) headerset.getHeader(HeaderSet.APPLICATION_PARAMETER);
+            return new ObexAppParameters(raw);
+        } catch (IOException e) {
+            // won't happen
+        }
+
+        return null;
+    }
+
+    public byte[] getHeader() {
+        int length = 0;
+
+        for (Map.Entry<Byte, byte[]> entry : mParams.entrySet()) {
+            length += (entry.getValue().length + 2);
+        }
+
+        byte[] ret = new byte[length];
+
+        int idx = 0;
+        for (Map.Entry<Byte, byte[]> entry : mParams.entrySet()) {
+            length = entry.getValue().length;
+
+            ret[idx++] = entry.getKey();
+            ret[idx++] = (byte) length;
+            System.arraycopy(entry.getValue(), 0, ret, idx, length);
+            idx += length;
+        }
+
+        return ret;
+    }
+
+    public void addToHeaderSet(HeaderSet headerset) {
+        if (mParams.size() > 0) {
+            headerset.setHeader(HeaderSet.APPLICATION_PARAMETER, getHeader());
+        }
+    }
+
+    public boolean exists(byte tag) {
+        return mParams.containsKey(tag);
+    }
+
+    public void add(byte tag, byte val) {
+        byte[] bval = ByteBuffer.allocate(1).put(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, short val) {
+        byte[] bval = ByteBuffer.allocate(2).putShort(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, int val) {
+        byte[] bval = ByteBuffer.allocate(4).putInt(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, long val) {
+        byte[] bval = ByteBuffer.allocate(8).putLong(val).array();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, String val) {
+        byte[] bval = val.getBytes();
+        mParams.put(tag, bval);
+    }
+
+    public void add(byte tag, byte[] bval) {
+        mParams.put(tag, bval);
+    }
+
+    public byte getByte(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null || bval.length < 1) {
+            return 0;
+        }
+
+        return ByteBuffer.wrap(bval).get();
+    }
+
+    public short getShort(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null || bval.length < 2) {
+            return 0;
+        }
+
+        return ByteBuffer.wrap(bval).getShort();
+    }
+
+    public int getInt(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null || bval.length < 4) {
+            return 0;
+        }
+
+        return ByteBuffer.wrap(bval).getInt();
+    }
+
+    public String getString(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        if (bval == null) {
+            return null;
+        }
+
+        return new String(bval);
+    }
+
+    public byte[] getByteArray(byte tag) {
+        byte[] bval = mParams.get(tag);
+
+        return bval;
+    }
+
+    @Override
+    public String toString() {
+        return mParams.toString();
+    }
+}
diff --git a/src/android/bluetooth/client/pbap/utils/ObexTime.java b/src/android/bluetooth/client/pbap/utils/ObexTime.java
new file mode 100644
index 0000000..74bc2ab
--- /dev/null
+++ b/src/android/bluetooth/client/pbap/utils/ObexTime.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * 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 android.bluetooth.client.pbap.utils;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public final class ObexTime {
+
+    private Date mDate;
+
+    public ObexTime(String time) {
+        /*
+         * match OBEX time string: YYYYMMDDTHHMMSS with optional UTF offset
+         * +/-hhmm
+         */
+        Pattern p = Pattern
+                .compile("(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})(([+-])(\\d{2})(\\d{2}))?");
+        Matcher m = p.matcher(time);
+
+        if (m.matches()) {
+
+            /*
+             * matched groups are numberes as follows: YYYY MM DD T HH MM SS +
+             * hh mm ^^^^ ^^ ^^ ^^ ^^ ^^ ^ ^^ ^^ 1 2 3 4 5 6 8 9 10 all groups
+             * are guaranteed to be numeric so conversion will always succeed
+             * (except group 8 which is either + or -)
+             */
+
+            Calendar cal = Calendar.getInstance();
+            cal.set(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)) - 1,
+                    Integer.parseInt(m.group(3)), Integer.parseInt(m.group(4)),
+                    Integer.parseInt(m.group(5)), Integer.parseInt(m.group(6)));
+
+            /*
+             * if 7th group is matched then we have UTC offset information
+             * included
+             */
+            if (m.group(7) != null) {
+                int ohh = Integer.parseInt(m.group(9));
+                int omm = Integer.parseInt(m.group(10));
+
+                /* time zone offset is specified in miliseconds */
+                int offset = (ohh * 60 + omm) * 60 * 1000;
+
+                if (m.group(8).equals("-")) {
+                    offset = -offset;
+                }
+
+                TimeZone tz = TimeZone.getTimeZone("UTC");
+                tz.setRawOffset(offset);
+
+                cal.setTimeZone(tz);
+            }
+
+            mDate = cal.getTime();
+        }
+    }
+
+    public ObexTime(Date date) {
+        mDate = date;
+    }
+
+    public Date getTime() {
+        return mDate;
+    }
+
+    @Override
+    public String toString() {
+        if (mDate == null) {
+            return null;
+        }
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(mDate);
+
+        /* note that months are numbered stating from 0 */
+        return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02d",
+                cal.get(Calendar.YEAR), cal.get(Calendar.MONTH) + 1,
+                cal.get(Calendar.DATE), cal.get(Calendar.HOUR_OF_DAY),
+                cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND));
+    }
+}
