diff --git a/Android.mk b/Android.mk
index bbd17ec..518661b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -2,10 +2,14 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := optional
-src_dirs:= src/org/codeaurora/bluetooth/btcservice \
-           src/org/codeaurora/bluetooth/map \
+src_dirs:= src/org/codeaurora/bluetooth/map \
            src/org/codeaurora/bluetooth/ftp \
-           src/org/codeaurora/bluetooth/sap
+           src/org/codeaurora/bluetooth/sap \
+           src/org/codeaurora/bluetooth/dun
+
+ifeq ($(BOARD_HAS_QCA_BT_AR3002),true)
+src_dirs += src/org/codeaurora/bluetooth/btcservice
+endif
 
 LOCAL_SRC_FILES := \
         $(call all-java-files-under, $(src_dirs))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2452b54..ff8189c 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -48,13 +48,15 @@
     <uses-permission android:name="android.permission.MMS_PUSH"></uses-permission>
     <uses-permission android:name="com.android.email.permission.ACCESS_PROVIDER"/>
     <uses-permission android:name="com.android.email.permission.READ_ATTACHMENT"/>
-    <application>
+    <application android:process="com.android.bluetooth">
         <uses-library android:name="javax.obex" />
         <service
+            android:enabled="@bool/profile_supported_btc"
             android:name = ".btcservice.BTCService">
         </service>
         <receiver
             android:exported="true"
+            android:enabled="@bool/profile_supported_btc"
             android:name=".btcservice.BTCEventProvider">
             <intent-filter>
                 <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
@@ -144,5 +146,32 @@
                 <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED"/>
             </intent-filter>
         </receiver>
+        <activity android:name=".dun.BluetoothDunPermissionActivity"
+            android:process="@string/process"
+            android:excludeFromRecents="true"
+            android:enabled="@bool/profile_supported_dun"
+            android:theme="@*android:style/Theme.Holo.Dialog.Alert">
+            <intent-filter>
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <service
+            android:process="@string/process"
+            android:name=".dun.BluetoothDunService"
+            android:enabled="@bool/profile_supported_dun" >
+            <intent-filter>
+                <action android:name="android.bluetooth.IBluetoothDun" />
+            </intent-filter>
+       </service>
+        <receiver
+            android:process="@string/process"
+            android:enabled="@bool/profile_supported_dun"
+            android:name=".dun.BluetoothDunReceiver">
+            <intent-filter>
+                <action android:name="android.bluetooth.adapter.action.STATE_CHANGED"/>
+                <action android:name="android.bluetooth.device.action.BOND_STATE_CHANGED"/>
+                <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED"/>
+            </intent-filter>
+        </receiver>
     </application>
 </manifest>
