diff --git a/Android.mk b/Android.mk
index 33c1115..4e4a62c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -37,4 +37,20 @@
 LOCAL_PROGUARD_ENABLED := disabled
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+
+src_dirs:=  src/org/codeaurora/bluetooth/pbapclient
+
+LOCAL_SRC_FILES := \
+        $(call all-java-files-under, $(src_dirs))
+
+LOCAL_MODULE:= org.codeaurora.bluetooth.pbapclient
+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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapCard.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapCard.java
new file mode 100644
index 0000000..21d9371
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapCard.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.codeaurora.bluetooth.pbapclient;
+
+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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapClient.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapClient.java
new file mode 100644
index 0000000..b6e688b
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapClient.java
@@ -0,0 +1,858 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapObexAuthenticator.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapObexAuthenticator.java
new file mode 100644
index 0000000..239e675
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapObexAuthenticator.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.codeaurora.bluetooth.pbapclient;
+
+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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapObexSession.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapObexSession.java
new file mode 100644
index 0000000..d7410cf
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapObexSession.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapObexTransport.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapObexTransport.java
new file mode 100644
index 0000000..8576636
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapObexTransport.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2008-2009, Motorola, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the Motorola, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequest.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequest.java
new file mode 100644
index 0000000..5f73ffc
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.codeaurora.bluetooth.pbapclient;
+
+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);
+        } 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 */
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java
new file mode 100644
index 0000000..db08189
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBook.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+import android.util.Log;
+
+import com.android.vcard.VCardEntry;
+import org.codeaurora.bluetooth.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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookSize.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookSize.java
new file mode 100644
index 0000000..8ad2324
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullPhoneBookSize.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+import android.util.Log;
+
+import org.codeaurora.bluetooth.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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullVcardEntry.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullVcardEntry.java
new file mode 100644
index 0000000..1bbe359
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullVcardEntry.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+import android.util.Log;
+
+import com.android.vcard.VCardEntry;
+import org.codeaurora.bluetooth.utils.ObexAppParameters;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.obex.HeaderSet;
+
+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);
+
+        if (mResponse.getCount() == 0) {
+            throw new IOException("Invalid response received");
+        }
+    }
+
+    public VCardEntry getVcard() {
+        return mResponse.getFirst();
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullVcardListing.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullVcardListing.java
new file mode 100644
index 0000000..a6863c4
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullVcardListing.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+import android.util.Log;
+
+import org.codeaurora.bluetooth.utils.ObexAppParameters;
+import org.codeaurora.bluetooth.pbapclient.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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullVcardListingSize.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullVcardListingSize.java
new file mode 100644
index 0000000..9fb9295
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestPullVcardListingSize.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+import android.util.Log;
+
+import org.codeaurora.bluetooth.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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestSetPath.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestSetPath.java
new file mode 100644
index 0000000..ca6d9b5
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapRequestSetPath.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapSession.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapSession.java
new file mode 100644
index 0000000..7cd16f1
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapSession.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+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 = "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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapVcardList.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapVcardList.java
new file mode 100644
index 0000000..35118d8
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapVcardList.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.pbapclient;
+
+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/org/codeaurora/bluetooth/pbapclient/BluetoothPbapVcardListing.java b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapVcardListing.java
new file mode 100644
index 0000000..2b633ec
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/BluetoothPbapVcardListing.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.codeaurora.bluetooth.pbapclient;
+
+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/org/codeaurora/bluetooth/pbapclient/utils/BmsgTokenizer.java b/src/org/codeaurora/bluetooth/pbapclient/utils/BmsgTokenizer.java
new file mode 100644
index 0000000..8e1bbe4
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/utils/BmsgTokenizer.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.codeaurora.bluetooth.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/org/codeaurora/bluetooth/pbapclient/utils/ObexAppParameters.java b/src/org/codeaurora/bluetooth/pbapclient/utils/ObexAppParameters.java
new file mode 100644
index 0000000..cfb7667
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/utils/ObexAppParameters.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+package org.codeaurora.bluetooth.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/org/codeaurora/bluetooth/pbapclient/utils/ObexTime.java b/src/org/codeaurora/bluetooth/pbapclient/utils/ObexTime.java
new file mode 100644
index 0000000..83c42ad
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/pbapclient/utils/ObexTime.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *        * Redistributions of source code must retain the above copyright
+ *            notice, this list of conditions and the following disclaimer.
+ *        * Redistributions in binary form must reproduce the above copyright
+ *            notice, this list of conditions and the following disclaimer in the
+ *            documentation and/or other materials provided with the distribution.
+ *        * Neither the name of The Linux Foundation nor
+ *            the names of its contributors may be used to endorse or promote
+ *            products derived from this software without specific prior written
+ *            permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.    IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.codeaurora.bluetooth.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));
+    }
+}