diff --git a/bttestapp/src/org/codeaurora/bluetooth/bttestapp/MapTestActivity.java b/bttestapp/src/org/codeaurora/bluetooth/bttestapp/MapTestActivity.java
index 1aa5165..c35b0be 100644
--- a/bttestapp/src/org/codeaurora/bluetooth/bttestapp/MapTestActivity.java
+++ b/bttestapp/src/org/codeaurora/bluetooth/bttestapp/MapTestActivity.java
@@ -1032,13 +1032,37 @@
 
     public void onClickGetMessagesListing(View view) {
         String folder = mSpinnerFolders.getSelectedItem().toString();
-        int maxListCount = Integer.parseInt(
-                mEditTextMaxListCountMessages.getText().toString());
-        int listStartOffset = Integer.parseInt(
-                mEditTextListStartOffsetMessages.getText().toString());
-        int subjectLength = Integer.parseInt(
-                mEditTextSubjectLength.getText().toString());
 
+        int maxListCount = 0;
+        int listStartOffset = 0;
+        int subjectLength = 0;
+
+        try {
+            maxListCount = Integer.parseInt(
+                    mEditTextMaxListCountMessages.getText().toString());
+        } catch (NumberFormatException e) {
+            Toast.makeText(this,
+                   "Incorrect maxListCount. Some defaults will be used",
+                         Toast.LENGTH_LONG).show();
+        }
+
+        try {
+            listStartOffset = Integer.parseInt(
+                    mEditTextListStartOffsetMessages.getText().toString());
+        } catch (NumberFormatException e) {
+            Toast.makeText(this,
+                   "Incorrect listStartOffset. Some defaults will be used",
+                         Toast.LENGTH_LONG).show();
+        }
+
+        try {
+            subjectLength = Integer.parseInt(
+                    mEditTextSubjectLength.getText().toString());
+        } catch (NumberFormatException e) {
+            Toast.makeText(this,
+                   "Incorrect subject lenght. Some defaults will be used",
+                         Toast.LENGTH_LONG).show();
+        }
         if (folder.equals(".")) {
             folder = "";
         }
diff --git a/bttestapp/src/org/codeaurora/bluetooth/bttestapp/ServicesFragment.java b/bttestapp/src/org/codeaurora/bluetooth/bttestapp/ServicesFragment.java
index 2776ebd..4d3feb9 100644
--- a/bttestapp/src/org/codeaurora/bluetooth/bttestapp/ServicesFragment.java
+++ b/bttestapp/src/org/codeaurora/bluetooth/bttestapp/ServicesFragment.java
@@ -503,7 +503,12 @@
                 break;
 
             case HFP:
-                intent = new Intent(getActivity(), HfpTestActivity.class);
+                if (mActivity.mProfileService.getHfpClient() != null)
+                    intent = new Intent(getActivity(), HfpTestActivity.class);
+                else {
+                    Log.v(TAG, "HfpClient service is null");
+                    return;
+                }
                 break;
 
             case MAP:
diff --git a/res/values/config.xml b/res/values/config.xml
index ce26ba4..6c6a875 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -16,4 +16,6 @@
     <bool name="profile_supported_ftp">true</bool>
     <bool name="profile_supported_map">true</bool>
     <bool name="profile_supported_sap">true</bool>
+    <bool name="profile_supported_dun">true</bool>
+    <bool name="profile_supported_btc">false</bool>
 </resources>
diff --git a/res/values/strings_dun.xml b/res/values/strings_dun.xml
new file mode 100644
index 0000000..f491270
--- /dev/null
+++ b/res/values/strings_dun.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (c) 2011-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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="dun_notif_ticker">Bluetooth DUN request</string>
+    <!-- Notification title when a Bluetooth device wants to pair with us -->
+    <string name="dun_notif_title">Session Key Request for DUN</string>
+    <!-- Notification message when a Bluetooth device wants to pair with us -->
+    <string name="dun_notif_message">"Touch to connect to \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022."</string>
+    <string name="dun_acceptance_timeout_message">There was time out to accept connection with %1$s</string>
+    <!-- Activity label of BluetoothDunPermissionActivity, also used as Strings in the permission dialog [CHAR LIMIT=none] -->
+    <string name="bluetooth_dun_request">"DUN request"</string>
+    <!-- Bluetooth DUN permission Alert Activity text [CHAR LIMIT=none] -->
+    <string name="bluetooth_dun_acceptance_dialog_text">%1$s would like to use DUN. Give access to %2$s?</string>
+
+</resources>
diff --git a/src/org/codeaurora/bluetooth/dun/BluetoothDunPermissionActivity.java b/src/org/codeaurora/bluetooth/dun/BluetoothDunPermissionActivity.java
new file mode 100644
index 0000000..74ffd94
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/dun/BluetoothDunPermissionActivity.java
@@ -0,0 +1,309 @@
+/*
+ * 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.dun;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.Preference;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+
+import org.codeaurora.bluetooth.R;
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+
+/**
+ * DunPermissionActivity shows dialogues for accepting incoming DUN request
+ * with a remote Bluetooth device.
+  */
+
+public class BluetoothDunPermissionActivity extends AlertActivity implements
+        DialogInterface.OnClickListener, Preference.OnPreferenceChangeListener, TextWatcher {
+    private static final String TAG = "BluetoothDunPermissionActivity";
+
+    private static final boolean V = BluetoothDunService.VERBOSE;
+
+    private static final int DIALOG_YES_NO_CONNECT = 1;
+
+    private static final String KEY_USER_TIMEOUT = "user_timeout";
+
+    private View mView;
+
+    private EditText mKeyView;
+
+    private TextView messageView;
+
+    private int mCurrentDialog;
+
+    private Button mOkButton;
+
+    private CheckBox mAlwaysAllowed;
+
+    private boolean mTimeout = false;
+
+    private boolean mAlwaysAllowedValue = false;
+
+    private static final int DISMISS_TIMEOUT_DIALOG = 0;
+
+    private static final int DISMISS_TIMEOUT_DIALOG_VALUE = 2000;
+
+    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (!BluetoothDunService.USER_CONFIRM_TIMEOUT_ACTION.equals(intent.getAction())) {
+                return;
+            }
+            onTimeout();
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent i = getIntent();
+        String action = i.getAction();
+        if (BluetoothDunService.DUN_ACCESS_REQUEST_ACTION.equals(action)) {
+            showDunDialog(DIALOG_YES_NO_CONNECT);
+            mCurrentDialog = DIALOG_YES_NO_CONNECT;
+        }
+        else {
+            Log.e(TAG, "Error: this activity may be started only with intent "
+                    + "DUN_ACCESS_REQUEST");
+            finish();
+        }
+        registerReceiver(mReceiver, new IntentFilter(
+                BluetoothDunService.USER_CONFIRM_TIMEOUT_ACTION));
+    }
+
+    private void showDunDialog(int id) {
+        final AlertController.AlertParams p = mAlertParams;
+        switch (id) {
+            case DIALOG_YES_NO_CONNECT:
+                p.mIconId = android.R.drawable.ic_dialog_info;
+                p.mTitle = getString(R.string.bluetooth_dun_request);
+                p.mView = createView(DIALOG_YES_NO_CONNECT);
+                p.mPositiveButtonText = getString(android.R.string.yes);
+                p.mPositiveButtonListener = this;
+                p.mNegativeButtonText = getString(android.R.string.no);
+                p.mNegativeButtonListener = this;
+                mOkButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE);
+                setupAlert();
+                break;
+            default:
+                break;
+        }
+    }
+
+    private String getRemoteDeviceName() {
+        String remoteDeviceName = null;
+        Intent intent = getIntent();
+        if (intent.hasExtra(BluetoothDunService.EXTRA_BLUETOOTH_DEVICE)) {
+            BluetoothDevice device = intent.getParcelableExtra(BluetoothDunService.EXTRA_BLUETOOTH_DEVICE);
+            if (device != null) {
+                remoteDeviceName = device.getName();
+            }
+        }
+
+        return (remoteDeviceName != null) ? remoteDeviceName : getString(R.string.defaultname);
+    }
+
+    private String createDisplayText(final int id) {
+        String mRemoteName = getRemoteDeviceName();
+        switch (id) {
+        case DIALOG_YES_NO_CONNECT:
+            String mMessage1 = getString(R.string.bluetooth_dun_acceptance_dialog_text, mRemoteName,
+                    mRemoteName);
+            return mMessage1;
+        default:
+            return null;
+        }
+    }
+
+    private View createView(final int id) {
+        switch (id) {
+            case DIALOG_YES_NO_CONNECT:
+                mView = getLayoutInflater().inflate(R.layout.bluetooth_access, null);
+                messageView = (TextView)mView.findViewById(R.id.message);
+                messageView.setText(createDisplayText(id));
+                mAlwaysAllowed = (CheckBox)mView.findViewById(R.id.alwaysallowed);
+                mAlwaysAllowed.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                        if (isChecked) {
+                            mAlwaysAllowedValue = true;
+                        } else {
+                            mAlwaysAllowedValue = false;
+                        }
+                    }
+                });
+                return mView;
+            default:
+                return null;
+        }
+    }
+
+    private void onPositive() {
+        if (!mTimeout) {
+            if (mCurrentDialog == DIALOG_YES_NO_CONNECT) {
+                sendIntentToReceiver(BluetoothDunService.DUN_ACCESS_ALLOWED_ACTION,
+                        BluetoothDunService.DUN_EXTRA_ALWAYS_ALLOWED, mAlwaysAllowedValue);
+            }
+        }
+        mTimeout = false;
+        finish();
+    }
+
+    private void onNegative() {
+        if (mCurrentDialog == DIALOG_YES_NO_CONNECT) {
+            sendIntentToReceiver(BluetoothDunService.DUN_ACCESS_DISALLOWED_ACTION, null, null);
+        }
+        finish();
+    }
+
+    private void sendIntentToReceiver(final String intentName, final String extraName,
+            final String extraValue) {
+        Intent intent = new Intent(intentName);
+        intent.setClassName(BluetoothDunService.THIS_PACKAGE_NAME, BluetoothDunReceiver.class
+                .getName());
+        if (extraName != null) {
+            intent.putExtra(extraName, extraValue);
+        }
+        sendBroadcast(intent);
+    }
+
+    private void sendIntentToReceiver(final String intentName, final String extraName,
+            final boolean extraValue) {
+        Intent intent = new Intent(intentName);
+        intent.setClassName(BluetoothDunService.THIS_PACKAGE_NAME, BluetoothDunReceiver.class
+                .getName());
+        if (extraName != null) {
+            intent.putExtra(extraName, extraValue);
+        }
+        Intent i = getIntent();
+        if (i.hasExtra(BluetoothDunService.EXTRA_BLUETOOTH_DEVICE)) {
+            intent.putExtra(BluetoothDunService.EXTRA_BLUETOOTH_DEVICE, i.getParcelableExtra(BluetoothDunService.EXTRA_BLUETOOTH_DEVICE));
+        }
+        sendBroadcast(intent);
+    }
+
+    public void onClick(DialogInterface dialog, int which) {
+        switch (which) {
+            case DialogInterface.BUTTON_POSITIVE:
+                onPositive();
+                break;
+
+            case DialogInterface.BUTTON_NEGATIVE:
+                onNegative();
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void onTimeout() {
+        mTimeout = true;
+        if (mCurrentDialog == DIALOG_YES_NO_CONNECT) {
+            if(mView != null) {
+                messageView.setText(getString(R.string.dun_acceptance_timeout_message,
+                        getRemoteDeviceName()));
+                mAlert.getButton(DialogInterface.BUTTON_NEGATIVE).setVisibility(View.GONE);
+                mAlwaysAllowed.setVisibility(View.GONE);
+                mAlwaysAllowed.clearFocus();
+            }
+        }
+
+        mTimeoutHandler.sendMessageDelayed(mTimeoutHandler.obtainMessage(DISMISS_TIMEOUT_DIALOG),
+                DISMISS_TIMEOUT_DIALOG_VALUE);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Bundle savedInstanceState) {
+        super.onRestoreInstanceState(savedInstanceState);
+        mTimeout = savedInstanceState.getBoolean(KEY_USER_TIMEOUT);
+        if (V) Log.v(TAG, "onRestoreInstanceState() mTimeout: " + mTimeout);
+
+        if (mTimeout) {
+            onTimeout();
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putBoolean(KEY_USER_TIMEOUT, mTimeout);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        unregisterReceiver(mReceiver);
+    }
+
+    public boolean onPreferenceChange(Preference preference, Object newValue) {
+        return true;
+    }
+
+    public void beforeTextChanged(CharSequence s, int start, int before, int after) {
+    }
+
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    }
+
+    public void afterTextChanged(android.text.Editable s) {
+        if (s.length() > 0) {
+            mOkButton.setEnabled(true);
+        }
+    }
+    private final Handler mTimeoutHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case DISMISS_TIMEOUT_DIALOG:
+                    if (V) Log.v(TAG, "Received DISMISS_TIMEOUT_DIALOG msg.");
+                    finish();
+                    break;
+                default:
+                    break;
+            }
+        }
+    };
+}
diff --git a/src/org/codeaurora/bluetooth/dun/BluetoothDunReceiver.java b/src/org/codeaurora/bluetooth/dun/BluetoothDunReceiver.java
new file mode 100644
index 0000000..60f3dc7
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/dun/BluetoothDunReceiver.java
@@ -0,0 +1,82 @@
+/*
+ * 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.dun;
+
+import android.bluetooth.BluetoothAdapter;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+import android.os.SystemProperties;
+
+public class BluetoothDunReceiver extends BroadcastReceiver {
+
+    private static final String TAG = "BluetoothDunReceiver";
+
+    private static final boolean V = BluetoothDunService.VERBOSE;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+
+        if(SystemProperties.getBoolean("ro.bluetooth.dun", false) == false) {
+            return;
+        }
+
+        if (V) Log.v(TAG, "DunReceiver onReceive ");
+
+        Intent in = new Intent();
+        in.putExtras(intent);
+        in.setClass(context, BluetoothDunService.class);
+        String action = intent.getAction();
+        in.putExtra("action", action);
+        if (V) Log.v(TAG,"action = " + action);
+
+        boolean startService = true;
+
+        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+            int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+            in.putExtra(BluetoothAdapter.EXTRA_STATE, state);
+            if (V) Log.v(TAG," Bluetooth Adapter state = " + state);
+            if ((state == BluetoothAdapter.STATE_TURNING_ON)
+                    || (state == BluetoothAdapter.STATE_OFF)) {
+                startService = false;
+            }
+        } else {
+            // Don't forward intent unless device has bluetooth and bluetooth is enabled.
+            BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+            if (adapter == null || !adapter.isEnabled()) {
+                startService = false;
+            }
+        }
+        if (startService) {
+            if (V) Log.v(TAG,"Calling DUN service start service with action = " + in.getAction());
+            context.startService(in);
+        }
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/dun/BluetoothDunService.java b/src/org/codeaurora/bluetooth/dun/BluetoothDunService.java
new file mode 100644
index 0000000..88ea756
--- /dev/null
+++ b/src/org/codeaurora/bluetooth/dun/BluetoothDunService.java
@@ -0,0 +1,1436 @@
+/*
+ * 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.dun;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothDun;
+import android.bluetooth.BluetoothProfile;
+import android.bluetooth.IBluetoothDun;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import android.bluetooth.BluetoothAdapter;
+import android.os.SystemProperties;
+import android.app.Service;
+import android.bluetooth.IBluetooth;
+import android.bluetooth.BluetoothServerSocket;
+import android.bluetooth.BluetoothSocket;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import java.io.OutputStream;
+import java.io.InputStream;
+import android.os.IBinder;
+import java.nio.ByteBuffer;
+import java.io.IOException;
+import android.content.ServiceConnection;
+import android.os.ParcelUuid;
+import java.util.UUID;
+import android.text.TextUtils;
+import android.content.ComponentName;
+import android.os.RemoteException;
+import org.codeaurora.bluetooth.R;
+
+/**
+ * Provides Bluetooth Dun profile, as a service in the BluetoothExt APK.
+ * @hide
+ */
+
+public class BluetoothDunService extends Service {
+
+    private static final String TAG                             = "BluetoothDunService";
+    private static final boolean DBG                            = false;
+    public  static final boolean VERBOSE                        = false;
+
+    private final static String DUN_SERVER                      = "qcom.dun.server";
+
+    private static final int MESSAGE_START_LISTENER             = 0x01;
+    private static final int MESSAGE_DUN_USER_TIMEOUT           = 0x02;
+
+    private static final int USER_CONFIRM_TIMEOUT_VALUE         = 30000; // 30 seconds
+
+    private static final int MON_THREAD_SLEEP_INTERVAL          = 200; // 200 mseconds
+
+    /**
+     * IPC message types which can be exchanged between
+     * Dun server process and BluetoothDunService
+     */
+    private static final byte DUN_IPC_MSG_DUN_REQUEST           = 0x00;
+    private static final byte DUN_IPC_MSG_DUN_RESPONSE          = 0x01;
+    private static final byte DUN_IPC_MSG_CTRL_REQUEST          = 0x02;
+    private static final byte DUN_IPC_MSG_CTRL_RESPONSE         = 0x03;
+    private static final byte DUN_IPC_MSG_MDM_STATUS            = 0x04;
+
+    /**
+     * Control message types between Dun server and
+     * BluetoothDunService
+     */
+    private static final byte DUN_CRTL_MSG_DISCONNECT_REQ       = 0x00;
+    private static final byte DUN_CRTL_MSG_CONNECTED_RESP       = 0x01;
+    private static final byte DUN_CRTL_MSG_DISCONNECTED_RESP    = 0x02;
+
+    /**
+     * Offsets of message data with in the IPC message
+     */
+    private static final byte DUN_IPC_MSG_OFF_MSG_TYPE          = 0x00;
+    private static final byte DUN_IPC_MSG_OFF_MSG_LEN           = 0x01;
+    private static final byte DUN_IPC_MSG_OFF_MSG               = 0x03;
+
+    /**
+     * Server supported DUN Profile's maximum message size
+     */
+    private static final int DUN_MAX_MSG_LEN                    = 32764;
+
+    /**
+     * IPC message's header size
+     */
+    private static final int DUN_IPC_HEADER_SIZE                = 0x03;
+
+    /**
+     * IPC message's maximum message size (Dun server <---> DUN service)
+     */
+    private static final int DUN_MAX_IPC_MSG_LEN                = DUN_MAX_MSG_LEN +
+                                                                  DUN_IPC_HEADER_SIZE;
+    /**
+     * IPC message's control message size
+     */
+    private static final byte DUN_IPC_CTRL_MSG_SIZE             = 0x01;
+
+    /**
+     * IPC message's modem status message size
+     */
+    private static final byte DUN_IPC_MDM_STATUS_MSG_SIZE       = 0x01;
+
+    /**
+     * BT socket options
+     */
+    private static final int BTSOCK_OPT_GET_MODEM_BITS          = 0x01;
+    private static final int BTSOCK_OPT_SET_MODEM_BITS          = 0x02;
+    private static final int BTSOCK_OPT_CLR_MODEM_BITS          = 0x03;
+
+    private static IBluetooth mAdapterService                   = null;
+
+    private static BluetoothDevice mRemoteDevice                = null;
+
+    private static volatile SocketAcceptThread mAcceptThread    = null;
+
+    /**
+     * Thread for reading the requests from DUN client using the socket
+     * mRfcommSocket and upload the same requests to DUNd using the
+     * socket mDundSocket
+     */
+    private static volatile UplinkThread mUplinkThread          = null;
+
+    /**
+     * Thtread for reading(download) the responses from DUNd using
+     * the socket mDundSocket and route the same responses to
+     * DUN client using the socket mRfcommSocket
+     */
+    private static volatile DownlinkThread mDownlinkThread      = null;
+
+    /**
+     * Thtread for monitoring the modem status and base on the status
+     * chnage it will update the DUN server with the updated status
+     */
+    private static volatile MonitorThread mMonitorThread      = null;
+
+    /**
+     * Listening Rfcomm Socket
+     */
+    private static volatile BluetoothServerSocket mListenSocket = null;
+
+    /**
+     * Connected Rfcomm socket
+     */
+    private static volatile BluetoothSocket mRfcommSocket       = null;
+
+    /**
+     * Socket represents the connection between DUNd and DUN service
+     */
+    private static volatile LocalSocket mDundSocket             = null;
+
+    private boolean mIsWaitingAuthorization                     = false;
+
+    private volatile boolean mInterrupted                       = false;
+
+    private boolean mDunEnable                                  = false;
+
+    private byte mRmtMdmStatus                                  = 0x00;
+
+    /**
+     * DUN profile's UUID
+     */
+    private static final String DUN_UUID = "00001103-0000-1000-8000-00805F9B34FB";
+
+    /**
+     * Intent indicating incoming connection request which is sent to
+     * BluetoothDunPermissionActivity
+     */
+    public static final String DUN_ACCESS_REQUEST_ACTION =
+                                     "org.codeaurora.bluetooth.dun.accessrequest";
+
+    /**
+     * Intent indicating incoming connection request accepted by user which is
+     * sent from BluetoothDunPermissionActivity
+     */
+    public static final String DUN_ACCESS_ALLOWED_ACTION =
+                                     "org.codeaurora.bluetooth.dun.accessallowed";
+
+    /**
+     * Intent indicating incoming connection request denied by user which is
+     * sent from BluetoothDunPermissionActivity
+     */
+    public static final String DUN_ACCESS_DISALLOWED_ACTION =
+                                  "org.codeaurora.bluetooth.dun.accessdisallowed";
+
+    /**
+     * Intent indicating timeout for user confirmation, which is sent to
+     * BluetoothDunPermissionActivity
+     */
+    public static final String USER_CONFIRM_TIMEOUT_ACTION =
+                                "org.codeaurora.bluetooth.dun.userconfirmtimeout";
+
+    public static final String THIS_PACKAGE_NAME = "org.codeaurora.bluetooth";
+
+    /**
+     * Intent Extra name indicating always allowed which is sent from
+     * BluetoothDunPermissionActivity
+     */
+    public static final String DUN_EXTRA_ALWAYS_ALLOWED =
+                                     "org.codeaurora.bluetooth.dun.alwaysallowed";
+
+    // Ensure not conflict with Opp notification ID
+    private static final int DUN_NOTIFICATION_ID_ACCESS = -1000006;
+
+    /**
+     * Intent Extra name indicating BluetoothDevice which is sent to
+     * BluetoothDunPermissionActivity
+     */
+    public static final String EXTRA_BLUETOOTH_DEVICE =
+                                   "org.codeaurora.bluetooth.dun.bluetoothdevice";
+
+    /**
+     * String signifies the DUN profile status
+     */
+    public static final String BLUETOOTH_DUN_PROFILE_STATUS = "bluetooth.dun.status";
+
+    public static final ParcelUuid DUN = ParcelUuid.fromString(DUN_UUID);
+
+    private static final Object mAcceptLock = new Object();
+
+    private static final Object mUplinkLock = new Object();
+
+    private static final Object mDownlinkLock = new Object();
+
+    private static final Object mMonitorLock = new Object();
+
+    private static final Object mAuthLock = new Object();
+
+    private HashMap<BluetoothDevice, BluetoothDunDevice> mDunDevices;
+
+    private IBinder mDunBinder;
+
+    private BluetoothAdapter mAdapter;
+
+    /**
+     * package and class name to which we send intent to check DUN profile
+     * access permission
+     */
+    private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings";
+    private static final String ACCESS_AUTHORITY_CLASS =
+        "com.android.settings.bluetooth.BluetoothPermissionRequest";
+
+    private static final String BLUETOOTH_ADMIN_PERM =
+                    android.Manifest.permission.BLUETOOTH_ADMIN;
+
+    private static final String BLUETOOTH_PERM =
+                    android.Manifest.permission.BLUETOOTH;
+
+    @Override
+    public void onCreate() {
+
+        super.onCreate();
+
+        if (VERBOSE) Log.v(TAG, "Dun Service onCreate");
+
+        mDunDevices = new HashMap<BluetoothDevice, BluetoothDunDevice>();
+
+        mAdapter = BluetoothAdapter.getDefaultAdapter();
+        mDunBinder = initBinder();
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+
+        mInterrupted = false;
+
+        if (mAdapter == null) {
+            Log.w(TAG, "Stopping BluetoothDunService: "
+                    + "device does not have BT or device is not ready");
+            // Release all resources
+            closeDunService();
+        } else {
+            if (intent != null) {
+                parseIntent(intent);
+            }
+        }
+        return START_NOT_STICKY;
+    }
+
+    @Override
+    public void onDestroy() {
+        if (VERBOSE) Log.v(TAG, "Dun Service onDestroy");
+
+        super.onDestroy();
+
+        if(mDunDevices != null)
+            mDunDevices.clear();
+
+        closeDunService();
+        if(mDunHandler != null) {
+            mDunHandler.removeCallbacksAndMessages(null);
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (VERBOSE) Log.v(TAG, "Dun Service onBind");
+        return mDunBinder;
+    }
+
+    private IBinder initBinder() {
+        return new BluetoothDunBinder(this);
+    }
+
+    private final Handler mDunHandler = new Handler() {
+        @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MESSAGE_START_LISTENER:
+                        if (mAdapter.isEnabled()) {
+                            startRfcommListenerThread();
+                        }
+                        break;
+                    case MESSAGE_DUN_USER_TIMEOUT:
+                        {
+                            synchronized(mAuthLock) {
+                                if (!mIsWaitingAuthorization) {
+                                    // already handled, ignore it
+                                    break;
+                                }
+
+                                mIsWaitingAuthorization = false;
+                            }
+                            Intent intent = new Intent(USER_CONFIRM_TIMEOUT_ACTION);
+                            intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mRemoteDevice);
+                            sendBroadcast(intent);
+                            removeDunNotification(DUN_NOTIFICATION_ID_ACCESS);
+                            /* close the rfcomm socket and restart the listener thread */
+                            closeRfcommSocket();
+                            startRfcommListenerThread();
+
+                            if (DBG) Log.d(TAG,"DUN user Authorization Timeout");
+                        }
+                        break;
+                }
+            }
+    };
+
+    // process the intent from DUN receiver
+    private void parseIntent(final Intent intent) {
+
+        String action = intent.getStringExtra("action");
+        if (VERBOSE) Log.v(TAG, "action: " + action);
+
+        int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
+        if (VERBOSE) Log.v(TAG, "state: " + state);
+
+        boolean removeTimeoutMsg = true;
+        if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
+
+            if ((state == BluetoothAdapter.STATE_ON) && (!mDunEnable)) {
+
+                synchronized(mConnection) {
+                    try {
+                        if (mAdapterService == null) {
+                            if ( !bindService(new Intent(IBluetooth.class.getName()), mConnection, 0)) {
+                                Log.v(TAG, "Could not bind to AdapterService");
+                                return;
+                            }
+                        }
+                    } catch (Exception e) {
+                        Log.e(TAG, "bindService Exception", e);
+                        return;
+                    }
+                }
+
+                Log.v(TAG, "Starting DUN server process");
+                SystemProperties.set(BLUETOOTH_DUN_PROFILE_STATUS, "running");
+
+                mDunHandler.sendMessage(mDunHandler
+                        .obtainMessage(MESSAGE_START_LISTENER));
+
+                mDunEnable = true;
+            }
+            else if (state == BluetoothAdapter.STATE_TURNING_OFF) {
+                // Send any pending timeout now, as this service will be destroyed.
+                if (mDunHandler.hasMessages(MESSAGE_DUN_USER_TIMEOUT)) {
+                    Intent timeoutIntent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_CANCEL);
+                    timeoutIntent.setClassName(ACCESS_AUTHORITY_PACKAGE, ACCESS_AUTHORITY_CLASS);
+                    sendBroadcast(timeoutIntent, BLUETOOTH_ADMIN_PERM);
+                }
+
+                if (mDunEnable) {
+                    Log.v(TAG, "Stopping DUN server process");
+                    SystemProperties.set(BLUETOOTH_DUN_PROFILE_STATUS, "stopped");
+
+                    synchronized(mConnection) {
+                        try {
+                            mAdapterService = null;
+                            unbindService(mConnection);
+                        } catch (Exception e) {
+                            Log.e(TAG, "", e);
+                        }
+                    }
+
+                    // Release all resources
+                    closeDunService();
+                    mDunEnable = false;
+                }
+                synchronized(mAuthLock) {
+                    if (mIsWaitingAuthorization) {
+                        removeDunNotification(DUN_NOTIFICATION_ID_ACCESS);
+                        mIsWaitingAuthorization = false;
+                    }
+                }
+
+            } else {
+                removeTimeoutMsg = false;
+            }
+        } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED) &&
+                                 mIsWaitingAuthorization) {
+            if (mRemoteDevice == null) {
+               Log.e(TAG, "Unexpected error!");
+               return;
+            }
+            if (mDunHandler != null) {
+               /* Let the user timeout handle this case as well */
+               mDunHandler.sendMessage(mDunHandler.obtainMessage(MESSAGE_DUN_USER_TIMEOUT));
+               removeTimeoutMsg = false;
+            }
+
+        }  else if (action.equals(DUN_ACCESS_ALLOWED_ACTION)) {
+            if (mRemoteDevice == null) {
+               Log.e(TAG, "Unexpected error!");
+               return;
+            }
+
+            if (VERBOSE) {
+
+                Log.v(TAG, "DunService-Received ACCESS_ALLOWED_ACTION");
+            }
+            synchronized(mAuthLock) {
+                if (!mIsWaitingAuthorization) {
+                    // this reply is not for us
+                    return;
+                }
+
+                mIsWaitingAuthorization = false;
+            }
+
+            if (intent.getBooleanExtra(BluetoothDunService.DUN_EXTRA_ALWAYS_ALLOWED, false) == true) {
+                  if(mRemoteDevice != null) {
+                     mRemoteDevice.setTrust(true);
+                     Log.v(TAG, "setTrust() TRUE " + mRemoteDevice.getName());
+                  }
+            }
+            /* start the uplink thread */
+            startUplinkThread();
+
+        } else if (action.equals(DUN_ACCESS_DISALLOWED_ACTION)) {
+            /* close the rfcomm socket and restart the listener thread */
+            closeRfcommSocket();
+            startRfcommListenerThread();
+        } else if ( BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
+
+            if (intent.hasExtra(BluetoothDevice.EXTRA_DEVICE)) {
+               BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+                if(device != null)
+                    Log.d(TAG,"device: "+ device.getName());
+                if(mRemoteDevice != null)
+                    Log.d(TAG," Remtedevie: "+mRemoteDevice.getName());
+               if ((device != null) && (mRemoteDevice != null) && (device.equals(mRemoteDevice)) &&
+                    (mRemoteDevice.getTrustState()) && (intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
+                               BluetoothDevice.BOND_NONE) == BluetoothDevice.BOND_NONE)) {
+
+                   Log.d(TAG,"BOND_STATE_CHANGED REFRESH trustDevices"+ device.getName());
+                   mRemoteDevice.setTrust(false);
+               }
+            }
+
+        } else {
+            removeTimeoutMsg = false;
+        }
+
+        if (removeTimeoutMsg) {
+            mDunHandler.removeMessages(MESSAGE_DUN_USER_TIMEOUT);
+        }
+    }
+
+    private void startRfcommListenerThread() {
+        if (VERBOSE) Log.v(TAG, "DUN Service startRfcommListenerThread");
+
+        synchronized(mAcceptLock) {
+            // if it is already running,close it
+            if (mAcceptThread != null) {
+                try {
+                    mAcceptThread.shutdown();
+                    mAcceptThread.join();
+                    mAcceptThread = null;
+                } catch (InterruptedException ex) {
+                    Log.w(TAG, "mAcceptThread close error" + ex);
+                }
+            }
+            if (mAcceptThread == null) {
+                mAcceptThread = new SocketAcceptThread();
+                mAcceptThread.setName("BluetoothDunAcceptThread");
+                mAcceptThread.start();
+            }
+        }
+    }
+
+    private void startUplinkThread() {
+        if (VERBOSE) Log.v(TAG, "DUN Service startUplinkThread");
+
+        synchronized(mUplinkLock) {
+            if (mUplinkThread != null) {
+                try {
+                    mUplinkThread.shutdown();
+                    mUplinkThread.join();
+                    mUplinkThread = null;
+                } catch (InterruptedException ex) {
+                    Log.w(TAG, "mUplinkThread close error" + ex);
+                }
+            }
+            if (mUplinkThread == null) {
+                mUplinkThread = new UplinkThread();
+                mUplinkThread.setName("BluetoothDunUplinkThread");
+                mUplinkThread.start();
+            }
+        }
+    }
+
+    private void startDownlinkThread() {
+        if (VERBOSE) Log.v(TAG, "DUN Service startDownlinkThread");
+
+        synchronized(mDownlinkLock) {
+            if (mDownlinkThread == null) {
+                mDownlinkThread = new DownlinkThread();
+                mDownlinkThread.setName("BluetoothDunDownlinkThread");
+                mDownlinkThread.start();
+            }
+        }
+    }
+
+    private void startMonitorThread() {
+        if (VERBOSE) Log.v(TAG, "DUN Service startMonitorThread");
+
+        synchronized(mMonitorLock) {
+            if (mMonitorThread  == null) {
+                mMonitorThread  = new MonitorThread();
+                mMonitorThread .setName("BluetoothDunMonitorThread");
+                mMonitorThread .start();
+            }
+        }
+    }
+
+    private final boolean initRfcommSocket() {
+        if (VERBOSE) Log.v(TAG, "Dun Service initRfcommSocket");
+
+        boolean initRfcommSocketOK = false;
+        final int CREATE_RETRY_TIME = 10;
+
+        // It's possible that create will fail in some cases. retry for 10 times
+        for (int i = 0; i < CREATE_RETRY_TIME && !mInterrupted; i++) {
+            initRfcommSocketOK = true;
+            try {
+                // start listening for incoming rfcomm channel connection
+                mListenSocket = mAdapter.listenUsingRfcommWithServiceRecord("Dial up Networking", DUN.getUuid());
+
+            } catch (IOException e) {
+                Log.e(TAG, "Error create RfcommListenSocket " + e.toString());
+                initRfcommSocketOK = false;
+            }
+            if (!initRfcommSocketOK) {
+                // Need to break out of this loop if BT is being turned off.
+                if (mAdapter == null) break;
+                int state = mAdapter.getState();
+                if ((state != BluetoothAdapter.STATE_TURNING_ON) && (state != BluetoothAdapter.STATE_ON)) {
+                    Log.w(TAG, "initRfcommSocket failed as BT is (being) turned off");
+                    break;
+                }
+                try {
+                    if (VERBOSE) Log.v(TAG, "wait 300 ms");
+                    Thread.sleep(300);
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "socketAcceptThread thread was interrupted (3)");
+                    break;
+                }
+            } else {
+                break;
+            }
+        }
+
+        if (mInterrupted) {
+            initRfcommSocketOK = false;
+            //close the listen socket to avoid resource leakage
+            closeListenSocket();
+        }
+
+        if (initRfcommSocketOK) {
+            if (VERBOSE) Log.v(TAG, "Succeed to create listening socket ");
+
+        } else {
+            Log.e(TAG, "Error to create listening socket after " + CREATE_RETRY_TIME + " try");
+        }
+        return initRfcommSocketOK;
+    }
+
+    private final boolean initDundClientSocket() {
+        if (VERBOSE) Log.v(TAG, "DUN initDundClientSocket");
+
+        boolean initDundSocketOK = false;
+
+        try {
+            LocalSocketAddress locSockAddr = new LocalSocketAddress(DUN_SERVER);
+            mDundSocket = new LocalSocket();
+            mDundSocket.connect(locSockAddr);
+            initDundSocketOK = true;
+        } catch (java.io.IOException e) {
+            Log.e(TAG, "cant connect: " + e);
+        }
+
+        if (initDundSocketOK) {
+            if (VERBOSE) Log.v(TAG, "Succeed to create Dund socket ");
+
+        } else {
+            Log.e(TAG, "Error to create Dund socket");
+        }
+        return initDundSocketOK;
+    }
+
+    private final synchronized void closeListenSocket() {
+        // exit SocketAcceptThread early
+        if (VERBOSE) Log.v(TAG, "Close listen Socket : " );
+        if (mListenSocket != null) {
+            try {
+                // this will cause mListenSocket.accept() return early with
+                // IOException
+                mListenSocket.close();
+                mListenSocket = null;
+            } catch (IOException ex) {
+                Log.e(TAG, "Close listen Socket error: " + ex);
+            }
+        }
+    }
+
+    private final synchronized void closeRfcommSocket() {
+        if (VERBOSE) Log.v(TAG, "Close rfcomm Socket : " );
+        if (mRfcommSocket != null) {
+            try {
+                mRfcommSocket.close();
+                mRfcommSocket = null;
+            } catch (IOException e) {
+                Log.e(TAG, "Close Rfcomm Socket error: " + e.toString());
+            }
+        }
+    }
+
+    private final synchronized void closeDundSocket() {
+        if (VERBOSE) Log.v(TAG, "Close dund  Socket : " );
+        if (mDundSocket != null) {
+            try {
+                mDundSocket.close();
+                mDundSocket = null;
+            } catch (IOException e) {
+                Log.e(TAG, "Close Dund Socket error: " + e.toString());
+            }
+        }
+    }
+
+    private final void closeDunService() {
+        if (VERBOSE) Log.v(TAG, "Dun Service closeDunService in");
+
+        // exit initRfcommSocket early
+        mInterrupted = true;
+
+        closeListenSocket();
+
+        closeRfcommSocket();
+
+        closeDundSocket();
+
+        synchronized(mMonitorLock) {
+            if (mMonitorThread != null) {
+                try {
+                    mMonitorThread.shutdown();
+                    mMonitorThread.join();
+                    mMonitorThread = null;
+                } catch (InterruptedException ex) {
+                    Log.w(TAG, "mMonitorThread close error" + ex);
+                }
+            }
+        }
+
+        synchronized(mDownlinkLock) {
+            if (mDownlinkThread != null) {
+                try {
+                    mDownlinkThread.shutdown();
+                    mDownlinkThread.join();
+                    mDownlinkThread = null;
+                } catch (InterruptedException ex) {
+                    Log.w(TAG, "mDownlinkThread close error" + ex);
+                }
+            }
+        }
+
+        synchronized(mUplinkLock) {
+            if (mUplinkThread != null) {
+                try {
+                    mUplinkThread.shutdown();
+                    mUplinkThread.join();
+                    mUplinkThread = null;
+                } catch (InterruptedException ex) {
+                    Log.w(TAG, "mUplinkThread close error" + ex);
+                }
+            }
+        }
+        /* remove the MESSAGE_START_LISTENER message which might be posted
+         * by the uplink thread */
+        mDunHandler.removeMessages(MESSAGE_START_LISTENER);
+
+        synchronized(mAcceptLock) {
+            if (mAcceptThread != null) {
+                try {
+                    mAcceptThread.shutdown();
+                    mAcceptThread.join();
+                    mAcceptThread = null;
+                } catch (InterruptedException ex) {
+                    Log.w(TAG, "mAcceptThread close error" + ex);
+                }
+            }
+        }
+
+        stopSelf();
+
+        if (VERBOSE) Log.v(TAG, "Dun Service closeDunService out");
+    }
+
+    private void createDunNotification(BluetoothDevice device) {
+        if (VERBOSE) Log.v(TAG, "Creating DUN access notification");
+
+        NotificationManager nm = (NotificationManager)
+                getSystemService(Context.NOTIFICATION_SERVICE);
+
+        // Create an intent triggered by clicking on the status icon.
+        Intent clickIntent = new Intent();
+        clickIntent.setClass(this, BluetoothDunPermissionActivity.class);
+        clickIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        clickIntent.setAction(DUN_ACCESS_REQUEST_ACTION);
+        clickIntent.putExtra(EXTRA_BLUETOOTH_DEVICE, device);
+
+        // Create an intent triggered by clicking on the
+        // "Clear All Notifications" button
+        Intent deleteIntent = new Intent();
+        deleteIntent.setClass(this, BluetoothDunReceiver.class);
+
+        Notification notification = null;
+        String name = device.getName();
+        if (TextUtils.isEmpty(name)) {
+            name = getString(R.string.defaultname);
+        }
+
+        deleteIntent.setAction(DUN_ACCESS_DISALLOWED_ACTION);
+        notification = new Notification(android.R.drawable.stat_sys_data_bluetooth,
+            getString(R.string.dun_notif_ticker), System.currentTimeMillis());
+        notification.setLatestEventInfo(this, getString(R.string.dun_notif_ticker),
+                getString(R.string.dun_notif_message, name), PendingIntent
+                        .getActivity(this, 0, clickIntent, 0));
+
+        notification.flags |= Notification.FLAG_AUTO_CANCEL;
+        notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
+        notification.defaults = Notification.DEFAULT_SOUND;
+        notification.deleteIntent = PendingIntent.getBroadcast(this, 0, deleteIntent, 0);
+        nm.notify(DUN_NOTIFICATION_ID_ACCESS, notification);
+
+
+        if (VERBOSE) Log.v(TAG, "Awaiting Authorization : DUN Connection : " + device.getName());
+
+    }
+
+    private void removeDunNotification(int id) {
+        Context context = getApplicationContext();
+        NotificationManager nm = (NotificationManager) context
+                .getSystemService(Context.NOTIFICATION_SERVICE);
+        nm.cancel(id);
+    }
+
+    /**
+     * A thread that runs in the background waiting for remote rfcomm
+     * connect.Once a remote socket connected, this thread shall be
+     * shutdown.When the remote disconnect,this thread shall run again
+     * waiting for next request.
+     */
+    private class SocketAcceptThread extends Thread {
+
+        private boolean stopped = false;
+
+        @Override
+        public void run() {
+            BluetoothServerSocket listenSocket;
+            if (mListenSocket == null) {
+                if (!initRfcommSocket()) {
+                    return;
+                }
+            }
+
+            while (!stopped) {
+                try {
+                    if (VERBOSE) Log.v(TAG, "Accepting socket connection...");
+                    listenSocket = mListenSocket;
+                    if (listenSocket == null) {
+                        Log.w(TAG, "mListenSocket is null");
+                        break;
+                    }
+
+                    mRfcommSocket = mListenSocket.accept();
+
+                    synchronized (BluetoothDunService.this) {
+                        if (mRfcommSocket == null) {
+                            Log.w(TAG, " mRfcommSocket is null");
+                            break;
+                        }
+                        mRemoteDevice = mRfcommSocket.getRemoteDevice();
+                    }
+                    if (mRemoteDevice == null) {
+                        /* close the rfcomm socket */
+                        closeRfcommSocket();
+                        Log.i(TAG, "getRemoteDevice() = null");
+                        break;
+                    }
+                    boolean trust = false;
+                    if (mRemoteDevice != null)
+                        trust = mRemoteDevice.getTrustState();
+                    if (VERBOSE) Log.v(TAG, "GetTrustState() = " + trust);
+
+                    if (trust) {
+                        /* start the uplink thread */
+                        startUplinkThread();
+                    } else {
+                        createDunNotification(mRemoteDevice);
+
+                        if (VERBOSE) Log.v(TAG, "incoming connection accepted from: "+ mRemoteDevice);
+                        mIsWaitingAuthorization = true;
+
+                        mDunHandler.sendMessageDelayed(mDunHandler.obtainMessage(MESSAGE_DUN_USER_TIMEOUT),
+                                 USER_CONFIRM_TIMEOUT_VALUE);
+                    }
+                    stopped = true; // job done ,close this thread;
+                    if (VERBOSE) Log.v(TAG, "SocketAcceptThread stopped ");
+                } catch (IOException ex) {
+                    stopped=true;
+                    if (VERBOSE) Log.v(TAG, "Accept thread exception: " + ex.toString());
+                }
+            }
+        }
+
+        void shutdown() {
+            stopped = true;
+            interrupt();
+        }
+    }
+
+    /**
+     * A thread that runs in the background waiting for remote DUNd socket
+     * connection.Once the connection is established, this thread starts the
+     * downlink thread and starts forwarding the DUN profile requests to
+     * the DUNd on receiving the requests from rfcomm channel.
+     */
+    private class UplinkThread extends Thread {
+
+        private boolean stopped = false;
+        private boolean IntExit = false;
+        private OutputStream mDundOutputStream = null;
+        private InputStream mRfcommInputStream = null;
+        ByteBuffer IpcMsgBuffer = ByteBuffer.allocate(DUN_MAX_IPC_MSG_LEN);
+        private int NumRead = 0;
+        private byte TempByte = 0;
+
+        @Override
+        public void run() {
+            if (mDundSocket == null) {
+                if (!initDundClientSocket()) {
+                    /*restart the listener thread */
+                    mDunHandler.sendMessage(mDunHandler.obtainMessage(MESSAGE_START_LISTENER));
+                    return;
+                }
+            }
+            if(mDundSocket != null) {
+                if( mDundSocket.isConnected())
+                    try {
+                        mDundOutputStream = mDundSocket.getOutputStream();
+                    } catch (IOException ex) {
+                        if (VERBOSE)
+                            Log.v(TAG, "mDundOutputStream exception: " + ex.toString());
+                    }
+                else return;
+            }
+            else return;
+
+            if (mRfcommSocket != null) {
+                if(mRfcommSocket.isConnected())
+                    try {
+                        mRfcommInputStream = mRfcommSocket.getInputStream();
+                    } catch (IOException ex) {
+                        if (VERBOSE)
+                            Log.v(TAG, "mRfcommInputStream exception: " + ex.toString());
+                    }
+                else return;
+            }
+            else return;
+
+            // create the downlink thread for reading the responses
+            //from DUN server process
+            startDownlinkThread();
+            // create the modem status monitor thread
+            startMonitorThread();
+
+            while (!stopped) {
+                try {
+                    if (VERBOSE)
+                        Log.v(TAG, "Reading the DUN requests from Rfcomm channel");
+                    /* Read the DUN request from Rfcomm channel */
+                    NumRead = mRfcommInputStream.read(IpcMsgBuffer.array(), DUN_IPC_MSG_OFF_MSG,
+                                                                                DUN_MAX_MSG_LEN);
+                    if ( NumRead < 0) {
+                        IntExit = true;
+                        break;
+                    }
+                    else if ( NumRead != 0) {
+                        /* Wrtie the same DUN request to the DUN server socket with
+                           some additional parameters */
+                        IpcMsgBuffer.put(DUN_IPC_MSG_OFF_MSG_TYPE, DUN_IPC_MSG_DUN_REQUEST);
+                        IpcMsgBuffer.putShort(DUN_IPC_MSG_OFF_MSG_LEN, (short)NumRead);
+                        /* swap bytes of message len as buffer is Big Endian */
+                        TempByte = IpcMsgBuffer.get(DUN_IPC_MSG_OFF_MSG_LEN);
+
+                        IpcMsgBuffer.put( DUN_IPC_MSG_OFF_MSG_LEN, IpcMsgBuffer.get(DUN_IPC_MSG_OFF_MSG_LEN + 1));
+
+                        IpcMsgBuffer.put(DUN_IPC_MSG_OFF_MSG_LEN + 1, TempByte);
+                        try {
+                            mDundOutputStream.write(IpcMsgBuffer.array(), 0, NumRead + DUN_IPC_HEADER_SIZE);
+                        } catch (IOException ex) {
+                            break;
+                        }
+                    }
+                } catch (IOException ex) {
+                    IntExit = true;
+                    if (VERBOSE) Log.v(TAG, "Rfcomm channel Read exception: " + ex.toString());
+                    break;
+                }
+            }
+            // send the disconneciton request immediate to Dun server
+            if (IntExit) {
+                disconnect(mRemoteDevice);
+            }
+
+            /* close the dund socket */
+            closeDundSocket();
+            /* close the rfcomm socket */
+            closeRfcommSocket();
+            // Intimate the Settings APP about the disconnection
+            handleDunDeviceStateChange(mRemoteDevice, BluetoothProfile.STATE_DISCONNECTED);
+
+            /* wait for dun downlink thread to close */
+                if (VERBOSE) Log.v(TAG, "wait for dun downlink thread to close");
+            synchronized (mDownlinkLock) {
+                if (mDownlinkThread != null) {
+                    try {
+                        mDownlinkThread.shutdown();
+                        mDownlinkThread.join();
+                        mDownlinkThread = null;
+                    } catch (InterruptedException ex) {
+                        Log.w(TAG, "mDownlinkThread close error" + ex);
+                    }
+                }
+            }
+
+            /* wait for dun monitor thread to close */
+                if (VERBOSE) Log.v(TAG, "wait for dun monitor thread to close ");
+            synchronized (mMonitorLock) {
+                if (mMonitorThread != null) {
+                    try {
+                        mMonitorThread.shutdown();
+                        mMonitorThread.join();
+                        mMonitorThread = null;
+                    } catch (InterruptedException ex) {
+                        Log.w(TAG, "mMonitorThread  close error" + ex);
+                    }
+                }
+            }
+
+            if (IntExit && !stopped) {
+                if (VERBOSE) Log.v(TAG, "starting the listener thread ");
+                /* start the listener thread */
+                mDunHandler.sendMessage(mDunHandler.obtainMessage(MESSAGE_START_LISTENER));
+            }
+            /* reset the modem status */
+            mRmtMdmStatus = 0x00;
+            if (VERBOSE) Log.v(TAG, "uplink thread exited ");
+        }
+
+        void shutdown() {
+            stopped = true;
+            interrupt();
+        }
+    }
+
+
+    /**
+     * A thread that runs in the background and monitors the modem status of rfcomm
+     * channel and when there is a change in the modem status it will update the
+     * DUN server process with the new status.
+     */
+    private class MonitorThread extends Thread {
+
+        private boolean stopped = false;
+        private int len = 0;
+        private byte modemStatus = 0;
+        ByteBuffer IpcMsgBuffer = ByteBuffer.allocate(DUN_IPC_MDM_STATUS_MSG_SIZE);
+        private byte TempByte = 0;
+
+        byte mdmBits = 0;
+
+        @Override
+        public void run() {
+
+            while (!stopped) {
+                try {
+                    //wait for 200 ms
+                    Thread.sleep(MON_THREAD_SLEEP_INTERVAL);
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "MonitorThread thread was interrupted");
+                    break;
+                }
+                try {
+                    if ((mRfcommSocket == null) || (!mRfcommSocket.isConnected())) {
+                        break;
+                    }
+                    len = mRfcommSocket.getSocketOpt(BTSOCK_OPT_GET_MODEM_BITS, IpcMsgBuffer.array());
+                    if(len != DUN_IPC_MDM_STATUS_MSG_SIZE)  {
+                        Log.e(TAG, "getSocketOpt return length of socket option mismatch:");
+                        continue;
+                    }
+                } catch (IOException ex) {
+                    if (VERBOSE) Log.v(TAG, "getSocketOpt Exception: " + ex.toString());
+                }
+                if( mdmBits != IpcMsgBuffer.get(0)) {
+                    mdmBits = IpcMsgBuffer.get(0);
+                    notifyModemStatus(mdmBits);
+                }
+            }
+            if (VERBOSE) Log.v(TAG, "MonitorThread thread exited ");
+        }
+
+        void shutdown() {
+            stopped = true;
+            interrupt();
+        }
+    }
+
+
+    /**
+     * A thread that runs in the background and starts forwarding the
+     * DUN profile responses received from Dund to the rfcomm channel.
+     */
+    private class DownlinkThread extends Thread {
+
+        private boolean stopped = false;
+        private OutputStream mRfcommOutputStream = null;
+        private InputStream mDundInputStream = null;
+        ByteBuffer IpcMsgBuffer = ByteBuffer.allocate(2*DUN_MAX_IPC_MSG_LEN);
+        private int NumRead = 0;
+        private int ReadIndex = 0;
+        private short MsgLen = 0;
+        private byte TempByte = 0;
+
+        @Override
+        public void run() {
+
+            if (mDundSocket != null) {
+                if ( mDundSocket.isConnected())
+                    try {
+                        mDundInputStream = mDundSocket.getInputStream();
+                    } catch (IOException ex) {
+                        if (VERBOSE) Log.v(TAG, "mDundInputStream exception: " + ex.toString());
+                    }
+                else return;
+            }
+            else return;
+
+            if (mRfcommSocket != null) {
+                if (mRfcommSocket.isConnected())
+                    try {
+                        mRfcommOutputStream = mRfcommSocket.getOutputStream();
+                    } catch (IOException ex) {
+                        if (VERBOSE) Log.v(TAG, "mRfcommOutputStream exception: " + ex.toString());
+                    }
+                else return;
+            }
+            else return;
+
+            while (!stopped) {
+                try {
+                    if (VERBOSE) Log.v(TAG, "Reading the DUN responses from Dund");
+                    /* Read the DUN responses from DUN server */
+                    NumRead = mDundInputStream.read(IpcMsgBuffer.array(),0, DUN_MAX_IPC_MSG_LEN);
+                    if (VERBOSE) Log.v(TAG, "NumRead" + NumRead);
+                    if ( NumRead < 0) {
+                        break;
+                    }
+                    else if( NumRead != 0) {
+                        /* some times read buffer contains multiple responses */
+                        do {
+                            /* swap bytes of message len as buffer is Big Endian */
+                            TempByte = IpcMsgBuffer.get(ReadIndex + DUN_IPC_MSG_OFF_MSG_LEN);
+
+                            IpcMsgBuffer.put(ReadIndex + DUN_IPC_MSG_OFF_MSG_LEN, IpcMsgBuffer.get(ReadIndex +
+                                         DUN_IPC_MSG_OFF_MSG_LEN + 1));
+
+                            IpcMsgBuffer.put(ReadIndex + DUN_IPC_MSG_OFF_MSG_LEN + 1, TempByte);
+
+                            MsgLen =  IpcMsgBuffer.getShort(ReadIndex + DUN_IPC_MSG_OFF_MSG_LEN);
+
+                            if((ReadIndex + MsgLen + DUN_IPC_HEADER_SIZE) > NumRead) {
+                                if (VERBOSE) Log.v(TAG, "Boundary condition hit");
+                                mDundInputStream.read(IpcMsgBuffer.array(), NumRead , ReadIndex + MsgLen + DUN_IPC_HEADER_SIZE - NumRead);
+
+                            }
+
+                            if (IpcMsgBuffer.get(ReadIndex + DUN_IPC_MSG_OFF_MSG_TYPE) == DUN_IPC_MSG_DUN_RESPONSE) {
+                                try {
+                                    mRfcommOutputStream.write(IpcMsgBuffer.array(), ReadIndex + DUN_IPC_MSG_OFF_MSG,
+                                           IpcMsgBuffer.getShort(ReadIndex + DUN_IPC_MSG_OFF_MSG_LEN));
+                                } catch (IOException ex) {
+                                    stopped = true;
+                                    break;
+                                }
+                                if (VERBOSE)
+                                    Log.v(TAG, "DownlinkThread Msg written to Rfcomm");
+                            }
+                            else if (IpcMsgBuffer.get(ReadIndex + DUN_IPC_MSG_OFF_MSG_TYPE) == DUN_IPC_MSG_CTRL_RESPONSE) {
+
+                                if (IpcMsgBuffer.get(ReadIndex + DUN_IPC_MSG_OFF_MSG) == DUN_CRTL_MSG_CONNECTED_RESP) {
+                                    handleDunDeviceStateChange(mRemoteDevice, BluetoothProfile.STATE_CONNECTED);
+                                }
+                                else if (IpcMsgBuffer.get(ReadIndex + DUN_IPC_MSG_OFF_MSG) == DUN_CRTL_MSG_DISCONNECTED_RESP) {
+                                    handleDunDeviceStateChange(mRemoteDevice, BluetoothProfile.STATE_DISCONNECTED);
+                                }
+                                if (VERBOSE)
+                                    Log.v(TAG, "DownlinkThread control message received");
+                            }
+                            else if (IpcMsgBuffer.get(ReadIndex + DUN_IPC_MSG_OFF_MSG_TYPE) == DUN_IPC_MSG_MDM_STATUS) {
+                                /* handle the modem status messages */
+                                handleModemStatusChange(IpcMsgBuffer.get(ReadIndex + DUN_IPC_MSG_OFF_MSG));
+                                if (VERBOSE)
+                                    Log.v(TAG, "DownlinkThread modem status message received");
+                            }
+
+                            ReadIndex = ReadIndex + IpcMsgBuffer.getShort(ReadIndex + DUN_IPC_MSG_OFF_MSG_LEN);
+                            ReadIndex = ReadIndex + DUN_IPC_HEADER_SIZE;
+                        } while(ReadIndex < NumRead);
+                    }
+
+                } catch (IOException ex) {
+                    stopped = true;
+                    if (VERBOSE) Log.v(TAG, "Dund Read exception: " + ex.toString());
+                }
+                /* reset the ReadIndex */
+                ReadIndex = 0;
+            }
+            /* close the dund socket */
+            closeDundSocket();
+            /* close the rfcomm socket */
+            closeRfcommSocket();
+
+            if (VERBOSE) Log.v(TAG, "downlink thread exited ");
+        }
+
+        void shutdown() {
+            stopped = true;
+            interrupt();
+        }
+    }
+
+
+    boolean disconnect(BluetoothDevice device) {
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        OutputStream mDundOutputStream = null;
+        int WriteLen = DUN_IPC_HEADER_SIZE + DUN_IPC_CTRL_MSG_SIZE;
+        ByteBuffer IpcMsgBuffer = ByteBuffer.allocate(WriteLen);
+
+        if (mDundSocket != null) {
+            if ( mDundSocket.isConnected())
+                try {
+                    mDundOutputStream = mDundSocket.getOutputStream();
+                } catch (IOException ex) {
+                    if (VERBOSE) Log.v(TAG, "mDundOutputStream exception: " + ex.toString());
+                }
+            else return false;
+        }
+        else return false;
+
+        IpcMsgBuffer.put(DUN_IPC_MSG_OFF_MSG_TYPE, DUN_IPC_MSG_CTRL_REQUEST);
+        IpcMsgBuffer.putShort(DUN_IPC_MSG_OFF_MSG_LEN,DUN_IPC_CTRL_MSG_SIZE);
+        IpcMsgBuffer.put(DUN_IPC_MSG_OFF_MSG, DUN_CRTL_MSG_DISCONNECT_REQ);
+        try {
+            mDundOutputStream.write(IpcMsgBuffer.array(), 0, WriteLen);
+        } catch (IOException ex) {
+            if (VERBOSE) Log.v(TAG, "mDundOutputStream wrtie exception: " + ex.toString());
+        }
+        return true;
+    }
+
+    boolean notifyModemStatus(byte status) {
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        OutputStream mDundOutputStream = null;
+        int WriteLen = DUN_IPC_HEADER_SIZE + DUN_IPC_MDM_STATUS_MSG_SIZE;
+        ByteBuffer IpcMsgBuffer = ByteBuffer.allocate(WriteLen);
+        if (DBG) Log.d(TAG, "notifyModemStatus: status: " + status);
+
+        if (mDundSocket != null) {
+            if ( mDundSocket.isConnected())
+                try {
+                    mDundOutputStream = mDundSocket.getOutputStream();
+                } catch (IOException ex) {
+                    if (VERBOSE) Log.v(TAG, "mDundOutputStream exception: " + ex.toString());
+                }
+            else return false;
+        }
+        else return false;
+
+        IpcMsgBuffer.put(DUN_IPC_MSG_OFF_MSG_TYPE, DUN_IPC_MSG_MDM_STATUS);
+        IpcMsgBuffer.putShort(DUN_IPC_MSG_OFF_MSG_LEN,DUN_IPC_MDM_STATUS_MSG_SIZE);
+        IpcMsgBuffer.put(DUN_IPC_MSG_OFF_MSG, status);
+        try {
+            mDundOutputStream.write(IpcMsgBuffer.array(), 0, WriteLen);
+        } catch (IOException ex) {
+            if (VERBOSE) Log.v(TAG, "mDundOutputStream wrtie exception: " + ex.toString());
+        }
+        return true;
+    }
+
+    int getConnectionState(BluetoothDevice device) {
+        BluetoothDunDevice dunDevice = mDunDevices.get(device);
+        if (dunDevice == null) {
+            return BluetoothDun.STATE_DISCONNECTED;
+        }
+        return dunDevice.mState;
+    }
+
+    public void notifyProfileConnectionStateChanged(BluetoothDevice device,
+            int profileId, int newState, int prevState) {
+        if (mAdapterService != null) {
+            try {
+                mAdapterService.sendConnectionStateChange(device, profileId, newState, prevState);
+            }catch (RemoteException re) {
+                Log.e(TAG, "",re);
+            }
+        }
+    }
+
+    private final void handleDunDeviceStateChange(BluetoothDevice device, int state) {
+        if (DBG) Log.d(TAG, "handleDunDeviceStateChange: device: " + device + " state: " + state);
+        int prevState;
+        BluetoothDunDevice dunDevice = mDunDevices.get(device);
+        if (dunDevice == null) {
+            prevState = BluetoothProfile.STATE_DISCONNECTED;
+        } else {
+            prevState = dunDevice.mState;
+        }
+        Log.d(TAG, "handleDunDeviceStateChange preState: " + prevState + " state: " + state);
+        if (prevState == state) return;
+
+        if (dunDevice == null) {
+            dunDevice = new BluetoothDunDevice(state);
+            mDunDevices.put(device, dunDevice);
+        } else {
+            dunDevice.mState = state;
+        }
+
+        /* Notifying the connection state change of the profile before sending
+           the intent for connection state change, as it was causing a race
+           condition, with the UI not being updated with the correct connection
+           state. */
+        Log.d(TAG, "Dun Device state : device: " + device + " State:" +
+                       prevState + "->" + state);
+        notifyProfileConnectionStateChanged(device, BluetoothProfile.DUN, state, prevState);
+        Intent intent = new Intent(BluetoothDun.ACTION_CONNECTION_STATE_CHANGED);
+        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+        intent.putExtra(BluetoothDun.EXTRA_PREVIOUS_STATE, prevState);
+        intent.putExtra(BluetoothDun.EXTRA_STATE, state);
+        sendBroadcast(intent, BLUETOOTH_PERM);
+
+    }
+
+    private final void handleModemStatusChange(byte status) {
+        byte mdmBits = 0;
+        int WriteLen = DUN_IPC_MDM_STATUS_MSG_SIZE;
+        ByteBuffer IpcMsgBuffer = ByteBuffer.allocate(WriteLen);
+
+        if (DBG) Log.d(TAG, "handleModemStatusChange  status: " + status);
+
+        if ((mRfcommSocket == null) || (!mRfcommSocket.isConnected())) {
+            return;
+        }
+        if(mRmtMdmStatus != status) {
+            mdmBits = (byte)((~(int)mRmtMdmStatus) & ((int)mRmtMdmStatus ^ (int)status));
+            if (DBG) Log.d(TAG, "handleModemStatusChange  mdmBits " + mdmBits);
+            if(mdmBits > 0) {
+                IpcMsgBuffer.put(0, mdmBits);
+                try {
+                    mRfcommSocket.setSocketOpt(BTSOCK_OPT_SET_MODEM_BITS, IpcMsgBuffer.array(), WriteLen);
+                } catch (IOException ex) {
+                    if (VERBOSE) Log.v(TAG, "getSocketOpt Exception: " + ex.toString());
+                }
+            }
+            mdmBits = (byte)(((int)mRmtMdmStatus) & ((int)mRmtMdmStatus ^ (int)status));
+            if (DBG) Log.d(TAG, "handleModemStatusChange  mdmBits " + mdmBits);
+            if(mdmBits > 0) {
+                IpcMsgBuffer.put(0, mdmBits);
+                try {
+                    mRfcommSocket.setSocketOpt(BTSOCK_OPT_CLR_MODEM_BITS, IpcMsgBuffer.array(), WriteLen);
+                } catch (IOException ex) {
+                    if (VERBOSE) Log.v(TAG, "getSocketOpt Exception: " + ex.toString());
+                }
+            }
+            mRmtMdmStatus = status;
+        }
+    }
+
+    List<BluetoothDevice> getConnectedDevices() {
+        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        List<BluetoothDevice> devices = getDevicesMatchingConnectionStates(
+                new int[] {BluetoothProfile.STATE_CONNECTED});
+        return devices;
+    }
+
+    List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+         enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+        List<BluetoothDevice> dunDevices = new ArrayList<BluetoothDevice>();
+
+        for (BluetoothDevice device: mDunDevices.keySet()) {
+            int dunDeviceState = getConnectionState(device);
+            for (int state : states) {
+                if (state == dunDeviceState) {
+                    dunDevices.add(device);
+                    break;
+                }
+            }
+        }
+        return dunDevices;
+    }
+
+    private ServiceConnection mConnection = new ServiceConnection() {
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            mAdapterService = IBluetooth.Stub.asInterface(service);
+        }
+
+        public void onServiceDisconnected(ComponentName className) {
+            mAdapterService = null;
+        }
+    };
+
+    /**
+     * Handlers for incoming service calls
+     */
+    private static class BluetoothDunBinder extends IBluetoothDun.Stub {
+
+        private BluetoothDunService mService;
+
+        public BluetoothDunBinder(BluetoothDunService svc) {
+            mService = svc;
+        }
+
+        private BluetoothDunService getService() {
+            if (mService != null)
+                return mService;
+            return null;
+        }
+
+        public boolean disconnect(BluetoothDevice device) {
+            BluetoothDunService service = getService();
+            if (service == null) return false;
+            return service.disconnect(device);
+        }
+
+        public int getConnectionState(BluetoothDevice device) {
+            BluetoothDunService service = getService();
+            if (service == null) return BluetoothDun.STATE_DISCONNECTED;
+            return service.getConnectionState(device);
+        }
+        public List<BluetoothDevice> getConnectedDevices() {
+            BluetoothDunService service = getService();
+            if (service == null) return new ArrayList<BluetoothDevice>(0);
+            return service.getConnectedDevices();
+        }
+
+        public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+            BluetoothDunService service = getService();
+            if (service == null) return new ArrayList<BluetoothDevice>(0);
+            return service.getDevicesMatchingConnectionStates(states);
+        }
+    };
+
+    private class BluetoothDunDevice {
+        private int mState;
+
+        BluetoothDunDevice(int state) {
+            mState = state;
+        }
+    }
+}
diff --git a/src/org/codeaurora/bluetooth/ftp/BluetoothFtpActivity.java b/src/org/codeaurora/bluetooth/ftp/BluetoothFtpActivity.java
index a4ad2f8..57c7591 100644
--- a/src/org/codeaurora/bluetooth/ftp/BluetoothFtpActivity.java
+++ b/src/org/codeaurora/bluetooth/ftp/BluetoothFtpActivity.java
@@ -101,7 +101,7 @@
             if (!BluetoothFtpService.USER_CONFIRM_TIMEOUT_ACTION.equals(intent.getAction())) {
                 return;
             }
-            onTimeout();
+            finish();
         }
     };
 
