summary refs log tree commit diff
path: root/src/devices/bluetooth
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2015-01-22 00:29:39 +0100
committerMichael Biebl <biebl@debian.org>2015-01-22 00:29:39 +0100
commit2c032d8f1c6292c1338a615e6ec40252889ba85c (patch)
tree1f77182220b2b0264288ba4a476ab47e5bc48716 /src/devices/bluetooth
parent33491bc4279481db8ae47213e34a6d695a0e8830 (diff)
Imported Upstream version 1.0.0 upstream/1.0.0
Diffstat (limited to 'src/devices/bluetooth')
-rw-r--r--src/devices/bluetooth/Makefile.am26
-rw-r--r--src/devices/bluetooth/Makefile.in92
-rw-r--r--src/devices/bluetooth/exports.ver1
-rw-r--r--src/devices/bluetooth/nm-bluez-common.h4
-rw-r--r--src/devices/bluetooth/nm-bluez-device.c285
-rw-r--r--src/devices/bluetooth/nm-bluez-device.h11
-rw-r--r--src/devices/bluetooth/nm-bluez-manager.c35
-rw-r--r--src/devices/bluetooth/nm-bluez-manager.h6
-rw-r--r--src/devices/bluetooth/nm-bluez4-adapter.c20
-rw-r--r--src/devices/bluetooth/nm-bluez4-adapter.h6
-rw-r--r--src/devices/bluetooth/nm-bluez4-manager.c2
-rw-r--r--src/devices/bluetooth/nm-bluez4-manager.h6
-rw-r--r--src/devices/bluetooth/nm-bluez5-dun.c410
-rw-r--r--src/devices/bluetooth/nm-bluez5-dun.h46
-rw-r--r--src/devices/bluetooth/nm-bluez5-manager.c4
-rw-r--r--src/devices/bluetooth/nm-bluez5-manager.h6
-rw-r--r--src/devices/bluetooth/nm-bt-enum-types.c3
-rw-r--r--src/devices/bluetooth/nm-bt-error.c35
-rw-r--r--src/devices/bluetooth/nm-bt-error.h35
-rw-r--r--src/devices/bluetooth/nm-device-bt.c262
-rw-r--r--src/devices/bluetooth/nm-device-bt.h12
21 files changed, 930 insertions, 377 deletions
diff --git a/src/devices/bluetooth/Makefile.am b/src/devices/bluetooth/Makefile.am
index 639a1ad7..8ab561ac 100644
--- a/src/devices/bluetooth/Makefile.am
+++ b/src/devices/bluetooth/Makefile.am
@@ -5,26 +5,22 @@ include $(GLIB_MAKEFILE)
 AM_CPPFLAGS = \
 	-I${top_srcdir}/src \
 	-I${top_builddir}/src \
-	-I${top_srcdir}/src/logging \
 	-I${top_srcdir}/src/devices \
 	-I${top_srcdir}/src/settings \
 	-I${top_srcdir}/src/platform \
 	-I${top_srcdir}/src/devices/wwan \
-	-I${top_builddir}/include \
 	-I${top_srcdir}/include \
-	-I${top_builddir}/libnm-util \
-	-I${top_srcdir}/libnm-util \
+	-I${top_builddir}/libnm-core \
+	-I${top_srcdir}/libnm-core \
 	-DG_LOG_DOMAIN=\""NetworkManager-bluetooth"\" \
+	-DNETWORKMANAGER_COMPILATION \
 	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
-	$(DBUS_CFLAGS) \
-	$(POLKIT_CFLAGS) \
-	$(LIBNL_CFLAGS) \
-	$(GUDEV_CFLAGS)
+	$(DBUS_CFLAGS)
 
 GLIB_GENERATED = nm-bt-enum-types.h nm-bt-enum-types.c
 GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM
 GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM
-nm_bt_enum_types_sources = $(srcdir)/nm-device-bt.h
+nm_bt_enum_types_sources = $(srcdir)/nm-bt-error.h
 
 nm-device-bt-glue.h: $(top_srcdir)/introspection/nm-device-bt.xml
 	dbus-binding-tool --prefix=nm_device_bt --mode=glib-server --output=$@ $<
@@ -47,6 +43,8 @@ libnm_device_plugin_bluetooth_la_SOURCES = \
 	nm-bluez4-manager.h \
 	nm-bluez5-manager.c \
 	nm-bluez5-manager.h \
+	nm-bt-error.h \
+	nm-bt-error.c \
 	\
 	nm-device-bt.c \
 	nm-device-bt.h \
@@ -62,6 +60,16 @@ libnm_device_plugin_bluetooth_la_LIBADD = \
 	$(DBUS_LIBS) \
 	$(GUDEV_LIBS)
 
+if WITH_BLUEZ5_DUN
+AM_CPPFLAGS += $(BLUEZ5_CFLAGS)
+
+libnm_device_plugin_bluetooth_la_SOURCES += \
+	nm-bluez5-dun.c \
+	nm-bluez5-dun.h
+
+libnm_device_plugin_bluetooth_la_LIBADD += $(BLUEZ5_LIBS)
+endif
+
 CLEANFILES = $(BUILT_SOURCES)
 EXTRA_DIST = $(SYMBOL_VIS_FILE)
 
diff --git a/src/devices/bluetooth/Makefile.in b/src/devices/bluetooth/Makefile.in
index 3145c52d..0a285fda 100644
--- a/src/devices/bluetooth/Makefile.in
+++ b/src/devices/bluetooth/Makefile.in
@@ -78,6 +78,12 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
+@WITH_BLUEZ5_DUN_TRUE@am__append_1 = $(BLUEZ5_CFLAGS)
+@WITH_BLUEZ5_DUN_TRUE@am__append_2 = \
+@WITH_BLUEZ5_DUN_TRUE@	nm-bluez5-dun.c \
+@WITH_BLUEZ5_DUN_TRUE@	nm-bluez5-dun.h
+
+@WITH_BLUEZ5_DUN_TRUE@am__append_3 = $(BLUEZ5_LIBS)
 subdir = src/devices/bluetooth
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
 	$(top_srcdir)/build-aux/depcomp
@@ -131,14 +137,26 @@ am__uninstall_files_from_dir = { \
 am__installdirs = "$(DESTDIR)$(pkglibdir)"
 LTLIBRARIES = $(pkglib_LTLIBRARIES)
 am__DEPENDENCIES_1 =
+@WITH_BLUEZ5_DUN_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
 libnm_device_plugin_bluetooth_la_DEPENDENCIES =  \
 	$(top_builddir)/src/devices/wwan/libnm-wwan.la \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_2)
+am__libnm_device_plugin_bluetooth_la_SOURCES_DIST =  \
+	nm-bluez-manager.c nm-bluez-manager.h nm-bluez-common.h \
+	nm-bluez-device.c nm-bluez-device.h nm-bluez4-adapter.c \
+	nm-bluez4-adapter.h nm-bluez4-manager.c nm-bluez4-manager.h \
+	nm-bluez5-manager.c nm-bluez5-manager.h nm-bt-error.h \
+	nm-bt-error.c nm-device-bt.c nm-device-bt.h nm-bt-enum-types.h \
+	nm-bt-enum-types.c nm-device-bt-glue.h nm-bluez5-dun.c \
+	nm-bluez5-dun.h
 am__objects_1 = nm-bt-enum-types.lo
 am__objects_2 = $(am__objects_1)
+@WITH_BLUEZ5_DUN_TRUE@am__objects_3 = nm-bluez5-dun.lo
 am_libnm_device_plugin_bluetooth_la_OBJECTS = nm-bluez-manager.lo \
 	nm-bluez-device.lo nm-bluez4-adapter.lo nm-bluez4-manager.lo \
-	nm-bluez5-manager.lo nm-device-bt.lo $(am__objects_2)
+	nm-bluez5-manager.lo nm-bt-error.lo nm-device-bt.lo \
+	$(am__objects_2) $(am__objects_3)
 libnm_device_plugin_bluetooth_la_OBJECTS =  \
 	$(am_libnm_device_plugin_bluetooth_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
@@ -184,7 +202,7 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
 SOURCES = $(libnm_device_plugin_bluetooth_la_SOURCES)
-DIST_SOURCES = $(libnm_device_plugin_bluetooth_la_SOURCES)
+DIST_SOURCES = $(am__libnm_device_plugin_bluetooth_la_SOURCES_DIST)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -219,6 +237,8 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
+BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@
+BLUEZ5_LIBS = @BLUEZ5_LIBS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
@@ -342,6 +362,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@
 NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
+NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
 NM_MICRO_VERSION = @NM_MICRO_VERSION@
 NM_MINOR_VERSION = @NM_MINOR_VERSION@
@@ -361,6 +382,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
 PKG_CONFIG = @PKG_CONFIG@
 PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
 PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
@@ -387,7 +409,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@
 SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@
 SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
-UDEV_BASE_DIR = @UDEV_BASE_DIR@
+UDEV_DIR = @UDEV_DIR@
 USE_NLS = @USE_NLS@
 UUID_CFLAGS = @UUID_CFLAGS@
 UUID_LIBS = @UUID_LIBS@
@@ -466,59 +488,35 @@ with_dhcpcd = @with_dhcpcd@
 with_netconfig = @with_netconfig@
 with_resolvconf = @with_resolvconf@
 with_valgrind = @with_valgrind@
-AM_CPPFLAGS = \
-	-I${top_srcdir}/src \
-	-I${top_builddir}/src \
-	-I${top_srcdir}/src/logging \
-	-I${top_srcdir}/src/devices \
-	-I${top_srcdir}/src/settings \
-	-I${top_srcdir}/src/platform \
-	-I${top_srcdir}/src/devices/wwan \
-	-I${top_builddir}/include \
-	-I${top_srcdir}/include \
-	-I${top_builddir}/libnm-util \
-	-I${top_srcdir}/libnm-util \
+AM_CPPFLAGS = -I${top_srcdir}/src -I${top_builddir}/src \
+	-I${top_srcdir}/src/devices -I${top_srcdir}/src/settings \
+	-I${top_srcdir}/src/platform -I${top_srcdir}/src/devices/wwan \
+	-I${top_srcdir}/include -I${top_builddir}/libnm-core \
+	-I${top_srcdir}/libnm-core \
 	-DG_LOG_DOMAIN=\""NetworkManager-bluetooth"\" \
-	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
-	$(DBUS_CFLAGS) \
-	$(POLKIT_CFLAGS) \
-	$(LIBNL_CFLAGS) \
-	$(GUDEV_CFLAGS)
-
+	-DNETWORKMANAGER_COMPILATION \
+	-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE $(DBUS_CFLAGS) \
+	$(am__append_1)
 GLIB_GENERATED = nm-bt-enum-types.h nm-bt-enum-types.c
 GLIB_MKENUMS_H_FLAGS = --identifier-prefix NM
 GLIB_MKENUMS_C_FLAGS = --identifier-prefix NM
-nm_bt_enum_types_sources = $(srcdir)/nm-device-bt.h
+nm_bt_enum_types_sources = $(srcdir)/nm-bt-error.h
 BUILT_SOURCES = $(GLIB_GENERATED) nm-device-bt-glue.h
 pkglib_LTLIBRARIES = libnm-device-plugin-bluetooth.la
 SYMBOL_VIS_FILE = $(srcdir)/exports.ver
-libnm_device_plugin_bluetooth_la_SOURCES = \
-	nm-bluez-manager.c \
-	nm-bluez-manager.h \
-	nm-bluez-common.h \
-	nm-bluez-device.c \
-	nm-bluez-device.h \
-	nm-bluez4-adapter.c \
-	nm-bluez4-adapter.h \
-	nm-bluez4-manager.c \
-	nm-bluez4-manager.h \
-	nm-bluez5-manager.c \
-	nm-bluez5-manager.h \
-	\
-	nm-device-bt.c \
-	nm-device-bt.h \
-	\
-	$(BUILT_SOURCES)
-
+libnm_device_plugin_bluetooth_la_SOURCES = nm-bluez-manager.c \
+	nm-bluez-manager.h nm-bluez-common.h nm-bluez-device.c \
+	nm-bluez-device.h nm-bluez4-adapter.c nm-bluez4-adapter.h \
+	nm-bluez4-manager.c nm-bluez4-manager.h nm-bluez5-manager.c \
+	nm-bluez5-manager.h nm-bt-error.h nm-bt-error.c nm-device-bt.c \
+	nm-device-bt.h $(BUILT_SOURCES) $(am__append_2)
 libnm_device_plugin_bluetooth_la_LDFLAGS = \
 	-module -avoid-version \
 	-Wl,--version-script=$(SYMBOL_VIS_FILE)
 
-libnm_device_plugin_bluetooth_la_LIBADD = \
-	$(top_builddir)/src/devices/wwan/libnm-wwan.la \
-	$(DBUS_LIBS) \
-	$(GUDEV_LIBS)
-
+libnm_device_plugin_bluetooth_la_LIBADD =  \
+	$(top_builddir)/src/devices/wwan/libnm-wwan.la $(DBUS_LIBS) \
+	$(GUDEV_LIBS) $(am__append_3)
 CLEANFILES = $(BUILT_SOURCES)
 EXTRA_DIST = $(SYMBOL_VIS_FILE)
 all: $(BUILT_SOURCES)
@@ -605,8 +603,10 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez-manager.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez4-adapter.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez4-manager.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez5-dun.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bluez5-manager.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bt-enum-types.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-bt-error.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nm-device-bt.Plo@am__quote@
 
 .c.o:
diff --git a/src/devices/bluetooth/exports.ver b/src/devices/bluetooth/exports.ver
index d2c45124..24cd848c 100644
--- a/src/devices/bluetooth/exports.ver
+++ b/src/devices/bluetooth/exports.ver
@@ -1,7 +1,6 @@
 {
 global:
 	nm_device_factory_create;
-	nm_device_factory_get_device_type;
 local:
 	*;
 };
diff --git a/src/devices/bluetooth/nm-bluez-common.h b/src/devices/bluetooth/nm-bluez-common.h
index f80cfc2e..f0cab43b 100644
--- a/src/devices/bluetooth/nm-bluez-common.h
+++ b/src/devices/bluetooth/nm-bluez-common.h
@@ -18,8 +18,8 @@
  * Copyright (C) 2009 Red Hat, Inc.
  */
 
-#ifndef NM_BLUEZ_COMMON_H
-#define NM_BLUEZ_COMMON_H
+#ifndef __NETWORKMANAGER_BLUEZ_COMMON_H__
+#define __NETWORKMANAGER_BLUEZ_COMMON_H__
 
 #include <config.h>
 
diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c
index 4c448a37..fe1a97bb 100644
--- a/src/devices/bluetooth/nm-bluez-device.c
+++ b/src/devices/bluetooth/nm-bluez-device.c
@@ -19,22 +19,24 @@
  * Copyright (C) 2013 Intel Corporation.
  */
 
+#include "config.h"
+
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <gio/gio.h>
 #include <string.h>
-#include <net/ethernet.h>
-#include <netinet/ether.h>
 
-#include "NetworkManager.h"
-#include "nm-setting-bluetooth.h"
+#include "nm-core-internal.h"
 
 #include "nm-bluez-common.h"
 #include "nm-bluez-device.h"
 #include "nm-logging.h"
-#include "nm-utils.h"
 #include "nm-settings-connection.h"
+#include "NetworkManagerUtils.h"
 
+#if WITH_BLUEZ5_DUN
+#include "nm-bluez5-dun.h"
+#endif
 
 G_DEFINE_TYPE (NMBluezDevice, nm_bluez_device, G_TYPE_OBJECT)
 
@@ -55,19 +57,21 @@ typedef struct {
 	gboolean usable;
 	NMBluetoothCapabilities connection_bt_type;
 
+	char *adapter_address;
 	char *address;
-	guint8 bin_address[ETH_ALEN];
 	char *name;
 	guint32 capabilities;
 	gboolean connected;
 
-	char *bt_iface;
+	char *b4_iface;
+#if WITH_BLUEZ5_DUN
+	NMBluez5DunContext *b5_dun_context;
+#endif
 
 	NMConnectionProvider *provider;
 	GSList *connections;
 
 	NMConnection *pan_connection;
-	NMConnection *pan_connection_original;
 	gboolean pan_connection_no_autocreate;
 } NMBluezDevicePrivate;
 
@@ -156,9 +160,12 @@ nm_bluez_device_get_capabilities (NMBluezDevice *self)
 gboolean
 nm_bluez_device_get_connected (NMBluezDevice *self)
 {
+	NMBluezDevicePrivate *priv;
+
 	g_return_val_if_fail (NM_IS_BLUEZ_DEVICE (self), FALSE);
 
-	return NM_BLUEZ_DEVICE_GET_PRIVATE (self)->connected;
+	priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
+	return priv->connected;
 }
 
 static void
@@ -168,7 +175,6 @@ pan_connection_check_create (NMBluezDevice *self)
 	NMConnection *added;
 	NMSetting *setting;
 	char *uuid, *id;
-	GByteArray *bdaddr_array;
 	GError *error = NULL;
 	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
 
@@ -187,7 +193,7 @@ pan_connection_check_create (NMBluezDevice *self)
 
 	/* create a new connection */
 
-	connection = nm_connection_new ();
+	connection = nm_simple_connection_new ();
 
 	/* Setting: Connection */
 	uuid = nm_utils_uuid_generate ();
@@ -202,29 +208,26 @@ pan_connection_check_create (NMBluezDevice *self)
 	nm_connection_add_setting (connection, setting);
 
 	/* Setting: Bluetooth */
-	bdaddr_array = g_byte_array_sized_new (sizeof (priv->bin_address));
-	g_byte_array_append (bdaddr_array, priv->bin_address, sizeof (priv->bin_address));
 	setting = nm_setting_bluetooth_new ();
 	g_object_set (G_OBJECT (setting),
-	              NM_SETTING_BLUETOOTH_BDADDR, bdaddr_array,
+	              NM_SETTING_BLUETOOTH_BDADDR, priv->address,
 	              NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
 	              NULL);
 	nm_connection_add_setting (connection, setting);
-	g_byte_array_free (bdaddr_array, TRUE);
 
 	/* Setting: IPv4 */
 	setting = nm_setting_ip4_config_new ();
 	g_object_set (G_OBJECT (setting),
-	              NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
-	              NM_SETTING_IP4_CONFIG_MAY_FAIL, FALSE,
+	              NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
+	              NM_SETTING_IP_CONFIG_MAY_FAIL, FALSE,
 	              NULL);
 	nm_connection_add_setting (connection, setting);
 
 	/* Setting: IPv6 */
 	setting = nm_setting_ip6_config_new ();
 	g_object_set (G_OBJECT (setting),
-	              NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
-	              NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE,
+	              NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO,
+	              NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE,
 	              NULL);
 	nm_connection_add_setting (connection, setting);
 
@@ -240,9 +243,10 @@ pan_connection_check_create (NMBluezDevice *self)
 		g_assert (connection_compatible (self, added));
 		g_assert (nm_connection_compare (added, connection, NM_SETTING_COMPARE_FLAG_EXACT));
 
+		nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED, TRUE);
+
 		priv->connections = g_slist_prepend (priv->connections, g_object_ref (added));
 		priv->pan_connection = added;
-		priv->pan_connection_original = connection;
 		nm_log_dbg (LOGD_BT, "bluez[%s] added new Bluetooth connection for NAP device: '%s' (%s)", priv->path, id, uuid);
 	} else {
 		nm_log_warn (LOGD_BT, "bluez[%s] couldn't add new Bluetooth connection for NAP device: '%s' (%s): %d / %s",
@@ -250,8 +254,8 @@ pan_connection_check_create (NMBluezDevice *self)
 		             (error && error->message) ? error->message : "(unknown)");
 		g_clear_error (&error);
 
-		g_object_unref (connection);
 	}
+	g_object_unref (connection);
 
 	g_free (id);
 	g_free (uuid);
@@ -264,13 +268,12 @@ check_emit_usable (NMBluezDevice *self)
 	gboolean new_usable;
 
 	/* only expect the supported capabilities set. */
-	g_assert (priv->bluez_version != 4 || ((priv->capabilities & ~(NM_BT_CAPABILITY_NAP | NM_BT_CAPABILITY_DUN)) == NM_BT_CAPABILITY_NONE ));
-	g_assert (priv->bluez_version != 5 || ((priv->capabilities & ~(NM_BT_CAPABILITY_NAP                       )) == NM_BT_CAPABILITY_NONE ));
+	g_assert ((priv->capabilities & ~(NM_BT_CAPABILITY_NAP | NM_BT_CAPABILITY_DUN)) == NM_BT_CAPABILITY_NONE );
 
 	new_usable = (priv->initialized && priv->capabilities && priv->name &&
 	              ((priv->bluez_version == 4) ||
 	               (priv->bluez_version == 5 && priv->adapter5 && priv->adapter_powered) ) &&
-	              priv->dbus_connection && priv->address);
+	              priv->dbus_connection && priv->address && priv->adapter_address);
 
 	if (!new_usable)
 		goto END;
@@ -302,7 +305,7 @@ connection_compatible (NMBluezDevice *self, NMConnection *connection)
 	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
 	NMSettingBluetooth *s_bt;
 	const char *bt_type;
-	const GByteArray *bdaddr;
+	const char *bdaddr;
 
 	if (!nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME))
 		return FALSE;
@@ -311,14 +314,13 @@ connection_compatible (NMBluezDevice *self, NMConnection *connection)
 	if (!s_bt)
 		return FALSE;
 
-	if (!priv->address) {
-		/* unless address is set, bin_address is not initialized. */
+	if (!priv->address)
 		return FALSE;
-	}
+
 	bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt);
-	if (!bdaddr || bdaddr->len != ETH_ALEN)
+	if (!bdaddr)
 		return FALSE;
-	if (memcmp (bdaddr->data, priv->bin_address, ETH_ALEN) != 0)
+	if (!nm_utils_hwaddr_matches (bdaddr, -1, priv->address, -1))
 		return FALSE;
 
 	bt_type = nm_setting_bluetooth_get_connection_type (s_bt);
@@ -362,10 +364,8 @@ cp_connection_removed (NMConnectionProvider *provider,
 
 	if (g_slist_find (priv->connections, connection)) {
 		priv->connections = g_slist_remove (priv->connections, connection);
-		if (priv->pan_connection == connection) {
+		if (priv->pan_connection == connection)
 			priv->pan_connection = NULL;
-			g_clear_object (&priv->pan_connection_original);
-		}
 		g_object_unref (connection);
 		check_emit_usable (self);
 	}
@@ -420,26 +420,37 @@ nm_bluez_device_disconnect (NMBluezDevice *self)
 {
 	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
 	GVariant *args = NULL;
-	const char *dbus_iface;
+	const char *dbus_iface = NULL;
 
 	g_return_if_fail (priv->dbus_connection);
 
-	if (priv->bluez_version == 5) {
-		g_return_if_fail (priv->connection_bt_type == NM_BT_CAPABILITY_NAP);
-		dbus_iface = BLUEZ5_NETWORK_INTERFACE;
-	} else if (priv->bluez_version == 4 && priv->connection_bt_type == NM_BT_CAPABILITY_DUN) {
-		/* Can't pass a NULL interface name through dbus to bluez, so just
-		 * ignore the disconnect if the interface isn't known.
-		 */
-		if (!priv->bt_iface)
-			return;
-
-		args = g_variant_new ("(s)", priv->bt_iface),
-		dbus_iface = BLUEZ4_SERIAL_INTERFACE;
-	} else {
-		g_return_if_fail (priv->bluez_version == 4 && priv->connection_bt_type == NM_BT_CAPABILITY_NAP);
-		dbus_iface = BLUEZ4_NETWORK_INTERFACE;
-	}
+	if (priv->connection_bt_type == NM_BT_CAPABILITY_DUN) {
+		if (priv->bluez_version == 4) {
+			/* Can't pass a NULL interface name through dbus to bluez, so just
+			 * ignore the disconnect if the interface isn't known.
+			 */
+			if (!priv->b4_iface)
+				goto out;
+			args = g_variant_new ("(s)", priv->b4_iface),
+			dbus_iface = BLUEZ4_SERIAL_INTERFACE;
+		} else if (priv->bluez_version == 5) {
+#if WITH_BLUEZ5_DUN
+			nm_bluez5_dun_cleanup (priv->b5_dun_context);
+#else
+			g_assert_not_reached ();
+#endif
+			priv->connected = FALSE;
+			goto out;
+		}
+	} else if (priv->connection_bt_type == NM_BT_CAPABILITY_NAP) {
+		if (priv->bluez_version == 4)
+			dbus_iface = BLUEZ4_NETWORK_INTERFACE;
+		else if (priv->bluez_version == 5)
+			dbus_iface = BLUEZ5_NETWORK_INTERFACE;
+		else
+			g_assert_not_reached ();
+	} else
+		g_assert_not_reached ();
 
 	g_dbus_connection_call (priv->dbus_connection,
 	                        BLUEZ_SERVICE,
@@ -454,6 +465,8 @@ nm_bluez_device_disconnect (NMBluezDevice *self)
 	                        (GAsyncReadyCallback) bluez_disconnect_cb,
 	                        g_object_ref (self));
 
+out:
+	g_clear_pointer (&priv->b4_iface, g_free);
 	priv->connection_bt_type = NM_BT_CAPABILITY_NONE;
 }
 
@@ -480,7 +493,7 @@ bluez_connect_cb (GDBusConnection *dbus_connection,
 		g_simple_async_result_set_op_res_gpointer (result,
 		                                           g_strdup (device),
 		                                           g_free);
-		priv->bt_iface = device;
+		priv->b4_iface = device;
 		g_variant_unref (variant);
 	}
 
@@ -489,6 +502,28 @@ bluez_connect_cb (GDBusConnection *dbus_connection,
 	g_object_unref (result_object);
 }
 
+#if WITH_BLUEZ5_DUN
+static void
+bluez5_dun_connect_cb (NMBluez5DunContext *context,
+                   const char *device,
+                   GError *error,
+                   gpointer user_data)
+{
+	GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (user_data);
+
+	if (error) {
+		g_simple_async_result_take_error (result, error);
+	} else {
+		g_simple_async_result_set_op_res_gpointer (result,
+		                                           g_strdup (device),
+		                                           g_free);
+	}
+
+	g_simple_async_result_complete (result);
+	g_object_unref (result);
+}
+#endif
+
 void
 nm_bluez_device_connect_async (NMBluezDevice *self,
                                NMBluetoothCapabilities connection_bt_type,
@@ -497,26 +532,39 @@ nm_bluez_device_connect_async (NMBluezDevice *self,
 {
 	GSimpleAsyncResult *simple;
 	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
-	const char *dbus_iface;
-	const char *connect_type = BLUETOOTH_CONNECT_NAP;
+	const char *dbus_iface = NULL;
+	const char *connect_type = NULL;
 
 	g_return_if_fail (priv->capabilities & connection_bt_type & (NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP));
 
-	if (priv->bluez_version == 5) {
-		g_return_if_fail (connection_bt_type == NM_BT_CAPABILITY_NAP);
-		dbus_iface = BLUEZ5_NETWORK_INTERFACE;
-	} else if (priv->bluez_version == 4 && connection_bt_type == NM_BT_CAPABILITY_DUN) {
-		dbus_iface = BLUEZ4_SERIAL_INTERFACE;
-		connect_type = BLUETOOTH_CONNECT_DUN;
-	} else {
-		g_return_if_fail (priv->bluez_version == 4 && connection_bt_type == NM_BT_CAPABILITY_NAP);
-		dbus_iface = BLUEZ4_NETWORK_INTERFACE;
-	}
-
 	simple = g_simple_async_result_new (G_OBJECT (self),
 	                                    callback,
 	                                    user_data,
 	                                    nm_bluez_device_connect_async);
+	priv->connection_bt_type = connection_bt_type;
+
+	if (connection_bt_type == NM_BT_CAPABILITY_NAP) {
+		connect_type = BLUETOOTH_CONNECT_NAP;
+		if (priv->bluez_version == 4)
+			dbus_iface = BLUEZ4_NETWORK_INTERFACE;
+		else if (priv->bluez_version == 5)
+			dbus_iface = BLUEZ5_NETWORK_INTERFACE;
+	} else if (connection_bt_type == NM_BT_CAPABILITY_DUN) {
+		connect_type = BLUETOOTH_CONNECT_DUN;
+		if (priv->bluez_version == 4)
+			dbus_iface = BLUEZ4_SERIAL_INTERFACE;
+		else if (priv->bluez_version == 5) {
+#if WITH_BLUEZ5_DUN
+			if (priv->b5_dun_context == NULL)
+				priv->b5_dun_context = nm_bluez5_dun_new (priv->adapter_address, priv->address);
+			nm_bluez5_dun_connect (priv->b5_dun_context, bluez5_dun_connect_cb, simple);
+#else
+			g_assert_not_reached ();
+#endif
+			return;
+		}
+	} else
+		g_assert_not_reached ();
 
 	g_dbus_connection_call (priv->dbus_connection,
 	                        BLUEZ_SERVICE,
@@ -530,8 +578,6 @@ nm_bluez_device_connect_async (NMBluezDevice *self,
 	                        NULL,
 	                        (GAsyncReadyCallback) bluez_connect_cb,
 	                        simple);
-
-	priv->connection_bt_type = connection_bt_type;
 }
 
 const char *
@@ -539,6 +585,7 @@ nm_bluez_device_connect_finish (NMBluezDevice *self,
                                 GAsyncResult *result,
                                 GError **error)
 {
+	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
 	GSimpleAsyncResult *simple;
 	const char *device;
 
@@ -553,13 +600,28 @@ nm_bluez_device_connect_finish (NMBluezDevice *self,
 		return NULL;
 
 	device = (const char *) g_simple_async_result_get_op_res_gpointer (simple);
+	if (device && priv->bluez_version == 5)
+		priv->connected = TRUE;
+
 	return device;
 }
 
 /***********************************************************/
 
+static void
+set_adapter_address (NMBluezDevice *self, const char *address)
+{
+	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
+
+	g_return_if_fail (address);
+
+	if (priv->adapter_address)
+		g_free (priv->adapter_address);
+	priv->adapter_address = g_strdup (address);
+}
+
 static guint32
-convert_uuids_to_capabilities (const char **strings, int bluez_version)
+convert_uuids_to_capabilities (const char **strings)
 {
 	const char **iter;
 	guint32 capabilities = 0;
@@ -571,8 +633,7 @@ convert_uuids_to_capabilities (const char **strings, int bluez_version)
 		if (parts && parts[0]) {
 			switch (g_ascii_strtoull (parts[0], NULL, 16)) {
 			case 0x1103:
-				if (bluez_version == 4)
-					capabilities |= NM_BT_CAPABILITY_DUN;
+				capabilities |= NM_BT_CAPABILITY_DUN;
 				break;
 			case 0x1116:
 				capabilities |= NM_BT_CAPABILITY_NAP;
@@ -593,7 +654,7 @@ _set_property_capabilities (NMBluezDevice *self, const char **uuids)
 	guint32 uint_val;
 	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
 
-	uint_val = convert_uuids_to_capabilities (uuids, priv->bluez_version);
+	uint_val = convert_uuids_to_capabilities (uuids);
 	if (priv->capabilities != uint_val) {
 		if (priv->capabilities) {
 			/* changing (relevant) capabilities is not supported and ignored -- except setting initially */
@@ -613,13 +674,10 @@ _set_property_capabilities (NMBluezDevice *self, const char **uuids)
 /**
  * priv->address can only be set one to a certain (non NULL) value. Every later attempt
  * to reset it to another value will be ignored and a warning will be logged.
- *
- * When setting the address for the first time, we also set bin_address.
  **/
 static void
 _set_property_address (NMBluezDevice *self, const char *addr)
 {
-	struct ether_addr *tmp;
 	NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
 
 	if (g_strcmp0 (priv->address, addr) == 0)
@@ -635,15 +693,11 @@ _set_property_address (NMBluezDevice *self, const char *addr)
 		return;
 	}
 
-	tmp = ether_aton (addr);
-	if (!tmp) {
-		if (priv->address)
-			nm_log_warn (LOGD_BT, "bluez[%s] cannot reset address from '%s' to '%s' (invalid value)", priv->path, priv->address, addr);
-		else
-			nm_log_warn (LOGD_BT, "bluez[%s] cannot reset address from NULL to '%s' (invalid value)", priv->path, addr);
+	if (!nm_utils_hwaddr_valid (addr, ETH_ALEN)) {
+		nm_log_warn (LOGD_BT, "bluez[%s] cannot set address to '%s' (invalid value)", priv->path, addr);
 		return;
 	}
-	memcpy (priv->bin_address, tmp->ether_addr_octet, ETH_ALEN);
+
 	priv->address = g_strdup (addr);
 	g_object_notify (G_OBJECT (self), NM_BLUEZ_DEVICE_ADDRESS);
 }
@@ -752,6 +806,10 @@ adapter5_on_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self)
 		if (v)
 			g_variant_unref (v);
 
+		v = g_dbus_proxy_get_cached_property (priv->adapter5, "Address");
+		if (VARIANT_IS_OF_TYPE_STRING (v))
+			set_adapter_address (self, g_variant_get_string (v, NULL));
+
 		priv->initialized = TRUE;
 		g_signal_emit (self, signals[INITIALIZED], 0, TRUE);
 
@@ -957,7 +1015,10 @@ on_bus_acquired (GObject *object, GAsyncResult *res, NMBluezDevice *self)
 /********************************************************************/
 
 NMBluezDevice *
-nm_bluez_device_new (const char *path, NMConnectionProvider *provider, int bluez_version)
+nm_bluez_device_new (const char *path,
+                     const char *adapter_address,
+                     NMConnectionProvider *provider,
+                     int bluez_version)
 {
 	NMBluezDevice *self;
 	NMBluezDevicePrivate *priv;
@@ -978,8 +1039,10 @@ nm_bluez_device_new (const char *path, NMConnectionProvider *provider, int bluez
 	priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self);
 
 	priv->bluez_version = bluez_version;
-
 	priv->provider = provider;
+	g_return_val_if_fail (bluez_version == 5 || (bluez_version == 4 && adapter_address), NULL);
+	if (adapter_address)
+		set_adapter_address (self, adapter_address);
 
 	g_signal_connect (priv->provider,
 	                  NM_CP_SIGNAL_CONNECTION_ADDED,
@@ -1037,14 +1100,19 @@ dispose (GObject *object)
 	if (priv->pan_connection) {
 		/* Check whether we want to remove the created connection. If so, we take a reference
 		 * and delete it at the end of dispose(). */
-		if (   nm_settings_connection_get_unsaved (NM_SETTINGS_CONNECTION (priv->pan_connection))
-		    && nm_connection_compare (priv->pan_connection, priv->pan_connection_original, NM_SETTING_COMPARE_FLAG_EXACT))
+		if (nm_settings_connection_get_nm_generated (NM_SETTINGS_CONNECTION (priv->pan_connection)))
 			to_delete = g_object_ref (priv->pan_connection);
 
 		priv->pan_connection = NULL;
-		g_clear_object (&priv->pan_connection_original);
 	}
 
+#if WITH_BLUEZ5_DUN
+	if (priv->b5_dun_context) {
+		nm_bluez5_dun_free (priv->b5_dun_context);
+		priv->b5_dun_context = NULL;
+	}
+#endif
+
 	g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_added, self);
 	g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_removed, self);
 	g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_updated, self);
@@ -1073,9 +1141,10 @@ finalize (GObject *object)
 	nm_log_dbg (LOGD_BT, "bluez[%s]: finalize NMBluezDevice", priv->path);
 
 	g_free (priv->path);
+	g_free (priv->adapter_address);
 	g_free (priv->address);
 	g_free (priv->name);
-	g_free (priv->bt_iface);
+	g_free (priv->b4_iface);
 
 	if (priv->proxy)
 		g_signal_handlers_disconnect_by_data (priv->proxy, object);
@@ -1148,51 +1217,45 @@ nm_bluez_device_class_init (NMBluezDeviceClass *config_class)
 	/* Properties */
 	g_object_class_install_property
 		(object_class, PROP_PATH,
-		 g_param_spec_string (NM_BLUEZ_DEVICE_PATH,
-		                      "DBus Path",
-		                      "DBus Path",
+		 g_param_spec_string (NM_BLUEZ_DEVICE_PATH, "", "",
 		                      NULL,
-		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+		                      G_PARAM_STATIC_STRINGS));
 
 	g_object_class_install_property
 		(object_class, PROP_ADDRESS,
-		 g_param_spec_string (NM_BLUEZ_DEVICE_ADDRESS,
-		                      "Address",
-		                      "Address",
+		 g_param_spec_string (NM_BLUEZ_DEVICE_ADDRESS, "", "",
 		                      NULL,
-		                      G_PARAM_READABLE));
+		                      G_PARAM_READABLE |
+		                      G_PARAM_STATIC_STRINGS));
 
 	g_object_class_install_property
 		(object_class, PROP_NAME,
-		 g_param_spec_string (NM_BLUEZ_DEVICE_NAME,
-		                      "Name",
-		                      "Name",
+		 g_param_spec_string (NM_BLUEZ_DEVICE_NAME, "", "",
 		                      NULL,
-		                      G_PARAM_READABLE));
+		                      G_PARAM_READABLE |
+		                      G_PARAM_STATIC_STRINGS));
 
 	g_object_class_install_property
 		(object_class, PROP_CAPABILITIES,
-		 g_param_spec_uint (NM_BLUEZ_DEVICE_CAPABILITIES,
-		                      "Capabilities",
-		                      "Capabilities",
-		                      0, G_MAXUINT, 0,
-		                      G_PARAM_READABLE));
+		 g_param_spec_uint (NM_BLUEZ_DEVICE_CAPABILITIES, "", "",
+		                    0, G_MAXUINT, 0,
+		                    G_PARAM_READABLE |
+		                    G_PARAM_STATIC_STRINGS));
 
 	g_object_class_install_property
 		(object_class, PROP_USABLE,
-		 g_param_spec_boolean (NM_BLUEZ_DEVICE_USABLE,
-		                       "Usable",
-		                       "Usable",
+		 g_param_spec_boolean (NM_BLUEZ_DEVICE_USABLE, "", "",
 		                       FALSE,
-		                       G_PARAM_READABLE));
+		                       G_PARAM_READABLE |
+		                       G_PARAM_STATIC_STRINGS));
 
 	g_object_class_install_property
 		(object_class, PROP_CONNECTED,
-		 g_param_spec_boolean (NM_BLUEZ_DEVICE_CONNECTED,
-		                       "Connected",
-		                       "Connected",
+		 g_param_spec_boolean (NM_BLUEZ_DEVICE_CONNECTED, "", "",
 		                       FALSE,
-		                       G_PARAM_READABLE));
+		                       G_PARAM_READABLE |
+		                       G_PARAM_STATIC_STRINGS));
 
 	/* Signals */
 	signals[INITIALIZED] = g_signal_new ("initialized",
diff --git a/src/devices/bluetooth/nm-bluez-device.h b/src/devices/bluetooth/nm-bluez-device.h
index 0bf7d898..92d99fa7 100644
--- a/src/devices/bluetooth/nm-bluez-device.h
+++ b/src/devices/bluetooth/nm-bluez-device.h
@@ -18,8 +18,8 @@
  * Copyright (C) 2009 - 2014 Red Hat, Inc.
  */
 
-#ifndef NM_BLUEZ_DEVICE_H
-#define NM_BLUEZ_DEVICE_H
+#ifndef __NETWORKMANAGER_BLUEZ_DEVICE_H__
+#define __NETWORKMANAGER_BLUEZ_DEVICE_H__
 
 #include <glib.h>
 #include <glib-object.h>
@@ -62,7 +62,10 @@ typedef struct {
 
 GType nm_bluez_device_get_type (void);
 
-NMBluezDevice *nm_bluez_device_new (const char *path, NMConnectionProvider *provider, int bluez_version);
+NMBluezDevice *nm_bluez_device_new (const char *path,
+                                    const char *adapter_address,
+                                    NMConnectionProvider *provider,
+                                    int bluez_version);
 
 const char *nm_bluez_device_get_path (NMBluezDevice *self);
 
@@ -94,5 +97,5 @@ nm_bluez_device_connect_finish (NMBluezDevice *self,
 void
 nm_bluez_device_disconnect (NMBluezDevice *self);
 
-#endif /* NM_BLUEZ_DEVICE_H */
+#endif /* __NETWORKMANAGER_BLUEZ_DEVICE_H__ */
 
diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c
index 04ffb0a4..e176a4b4 100644
--- a/src/devices/bluetooth/nm-bluez-manager.c
+++ b/src/devices/bluetooth/nm-bluez-manager.c
@@ -18,6 +18,8 @@
  * Copyright (C) 2013 - 2014 Red Hat, Inc.
  */
 
+#include "config.h"
+
 #include <signal.h>
 #include <string.h>
 #include <stdlib.h>
@@ -62,20 +64,12 @@ static void check_bluez_and_try_setup (NMBluezManager *self);
 
 /**************************************************************************/
 
-#define PLUGIN_TYPE NM_DEVICE_TYPE_BT
-
 G_MODULE_EXPORT NMDeviceFactory *
 nm_device_factory_create (GError **error)
 {
 	return (NMDeviceFactory *) g_object_new (NM_TYPE_BLUEZ_MANAGER, NULL);
 }
 
-G_MODULE_EXPORT NMDeviceType
-nm_device_factory_get_device_type (void)
-{
-	return PLUGIN_TYPE;
-}
-
 /************************************************************************/
 
 struct AsyncData {
@@ -368,6 +362,18 @@ check_bluez_and_try_setup (NMBluezManager *self)
 	                          async_data_pack (self));
 }
 
+static void
+start (NMDeviceFactory *factory)
+{
+	check_bluez_and_try_setup (NM_BLUEZ_MANAGER (factory));
+}
+
+static NMDeviceType
+get_device_type (NMDeviceFactory *factory)
+{
+	return NM_DEVICE_TYPE_BT;
+}
+
 /*********************************************************************/
 
 static void
@@ -391,16 +397,6 @@ dispose (GObject *object)
 }
 
 static void
-constructed (GObject *object)
-{
-	NMBluezManager *self = NM_BLUEZ_MANAGER (object);
-
-	G_OBJECT_CLASS (nm_bluez_manager_parent_class)->constructed (object);
-
-	check_bluez_and_try_setup (self);
-}
-
-static void
 nm_bluez_manager_init (NMBluezManager *self)
 {
 	NMBluezManagerPrivate *priv = NM_BLUEZ_MANAGER_GET_PRIVATE (self);
@@ -412,6 +408,8 @@ nm_bluez_manager_init (NMBluezManager *self)
 static void
 device_factory_interface_init (NMDeviceFactory *factory_iface)
 {
+	factory_iface->get_device_type = get_device_type;
+	factory_iface->start = start;
 }
 
 static void
@@ -423,6 +421,5 @@ nm_bluez_manager_class_init (NMBluezManagerClass *klass)
 
 	/* virtual methods */
 	object_class->dispose = dispose;
-	object_class->constructed = constructed;
 }
 
diff --git a/src/devices/bluetooth/nm-bluez-manager.h b/src/devices/bluetooth/nm-bluez-manager.h
index 68d6dbe5..8320b298 100644
--- a/src/devices/bluetooth/nm-bluez-manager.h
+++ b/src/devices/bluetooth/nm-bluez-manager.h
@@ -19,8 +19,8 @@
  * Copyright (C) 2007 - 2014 Red Hat, Inc.
  */
 
-#ifndef NM_BLUEZ_MANAGER_H
-#define NM_BLUEZ_MANAGER_H
+#ifndef __NETWORKMANAGER_BLUEZ_MANAGER_H__
+#define __NETWORKMANAGER_BLUEZ_MANAGER_H__
 
 #include <glib.h>
 #include <glib-object.h>
@@ -40,5 +40,5 @@ typedef struct {
 	GObjectClass parent;
 } NMBluezManagerClass;
 
-#endif /* NM_BLUEZ_MANAGER_H */
+#endif /* __NETWORKMANAGER_BLUEZ_MANAGER_H__ */
 
diff --git a/src/devices/bluetooth/nm-bluez4-adapter.c b/src/devices/bluetooth/nm-bluez4-adapter.c
index ad1786f0..9d1cfe1f 100644
--- a/src/devices/bluetooth/nm-bluez4-adapter.c
+++ b/src/devices/bluetooth/nm-bluez4-adapter.c
@@ -18,10 +18,12 @@
  * Copyright (C) 2009 - 2012 Red Hat, Inc.
  */
 
+#include "config.h"
+
 #include <glib.h>
 #include <string.h>
 
-#include "NetworkManager.h"
+#include "nm-dbus-interface.h"
 #include "nm-dbus-manager.h"
 #include "nm-bluez4-adapter.h"
 #include "nm-bluez-device.h"
@@ -162,7 +164,7 @@ device_created (DBusGProxy *proxy, const char *path, gpointer user_data)
 	NMBluez4AdapterPrivate *priv = NM_BLUEZ4_ADAPTER_GET_PRIVATE (self);
 	NMBluezDevice *device;
 
-	device = nm_bluez_device_new (path, priv->provider, 4);
+	device = nm_bluez_device_new (path, priv->address, priv->provider, 4);
 	g_signal_connect (device, "initialized", G_CALLBACK (device_initialized), self);
 	g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self);
 	g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device);
@@ -371,19 +373,17 @@ nm_bluez4_adapter_class_init (NMBluez4AdapterClass *config_class)
 	/* Properties */
 	g_object_class_install_property
 		(object_class, PROP_PATH,
-		 g_param_spec_string (NM_BLUEZ4_ADAPTER_PATH,
-		                      "DBus Path",
-		                      "DBus Path",
+		 g_param_spec_string (NM_BLUEZ4_ADAPTER_PATH, "", "",
 		                      NULL,
-		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+		                      G_PARAM_STATIC_STRINGS));
 
 	g_object_class_install_property
 		(object_class, PROP_ADDRESS,
-		 g_param_spec_string (NM_BLUEZ4_ADAPTER_ADDRESS,
-		                      "Address",
-		                      "Address",
+		 g_param_spec_string (NM_BLUEZ4_ADAPTER_ADDRESS, "", "",
 		                      NULL,
-		                      G_PARAM_READABLE));
+		                      G_PARAM_READABLE |
+		                      G_PARAM_STATIC_STRINGS));
 
 	/* Signals */
 	signals[INITIALIZED] = g_signal_new ("initialized",
diff --git a/src/devices/bluetooth/nm-bluez4-adapter.h b/src/devices/bluetooth/nm-bluez4-adapter.h
index 454ca557..a6256412 100644
--- a/src/devices/bluetooth/nm-bluez4-adapter.h
+++ b/src/devices/bluetooth/nm-bluez4-adapter.h
@@ -18,8 +18,8 @@
  * Copyright (C) 2009 - 2012 Red Hat, Inc.
  */
 
-#ifndef NM_BLUEZ4_ADAPTER_H
-#define NM_BLUEZ4_ADAPTER_H
+#ifndef __NETWORKMANAGER_BLUEZ4_ADAPTER_H__
+#define __NETWORKMANAGER_BLUEZ4_ADAPTER_H__
 
 #include <glib.h>
 #include <glib-object.h>
@@ -65,5 +65,5 @@ gboolean nm_bluez4_adapter_get_initialized (NMBluez4Adapter *self);
 
 GSList *nm_bluez4_adapter_get_devices (NMBluez4Adapter *self);
 
-#endif /* NM_BLUEZ4_ADAPTER_H */
+#endif /* __NETWORKMANAGER_BLUEZ4_ADAPTER_H__ */
 
diff --git a/src/devices/bluetooth/nm-bluez4-manager.c b/src/devices/bluetooth/nm-bluez4-manager.c
index 2660cbd9..23b13d32 100644
--- a/src/devices/bluetooth/nm-bluez4-manager.c
+++ b/src/devices/bluetooth/nm-bluez4-manager.c
@@ -19,6 +19,8 @@
  * Copyright (C) 2007 - 2013 Red Hat, Inc.
  */
 
+#include "config.h"
+
 #include <signal.h>
 #include <string.h>
 #include <stdlib.h>
diff --git a/src/devices/bluetooth/nm-bluez4-manager.h b/src/devices/bluetooth/nm-bluez4-manager.h
index 19b1c65a..13cfef93 100644
--- a/src/devices/bluetooth/nm-bluez4-manager.h
+++ b/src/devices/bluetooth/nm-bluez4-manager.h
@@ -19,8 +19,8 @@
  * Copyright (C) 2007 - 2013 Red Hat, Inc.
  */
 
-#ifndef NM_BLUEZ4_MANAGER_H
-#define NM_BLUEZ4_MANAGER_H
+#ifndef __NETWORKMANAGER_BLUEZ4_MANAGER_H__
+#define __NETWORKMANAGER_BLUEZ4_MANAGER_H__
 
 #include <glib.h>
 #include <glib-object.h>
@@ -58,5 +58,5 @@ NMBluez4Manager *nm_bluez4_manager_new (NMConnectionProvider *provider);
 
 void nm_bluez4_manager_query_devices (NMBluez4Manager *manager);
 
-#endif /* NM_BLUEZ4_MANAGER_H */
+#endif /* __NETWORKMANAGER_BLUEZ4_MANAGER_H__ */
 
diff --git a/src/devices/bluetooth/nm-bluez5-dun.c b/src/devices/bluetooth/nm-bluez5-dun.c
new file mode 100644
index 00000000..a97eaa77
--- /dev/null
+++ b/src/devices/bluetooth/nm-bluez5-dun.c
@@ -0,0 +1,410 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <sys/socket.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+#include <bluetooth/rfcomm.h>
+#include <net/ethernet.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "nm-bluez5-dun.h"
+#include "nm-bt-error.h"
+#include "nm-logging.h"
+#include "NetworkManagerUtils.h"
+
+struct _NMBluez5DunContext {
+	bdaddr_t src;
+	bdaddr_t dst;
+	char *src_str;
+	char *dst_str;
+	int rfcomm_channel;
+	int rfcomm_fd;
+	int rfcomm_tty_fd;
+	int rfcomm_id;
+	NMBluez5DunFunc callback;
+	gpointer user_data;
+	sdp_session_t *sdp_session;
+	guint sdp_watch_id;
+};
+
+static void
+dun_connect (NMBluez5DunContext *context)
+{
+	struct sockaddr_rc sa;
+	int devid, try = 30;
+	char tty[100];
+	const int ttylen = sizeof (tty) - 1;
+	GError *error = NULL;
+
+	struct rfcomm_dev_req req = {
+		.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP),
+		.dev_id = -1,
+		.channel = context->rfcomm_channel
+	};
+
+	context->rfcomm_fd = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+	if (context->rfcomm_fd < 0) {
+		int errsv = errno;
+		error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                     "Failed to create RFCOMM socket: (%d) %s",
+		                     errsv, strerror (errsv));
+		goto done;
+	}
+
+	/* Connect to the remote device */
+	sa.rc_family = AF_BLUETOOTH;
+	sa.rc_channel = 0;
+	memcpy (&sa.rc_bdaddr, &context->src, ETH_ALEN);
+	if (bind (context->rfcomm_fd, (struct sockaddr *) &sa, sizeof(sa))) {
+		int errsv = errno;
+		error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                     "Failed to bind socket: (%d) %s",
+		                     errsv, strerror (errsv));
+		goto done;
+	}
+
+	sa.rc_channel = context->rfcomm_channel;
+	memcpy (&sa.rc_bdaddr, &context->dst, ETH_ALEN);
+	if (connect (context->rfcomm_fd, (struct sockaddr *) &sa, sizeof (sa)) ) {
+		int errsv = errno;
+		error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                     "Failed to connect to remote device: (%d) %s",
+		                     errsv, strerror (errsv));
+		goto done;
+	}
+
+	nm_log_dbg (LOGD_BT, "(%s): connected to %s on channel %d",
+	            context->src_str, context->dst_str, context->rfcomm_channel);
+
+	/* Create an RFCOMM kernel device for the DUN channel */
+	memcpy (&req.src, &context->src, ETH_ALEN);
+	memcpy (&req.dst, &context->dst, ETH_ALEN);
+	devid = ioctl (context->rfcomm_fd, RFCOMMCREATEDEV, &req);
+	if (devid < 0) {
+		int errsv = errno;
+		error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                     "Failed to create rfcomm device: (%d) %s",
+		                     errsv, strerror (errsv));
+		goto done;
+	}
+	context->rfcomm_id = devid;
+
+	snprintf (tty, ttylen, "/dev/rfcomm%d", devid);
+	while ((context->rfcomm_tty_fd = open (tty, O_RDONLY | O_NOCTTY)) < 0 && try--) {
+		if (try) {
+			g_usleep (100 * 1000);
+			continue;
+		}
+
+		error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                     "Failed to find rfcomm device: %s",
+		                     tty);
+		break;
+	}
+
+done:
+	context->callback (context, tty, error, context->user_data);
+}
+
+static void
+sdp_search_cleanup (NMBluez5DunContext *context)
+{
+	if (context->sdp_session) {
+		sdp_close (context->sdp_session);
+		context->sdp_session = NULL;
+	}
+
+	if (context->sdp_watch_id) {
+		g_source_remove (context->sdp_watch_id);
+		context->sdp_watch_id = 0;
+	}
+}
+
+static void
+sdp_search_completed_cb (uint8_t type, uint16_t status, uint8_t *rsp, size_t size, void *user_data)
+{
+	NMBluez5DunContext *context = user_data;
+	int scanned, seqlen = 0, bytesleft = size;
+	uint8_t dataType;
+	int channel = -1;
+
+	nm_log_dbg (LOGD_BT, "(%s -> %s): SDP search finished with type=%d status=%d",
+	            context->src_str, context->dst_str, status, type);
+
+	/* SDP response received */
+	if (status || type != SDP_SVC_SEARCH_ATTR_RSP) {
+		GError *error = g_error_new (NM_BT_ERROR,
+		                             NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                             "Did not get a Service Discovery response");
+		context->callback (context, NULL, error, context->user_data);
+		goto done;
+	}
+
+	scanned = sdp_extract_seqtype (rsp, bytesleft, &dataType, &seqlen);
+
+	nm_log_dbg (LOGD_BT, "(%s -> %s): SDP sequence type scanned=%d length=%d",
+	            context->src_str, context->dst_str, scanned, seqlen);
+
+	scanned = sdp_extract_seqtype (rsp, bytesleft, &dataType, &seqlen);
+	if (!scanned || !seqlen) {
+		/* Short read or unknown sequence type */
+		GError *error = g_error_new (NM_BT_ERROR,
+		                             NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                             "Improper Service Discovery response");
+		context->callback (context, NULL, error, context->user_data);
+		goto done;
+	}
+
+	rsp += scanned;
+	bytesleft -= scanned;
+	do {
+		sdp_record_t *rec;
+		int recsize = 0;
+		sdp_list_t *protos;
+
+		rec = sdp_extract_pdu (rsp, bytesleft, &recsize);
+		if (!rec)
+			break;
+
+		if (!recsize) {
+			sdp_record_free (rec);
+			break;
+		}
+
+		if (sdp_get_access_protos (rec, &protos) == 0) {
+			/* Extract the DUN channel number */
+			channel = sdp_get_proto_port (protos, RFCOMM_UUID);
+			sdp_list_free (protos, NULL);
+
+			nm_log_dbg (LOGD_BT, "(%s -> %s): SDP channel=%d",
+			            context->src_str, context->dst_str, channel);
+		}
+		sdp_record_free (rec);
+
+		scanned += recsize;
+		rsp += recsize;
+		bytesleft -= recsize;
+	} while ((scanned < (ssize_t) size) && (bytesleft > 0) && (channel < 0));
+
+done:
+	if (channel != -1) {
+		context->rfcomm_channel = channel;
+		dun_connect (context);
+	}
+
+	sdp_search_cleanup (context);
+}
+
+static gboolean
+sdp_search_process_cb (GIOChannel *channel, GIOCondition condition, gpointer user_data)
+{
+	NMBluez5DunContext *context = user_data;
+
+	nm_log_dbg (LOGD_BT, "(%s -> %s): SDP search progressed with condition=%d",
+	            context->src_str, context->dst_str, condition);
+
+	if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+		GError *error = g_error_new (NM_BT_ERROR,
+		                             NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                             "Service Discovery interrupted");
+		context->callback (context, NULL, error, context->user_data);
+		sdp_search_cleanup (context);
+		return FALSE;
+	}
+
+	if (sdp_process (context->sdp_session) < 0) {
+		nm_log_dbg (LOGD_BT, "(%s -> %s): SDP search finished",
+		            context->src_str, context->dst_str);
+
+		/* Search finished successfully. */
+		return FALSE;
+	}
+
+	/* Search progressed successfully. */
+	return TRUE;
+}
+
+static gboolean
+sdp_connect_watch (GIOChannel *channel, GIOCondition condition, gpointer user_data)
+{
+	NMBluez5DunContext *context = user_data;
+	sdp_list_t *search, *attrs;
+	uuid_t svclass;
+	uint16_t attr;
+	int fd, err, fd_err = 0;
+	socklen_t len = sizeof (fd_err);
+	GError *error = NULL;
+
+	context->sdp_watch_id = 0;
+
+	fd = g_io_channel_unix_get_fd (channel);
+	if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &fd_err, &len) < 0) {
+		nm_log_dbg (LOGD_BT, "(%s -> %s): getsockopt error=%d",
+		            context->src_str, context->dst_str, errno);
+		err = errno;
+	} else {
+		nm_log_dbg (LOGD_BT, "(%s -> %s): SO_ERROR error=%d",
+		            context->src_str, context->dst_str, fd_err);
+		err = fd_err;
+	}
+
+	if (err != 0) {
+		error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                     "Error on Service Discovery socket: (%d) %s",
+		                     err, strerror (err));
+		goto done;
+	}
+
+	if (sdp_set_notify (context->sdp_session, sdp_search_completed_cb, context) < 0) {
+		/* Should not be reached, only can fail if we passed bad sdp_session. */
+		error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                     "Could not request Service Discovery notification");
+		goto done;
+	}
+
+	sdp_uuid16_create (&svclass, DIALUP_NET_SVCLASS_ID);
+	search = sdp_list_append (NULL, &svclass);
+	attr = SDP_ATTR_PROTO_DESC_LIST;
+	attrs = sdp_list_append (NULL, &attr);
+
+	if (!sdp_service_search_attr_async (context->sdp_session, search, SDP_ATTR_REQ_INDIVIDUAL, attrs)) {
+		/* Set callback responsible for update the internal SDP transaction */
+		context->sdp_watch_id = g_io_add_watch (channel,
+		                                        G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+		                                        sdp_search_process_cb,
+		                                        context);
+	} else {
+		err = sdp_get_error (context->sdp_session);
+		error = g_error_new (NM_BT_ERROR,
+		                     NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                     "Error starting Service Discovery: (%d) %s",
+		                     err, strerror (err));
+	}
+
+	sdp_list_free (attrs, NULL);
+	sdp_list_free (search, NULL);
+
+done:
+	if (error) {
+		context->callback (context, NULL, error, context->user_data);
+		sdp_search_cleanup (context);
+	}
+
+	return G_SOURCE_REMOVE;
+}
+
+NMBluez5DunContext *
+nm_bluez5_dun_new (const char *adapter,
+                   const char *remote)
+
+{
+	NMBluez5DunContext *context;
+
+	context = g_slice_new0 (NMBluez5DunContext);
+	str2ba (adapter, &context->src);
+	str2ba (remote, &context->dst);
+	context->src_str = g_strdup (adapter);
+	context->dst_str = g_strdup (remote);
+	context->rfcomm_channel = -1;
+	context->rfcomm_id = -1;
+	context->rfcomm_fd = -1;
+	return context;
+}
+
+void
+nm_bluez5_dun_connect (NMBluez5DunContext *context,
+                       NMBluez5DunFunc callback,
+                       gpointer user_data)
+{
+	GIOChannel *channel;
+
+	context->callback = callback;
+	context->user_data = user_data;
+
+	if (context->rfcomm_channel != -1) {
+		nm_log_dbg (LOGD_BT, "(%s): channel number on device %s cached: %d",
+			    context->src_str, context->dst_str, context->rfcomm_channel);
+		dun_connect (context);
+		return;
+	}
+
+	nm_log_dbg (LOGD_BT, "(%s): starting channel number discovery for device %s",
+		    context->src_str, context->dst_str);
+
+	context->sdp_session = sdp_connect (&context->src, &context->dst, SDP_NON_BLOCKING);
+	if (!context->sdp_session) {
+		GError *error;
+		int err = sdp_get_error (context->sdp_session);
+
+		error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED,
+		                     "Failed to connect to the SDP server: (%d) %s",
+		                      err, strerror (err));
+		context->callback (context, NULL, error, context->user_data);
+		return;
+	}
+
+	channel = g_io_channel_unix_new (sdp_get_socket (context->sdp_session));
+	context->sdp_watch_id = g_io_add_watch (channel,
+	                                        G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+	                                        sdp_connect_watch,
+	                                        context);
+	g_io_channel_unref (channel);
+}
+
+/* Only clean up connection-related stuff to allow reconnect */
+void
+nm_bluez5_dun_cleanup (NMBluez5DunContext *context)
+{
+	g_return_if_fail (context != NULL);
+
+	sdp_search_cleanup (context);
+
+	if (context->rfcomm_fd >= 0) {
+		if (context->rfcomm_id >= 0) {
+			struct rfcomm_dev_req req = { 0 };
+
+			req.dev_id = context->rfcomm_id;
+			ioctl (context->rfcomm_fd, RFCOMMRELEASEDEV, &req);
+			context->rfcomm_id = -1;
+		}
+		close (context->rfcomm_fd);
+		context->rfcomm_fd = -1;
+	}
+
+	close (context->rfcomm_tty_fd);
+	context->rfcomm_tty_fd = -1;
+}
+
+void
+nm_bluez5_dun_free (NMBluez5DunContext *context)
+{
+	g_return_if_fail (context != NULL);
+
+	nm_bluez5_dun_cleanup (context);
+	g_clear_pointer (&context->src_str, g_free);
+	g_clear_pointer (&context->dst_str, g_free);
+	g_slice_free (NMBluez5DunContext, context);
+}
diff --git a/src/devices/bluetooth/nm-bluez5-dun.h b/src/devices/bluetooth/nm-bluez5-dun.h
new file mode 100644
index 00000000..7e259725
--- /dev/null
+++ b/src/devices/bluetooth/nm-bluez5-dun.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ */
+
+#ifndef _NM_BLUEZ5_UTILS_H_
+#define _NM_BLUEZ5_UTILS_H_
+
+#include <glib.h>
+#include <gio/gio.h>
+
+typedef struct _NMBluez5DunContext NMBluez5DunContext;
+
+typedef void (*NMBluez5DunFunc) (NMBluez5DunContext *context,
+                                 const char *rfcomm_dev,
+                                 GError *error,
+                                 gpointer user_data);
+
+NMBluez5DunContext *nm_bluez5_dun_new (const char *adapter,
+                                       const char *remote);
+
+void nm_bluez5_dun_connect (NMBluez5DunContext *context,
+                            NMBluez5DunFunc callback, gpointer user_data);
+
+/* Clean up connection resources */
+void nm_bluez5_dun_cleanup (NMBluez5DunContext *context);
+
+/* Clean up and dispose all resources */
+void nm_bluez5_dun_free (NMBluez5DunContext *context);
+
+#endif  /* _NM_BLUEZ5_UTILS_H_ */
diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c
index 63006b3a..b8568523 100644
--- a/src/devices/bluetooth/nm-bluez5-manager.c
+++ b/src/devices/bluetooth/nm-bluez5-manager.c
@@ -20,6 +20,8 @@
  * Copyright (C) 2013 Intel Corporation.
  */
 
+#include "config.h"
+
 #include <signal.h>
 #include <string.h>
 #include <stdlib.h>
@@ -143,7 +145,7 @@ device_added (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self)
 	NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self);
 	NMBluezDevice *device;
 
-	device = nm_bluez_device_new (path, priv->provider, 5);
+	device = nm_bluez_device_new (path, NULL, priv->provider, 5);
 	g_signal_connect (device, "initialized", G_CALLBACK (device_initialized), self);
 	g_signal_connect (device, "notify::usable", G_CALLBACK (device_usable), self);
 	g_hash_table_insert (priv->devices, (gpointer) nm_bluez_device_get_path (device), device);
diff --git a/src/devices/bluetooth/nm-bluez5-manager.h b/src/devices/bluetooth/nm-bluez5-manager.h
index 79f347bc..8152976d 100644
--- a/src/devices/bluetooth/nm-bluez5-manager.h
+++ b/src/devices/bluetooth/nm-bluez5-manager.h
@@ -19,8 +19,8 @@
  * Copyright (C) 2007 - 2013 Red Hat, Inc.
  */
 
-#ifndef NM_BLUEZ5_MANAGER_H
-#define NM_BLUEZ5_MANAGER_H
+#ifndef __NETWORKMANAGER_BLUEZ5_MANAGER_H__
+#define __NETWORKMANAGER_BLUEZ5_MANAGER_H__
 
 #include <glib.h>
 #include <glib-object.h>
@@ -58,5 +58,5 @@ NMBluez5Manager *nm_bluez5_manager_new (NMConnectionProvider *provider);
 
 void nm_bluez5_manager_query_devices (NMBluez5Manager *manager);
 
-#endif /* NM_BLUEZ5_MANAGER_H */
+#endif /* __NETWORKMANAGER_BLUEZ5_MANAGER_H__ */
 
diff --git a/src/devices/bluetooth/nm-bt-enum-types.c b/src/devices/bluetooth/nm-bt-enum-types.c
index 2595caeb..16741c9f 100644
--- a/src/devices/bluetooth/nm-bt-enum-types.c
+++ b/src/devices/bluetooth/nm-bt-enum-types.c
@@ -5,7 +5,7 @@
 
 #include "nm-bt-enum-types.h"
 
-#include "nm-device-bt.h"
+#include "nm-bt-error.h"
 
 GType
 nm_bt_error_get_type (void)
@@ -18,6 +18,7 @@ nm_bt_error_get_type (void)
         { NM_BT_ERROR_CONNECTION_NOT_BT, "NM_BT_ERROR_CONNECTION_NOT_BT", "ConnectionNotBt" },
         { NM_BT_ERROR_CONNECTION_INVALID, "NM_BT_ERROR_CONNECTION_INVALID", "ConnectionInvalid" },
         { NM_BT_ERROR_CONNECTION_INCOMPATIBLE, "NM_BT_ERROR_CONNECTION_INCOMPATIBLE", "ConnectionIncompatible" },
+        { NM_BT_ERROR_DUN_CONNECT_FAILED, "NM_BT_ERROR_DUN_CONNECT_FAILED", "DunConnectFailed" },
         { 0, NULL, NULL }
       };
       GType g_define_type_id =
diff --git a/src/devices/bluetooth/nm-bt-error.c b/src/devices/bluetooth/nm-bt-error.c
new file mode 100644
index 00000000..e3b8e7f5
--- /dev/null
+++ b/src/devices/bluetooth/nm-bt-error.c
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include "nm-bt-error.h"
+
+GQuark
+nm_bt_error_quark (void)
+{
+	static GQuark quark = 0;
+	if (!quark)
+		quark = g_quark_from_static_string ("nm-bt-error");
+	return quark;
+}
+
+
diff --git a/src/devices/bluetooth/nm-bt-error.h b/src/devices/bluetooth/nm-bt-error.h
new file mode 100644
index 00000000..fa3a9570
--- /dev/null
+++ b/src/devices/bluetooth/nm-bt-error.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ */
+
+#ifndef _NM_BLUEZ5_ERROR_H_
+#define _NM_BLUEZ5_ERROR_H_
+
+typedef enum {
+	NM_BT_ERROR_CONNECTION_NOT_BT = 0,   /*< nick=ConnectionNotBt >*/
+	NM_BT_ERROR_CONNECTION_INVALID,      /*< nick=ConnectionInvalid >*/
+	NM_BT_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
+	NM_BT_ERROR_DUN_CONNECT_FAILED,      /*< nick=DunConnectFailed >*/
+} NMBtError;
+
+#define NM_BT_ERROR (nm_bt_error_quark ())
+GQuark nm_bt_error_quark (void);
+
+#endif  /* _NM_BT_ERROR_H_ */
+
diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c
index 0bd2f17d..689f37c9 100644
--- a/src/devices/bluetooth/nm-device-bt.c
+++ b/src/devices/bluetooth/nm-device-bt.c
@@ -22,8 +22,6 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <net/ethernet.h>
-#include <netinet/ether.h>
 
 #include <glib/gi18n.h>
 #include <gio/gio.h>
@@ -46,9 +44,13 @@
 #include "NetworkManagerUtils.h"
 #include "nm-bt-enum-types.h"
 #include "nm-utils.h"
+#include "nm-bt-error.h"
+#include "nm-bt-enum-types.h"
+
+#define MM_DBUS_SERVICE  "org.freedesktop.ModemManager1"
 
-#define MM_OLD_DBUS_SERVICE  "org.freedesktop.ModemManager"
-#define MM_NEW_DBUS_SERVICE  "org.freedesktop.ModemManager1"
+#include "nm-device-logging.h"
+_LOG_DECLARE_SELF(NMDeviceBt);
 
 G_DEFINE_TYPE (NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE)
 
@@ -63,7 +65,7 @@ typedef struct {
 
 	NMBluezDevice *bt_device;
 
-	guint8 bdaddr[ETH_ALEN];
+	char *bdaddr;
 	char *name;
 	guint32 capabilities;
 
@@ -94,17 +96,6 @@ enum {
 static guint signals[LAST_SIGNAL] = { 0 };
 
 
-#define NM_BT_ERROR (nm_bt_error_quark ())
-
-static GQuark
-nm_bt_error_quark (void)
-{
-	static GQuark quark = 0;
-	if (!quark)
-		quark = g_quark_from_static_string ("nm-bt-error");
-	return quark;
-}
-
 guint32 nm_device_bt_get_capabilities (NMDeviceBt *self)
 {
 	g_return_val_if_fail (NM_IS_DEVICE_BT (self), NM_BT_CAPABILITY_NONE);
@@ -112,15 +103,6 @@ guint32 nm_device_bt_get_capabilities (NMDeviceBt *self)
 	return NM_DEVICE_BT_GET_PRIVATE (self)->capabilities;
 }
 
-static guint
-get_hw_address_length (NMDevice *device, gboolean *out_permanent)
-{
-	/* HW address is the Bluetooth HW address of the remote device */
-	if (out_permanent)
-		*out_permanent = TRUE;   /* the bdaddr of the remote device will never change */
-	return ETH_ALEN;
-}
-
 static guint32
 get_connection_bt_type (NMConnection *connection)
 {
@@ -142,6 +124,12 @@ get_connection_bt_type (NMConnection *connection)
 	return NM_BT_CAPABILITY_NONE;
 }
 
+static guint32
+get_generic_capabilities (NMDevice *device)
+{
+	return NM_DEVICE_CAP_IS_NON_KERNEL;
+}
+
 static gboolean
 can_auto_connect (NMDevice *device,
                   NMConnection *connection,
@@ -167,7 +155,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
 	NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
 	NMSettingConnection *s_con;
 	NMSettingBluetooth *s_bt;
-	const GByteArray *array;
+	const char *bdaddr;
 	guint32 bt_type;
 
 	if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->check_connection_compatible (device, connection))
@@ -187,11 +175,10 @@ check_connection_compatible (NMDevice *device, NMConnection *connection)
 	if (!(bt_type & priv->capabilities))
 		return FALSE;
 
-	array = nm_setting_bluetooth_get_bdaddr (s_bt);
-	if (!array || (array->len != ETH_ALEN))
+	bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt);
+	if (!bdaddr)
 		return FALSE;
-
-	if (memcmp (priv->bdaddr, array->data, ETH_ALEN) != 0)
+	if (!nm_utils_hwaddr_matches (priv->bdaddr, -1, bdaddr, -1))
 		return FALSE;
 
 	return TRUE;
@@ -225,14 +212,14 @@ complete_connection (NMDevice *device,
 {
 	NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
 	NMSettingBluetooth *s_bt;
-	const GByteArray *setting_bdaddr;
+	const char *setting_bdaddr;
 	const char *ctype;
 	gboolean is_dun = FALSE, is_pan = FALSE;
 	NMSettingGsm *s_gsm;
 	NMSettingCdma *s_cdma;
 	NMSettingSerial *s_serial;
-	NMSettingPPP *s_ppp;
-	const char *format = NULL, *preferred = NULL;
+	NMSettingPpp *s_ppp;
+	const char *fallback_prefix = NULL, *preferred = NULL;
 
 	s_gsm = nm_connection_get_setting_gsm (connection);
 	s_cdma = nm_connection_get_setting_cdma (connection);
@@ -262,18 +249,24 @@ complete_connection (NMDevice *device,
 		/* Make sure the device supports PAN */
 		if (!(priv->capabilities & NM_BT_CAPABILITY_NAP)) {
 			g_set_error_literal (error,
-			                     NM_SETTING_BLUETOOTH_ERROR,
-			                     NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
-			                     "PAN required but Bluetooth device does not support NAP");
+			                     NM_CONNECTION_ERROR,
+			                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
+			                     _("PAN requested, but Bluetooth device does not support NAP"));
+			g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE);
 			return FALSE;
 		}
 
 		/* PAN can't use any DUN-related settings */
 		if (s_gsm || s_cdma || s_serial || s_ppp) {
 			g_set_error_literal (error,
-			                     NM_SETTING_BLUETOOTH_ERROR,
-			                     NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
-			                     "PAN incompatible with GSM, CDMA, or serial settings");
+			                     NM_CONNECTION_ERROR,
+			                     NM_CONNECTION_ERROR_INVALID_SETTING,
+			                     _("PAN connections cannot specify GSM, CDMA, or serial settings"));
+			g_prefix_error (error, "%s: ",
+			                s_gsm ? NM_SETTING_GSM_SETTING_NAME :
+			                s_cdma ? NM_SETTING_CDMA_SETTING_NAME :
+			                s_serial ? NM_SETTING_SERIAL_SETTING_NAME :
+			                NM_SETTING_PPP_SETTING_NAME);
 			return FALSE;
 		}
 
@@ -281,23 +274,25 @@ complete_connection (NMDevice *device,
 		              NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
 		              NULL);
 
-		format = _("PAN connection %d");
+		fallback_prefix = _("PAN connection");
 	} else if (is_dun) {
 		/* Make sure the device supports PAN */
 		if (!(priv->capabilities & NM_BT_CAPABILITY_DUN)) {
 			g_set_error_literal (error,
-			                     NM_SETTING_BLUETOOTH_ERROR,
-			                     NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
-			                     "DUN required but Bluetooth device does not support DUN");
+			                     NM_CONNECTION_ERROR,
+			                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
+			                     _("DUN requested, but Bluetooth device does not support DUN"));
+			g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE);
 			return FALSE;
 		}
 
 		/* Need at least a GSM or a CDMA setting */
 		if (!s_gsm && !s_cdma) {
 			g_set_error_literal (error,
-			                     NM_SETTING_BLUETOOTH_ERROR,
-			                     NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
-			                     "Setting requires DUN but no GSM or CDMA setting is present");
+			                     NM_CONNECTION_ERROR,
+			                     NM_CONNECTION_ERROR_INVALID_SETTING,
+			                     _("DUN connection must include a GSM or CDMA setting"));
+			g_prefix_error (error, "%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME);
 			return FALSE;
 		}
 
@@ -306,51 +301,46 @@ complete_connection (NMDevice *device,
 		              NULL);
 
 		if (s_gsm) {
-			format = _("GSM connection %d");
+			fallback_prefix = _("GSM connection");
 			if (!nm_setting_gsm_get_number (s_gsm))
 				g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL);
-		} else if (s_cdma) {
-			format = _("CDMA connection %d");
+		} else {
+			fallback_prefix = _("CDMA connection");
 			if (!nm_setting_cdma_get_number (s_cdma))
 				g_object_set (G_OBJECT (s_cdma), NM_SETTING_GSM_NUMBER, "#777", NULL);
-		} else
-			format = _("DUN connection %d");
+		}
 	} else {
 		g_set_error_literal (error,
-		                     NM_SETTING_BLUETOOTH_ERROR,
-		                     NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
-		                     "Unknown/unhandled Bluetooth connection type");
+		                     NM_CONNECTION_ERROR,
+		                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
+		                     _("Unknown/unhandled Bluetooth connection type"));
+		g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_TYPE);
 		return FALSE;
 	}
 
 	nm_utils_complete_generic (connection,
 	                           NM_SETTING_BLUETOOTH_SETTING_NAME,
 	                           existing_connections,
-	                           format,
 	                           preferred,
+	                           fallback_prefix,
+	                           NULL,
 	                           is_dun ? FALSE : TRUE); /* No IPv6 yet for DUN */
 
 	setting_bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt);
 	if (setting_bdaddr) {
 		/* Make sure the setting BT Address (if any) matches the device's */
-		if (memcmp (setting_bdaddr->data, priv->bdaddr, ETH_ALEN)) {
+		if (!nm_utils_hwaddr_matches (setting_bdaddr, -1, priv->bdaddr, -1)) {
 			g_set_error_literal (error,
-			                     NM_SETTING_BLUETOOTH_ERROR,
-			                     NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY,
-			                     NM_SETTING_BLUETOOTH_BDADDR);
+			                     NM_CONNECTION_ERROR,
+			                     NM_CONNECTION_ERROR_INVALID_PROPERTY,
+			                     _("connection does not match device"));
+			g_prefix_error (error, "%s.%s: ", NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR);
 			return FALSE;
 		}
 	} else {
-		GByteArray *bdaddr;
-		const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
-
 		/* Lock the connection to this device by default */
-		if (memcmp (priv->bdaddr, null_mac, ETH_ALEN)) {
-			bdaddr = g_byte_array_sized_new (ETH_ALEN);
-			g_byte_array_append (bdaddr, priv->bdaddr, ETH_ALEN);
-			g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, bdaddr, NULL);
-			g_byte_array_free (bdaddr, TRUE);
-		}
+		if (!nm_utils_hwaddr_matches (priv->bdaddr, -1, NULL, ETH_ALEN))
+			g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, priv->bdaddr, NULL);
 	}
 
 	return TRUE;
@@ -437,7 +427,8 @@ modem_prepare_result (NMModem *modem,
                       NMDeviceStateReason reason,
                       gpointer user_data)
 {
-	NMDevice *device = NM_DEVICE (user_data);
+	NMDeviceBt *self = NM_DEVICE_BT (user_data);
+	NMDevice *device = NM_DEVICE (self);
 	NMDeviceState state;
 
 	state = nm_device_get_state (device);
@@ -470,8 +461,7 @@ modem_prepare_result (NMModem *modem,
 			 * the SIM if the incorrect PIN continues to be used.
 			 */
 			g_object_set (G_OBJECT (device), NM_DEVICE_AUTOCONNECT, FALSE, NULL);
-			nm_log_info (LOGD_MB, "(%s): disabling autoconnect due to failed SIM PIN",
-			             nm_device_get_iface (device));
+			_LOGI (LOGD_MB, "disabling autoconnect due to failed SIM PIN");
 		}
 
 		nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason);
@@ -491,21 +481,20 @@ device_state_changed (NMDevice *device,
 }
 
 static void
-modem_ip4_config_result (NMModem *self,
+modem_ip4_config_result (NMModem *modem,
                          NMIP4Config *config,
                          GError *error,
                          gpointer user_data)
 {
-	NMDevice *device = NM_DEVICE (user_data);
+	NMDeviceBt *self = NM_DEVICE_BT (user_data);
+	NMDevice *device = NM_DEVICE (self);
 
 	g_return_if_fail (nm_device_activate_ip4_state_in_conf (device) == TRUE);
 
 	if (error) {
-		nm_log_warn (LOGD_MB | LOGD_IP4 | LOGD_BT,
-		             "(%s): retrieving IP4 configuration failed: (%d) %s",
-		             nm_device_get_ip_iface (device),
-		             error ? error->code : -1,
-		             error && error->message ? error->message : "(unknown)");
+		_LOGW (LOGD_MB | LOGD_IP4 | LOGD_BT,
+		       "retrieving IP4 configuration failed: (%d) %s",
+		       error->code, error->message ? error->message : "(unknown)");
 
 		nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
 	} else
@@ -648,16 +637,14 @@ component_added (NMDevice *device, GObject *component)
 	 */
 	state = nm_device_get_state (NM_DEVICE (self));
 	if (state != NM_DEVICE_STATE_CONFIG) {
-		nm_log_warn (LOGD_BT | LOGD_MB,
-		             "(%s): modem found but device not in correct state (%d)",
-		             nm_device_get_iface (NM_DEVICE (self)),
-		             nm_device_get_state (NM_DEVICE (self)));
+		_LOGW (LOGD_BT | LOGD_MB,
+		       "modem found but device not in correct state (%d)",
+		       nm_device_get_state (NM_DEVICE (self)));
 		return TRUE;
 	}
 
-	nm_log_info (LOGD_BT | LOGD_MB,
-	             "Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) modem found.",
-	             nm_device_get_iface (NM_DEVICE (self)));
+	_LOGI (LOGD_BT | LOGD_MB,
+	       "Activation: (bluetooth) Stage 2 of 5 (Device Configure) modem found.");
 
 	if (priv->modem) {
 		g_warn_if_reached ();
@@ -674,11 +661,6 @@ component_added (NMDevice *device, GObject *component)
 	g_signal_connect (modem, NM_MODEM_STATE_CHANGED, G_CALLBACK (modem_state_cb), self);
 	g_signal_connect (modem, NM_MODEM_REMOVED, G_CALLBACK (modem_removed_cb), self);
 
-	/* In the old ModemManager the data port is known from the very beginning;
-	 * while in the new ModemManager the data port is set afterwards when the bearer gets
-	 * created */
-	if (modem_data_port)
-		nm_device_set_ip_iface (NM_DEVICE (self), modem_data_port);
 	g_signal_connect (modem, "notify::" NM_MODEM_DATA_PORT, G_CALLBACK (data_port_changed_cb), self);
 
 	/* Kick off the modem connection */
@@ -711,11 +693,9 @@ check_connect_continue (NMDeviceBt *self)
 	if (!priv->connected || !priv->have_iface)
 		return;
 
-	nm_log_info (LOGD_BT, "Activation (%s %s/bluetooth) Stage 2 of 5 (Device Configure) "
-	             "successful.  Will connect via %s.",
-	             nm_device_get_iface (device),
-	             nm_device_get_ip_iface (device),
-	             dun ? "DUN" : (pan ? "PAN" : "unknown"));
+	_LOGI (LOGD_BT,
+	       "Activation: (bluetooth) Stage 2 of 5 (Device Configure) successful. Will connect via %s.",
+	       dun ? "DUN" : (pan ? "PAN" : "unknown"));
 
 	/* Kill the connect timeout since we're connected now */
 	if (priv->timeout_id) {
@@ -730,9 +710,8 @@ check_connect_continue (NMDeviceBt *self)
 		/* Wait for ModemManager to find the modem */
 		priv->timeout_id = g_timeout_add_seconds (30, modem_find_timeout, self);
 
-		nm_log_info (LOGD_BT | LOGD_MB, "Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) "
-		             "waiting for modem to appear.",
-		             nm_device_get_iface (device));
+		_LOGI (LOGD_BT | LOGD_MB,
+		       "Activation: (bluetooth) Stage 2 of 5 (Device Configure) waiting for modem to appear.");
 	} else
 		g_assert_not_reached ();
 }
@@ -751,13 +730,14 @@ bluez_connect_cb (GObject *object,
 	                                         res, &error);
 
 	if (!device) {
-		nm_log_warn (LOGD_BT, "Error connecting with bluez: %s",
-		             error && error->message ? error->message : "(unknown)");
+		_LOGW (LOGD_BT, "Error connecting with bluez: %s",
+		       error && error->message ? error->message : "(unknown)");
 		g_clear_error (&error);
 
 		nm_device_state_changed (NM_DEVICE (self),
 		                         NM_DEVICE_STATE_FAILED,
 		                         NM_DEVICE_STATE_REASON_BT_FAILED);
+		g_object_unref (self);
 		return;
 	}
 
@@ -768,12 +748,12 @@ bluez_connect_cb (GObject *object,
 		nm_device_set_ip_iface (NM_DEVICE (self), device);
 	}
 
-	nm_log_dbg (LOGD_BT, "(%s): connect request successful",
-	            nm_device_get_iface (NM_DEVICE (self)));
+	_LOGD (LOGD_BT, "connect request successful");
 
 	/* Stage 3 gets scheduled when Bluez says we're connected */
 	priv->have_iface = TRUE;
 	check_connect_continue (self);
+	g_object_unref (self);
 }
 
 static void
@@ -790,8 +770,7 @@ bluez_connected_changed (NMBluezDevice *bt_device,
 	connected = nm_bluez_device_get_connected (bt_device);
 	if (connected) {
 		if (state == NM_DEVICE_STATE_CONFIG) {
-			nm_log_dbg (LOGD_BT, "(%s): connected to the device",
-			            nm_device_get_iface (device));
+			_LOGD (LOGD_BT, "connected to the device");
 
 			priv->connected = TRUE;
 			check_connect_continue (self);
@@ -802,13 +781,10 @@ bluez_connected_changed (NMBluezDevice *bt_device,
 		/* Bluez says we're disconnected from the device.  Suck. */
 
 		if (nm_device_is_activating (device)) {
-			nm_log_info (LOGD_BT,
-			             "Activation (%s/bluetooth): bluetooth link disconnected.",
-			             nm_device_get_iface (device));
+			_LOGI (LOGD_BT, "Activation: (bluetooth) bluetooth link disconnected.");
 			fail = TRUE;
 		} else if (state == NM_DEVICE_STATE_ACTIVATED) {
-			nm_log_info (LOGD_BT, "(%s): bluetooth link disconnected.",
-			             nm_device_get_iface (device));
+			_LOGI (LOGD_BT, "bluetooth link disconnected.");
 			fail = TRUE;
 		}
 
@@ -824,8 +800,7 @@ bt_connect_timeout (gpointer user_data)
 {
 	NMDeviceBt *self = NM_DEVICE_BT (user_data);
 
-	nm_log_dbg (LOGD_BT, "(%s): initial connection timed out",
-	            nm_device_get_iface (NM_DEVICE (self)));
+	_LOGD (LOGD_BT, "initial connection timed out");
 
 	NM_DEVICE_BT_GET_PRIVATE (self)->timeout_id = 0;
 	nm_device_state_changed (NM_DEVICE (self),
@@ -837,6 +812,7 @@ bt_connect_timeout (gpointer user_data)
 static NMActStageReturn
 act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
 {
+	NMDeviceBt *self = NM_DEVICE_BT (device);
 	NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device);
 	NMConnection *connection;
 
@@ -853,13 +829,12 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
 		return NM_ACT_STAGE_RETURN_FAILURE;
 	}
 
-	nm_log_dbg (LOGD_BT, "(%s): requesting connection to the device",
-	            nm_device_get_iface (device));
+	_LOGD (LOGD_BT, "requesting connection to the device");
 
 	/* Connect to the BT device */
 	nm_bluez_device_connect_async (priv->bt_device,
 	                               priv->bt_type & (NM_BT_CAPABILITY_DUN | NM_BT_CAPABILITY_NAP),
-	                               bluez_connect_cb, device);
+	                               bluez_connect_cb, g_object_ref (device));
 
 	if (priv->timeout_id)
 		g_source_remove (priv->timeout_id);
@@ -897,8 +872,7 @@ act_stage3_ip6_config_start (NMDevice *device,
 
 	if (priv->bt_type == NM_BT_CAPABILITY_DUN) {
 		ret = nm_modem_stage3_ip6_config_start (NM_DEVICE_BT_GET_PRIVATE (device)->modem,
-		                                        device,
-		                                        NM_DEVICE_CLASS (nm_device_bt_parent_class),
+		                                        nm_device_get_act_request (device),
 		                                        reason);
 	} else
 		ret = NM_DEVICE_CLASS (nm_device_bt_parent_class)->act_stage3_ip6_config_start (device, out_config, reason);
@@ -979,8 +953,7 @@ handle_availability_change (NMDeviceBt *self,
 
 	state = nm_device_get_state (device);
 	if (state < NM_DEVICE_STATE_UNAVAILABLE) {
-		nm_log_dbg (LOGD_BT, "(%s): availability blocked by UNMANAGED state",
-		            nm_device_get_iface (device));
+		_LOGD (LOGD_BT, "availability blocked by UNMANAGED state");
 		return;
 	}
 
@@ -990,7 +963,7 @@ handle_availability_change (NMDeviceBt *self,
 
 	if (available) {
 		if (state != NM_DEVICE_STATE_UNAVAILABLE)
-			nm_log_warn (LOGD_CORE | LOGD_BT, "not in expected unavailable state!");
+			_LOGW (LOGD_CORE | LOGD_BT, "not in expected unavailable state!");
 
 		nm_device_state_changed (device,
 		                         NM_DEVICE_STATE_DISCONNECTED,
@@ -1011,9 +984,8 @@ set_mm_running (NMDeviceBt *self, gboolean running)
 	if (priv->mm_running == running)
 		return;
 
-	nm_log_dbg (LOGD_BT, "(%s): ModemManager now %s",
-	            nm_device_get_iface (NM_DEVICE (self)),
-	            running ? "available" : "unavailable");
+	_LOGD (LOGD_BT, "ModemManager now %s",
+	       running ? "available" : "unavailable");
 
 	old_available = nm_device_is_available (NM_DEVICE (self));
 	priv->mm_running = running;
@@ -1038,11 +1010,7 @@ mm_name_owner_changed (NMDBusManager *dbus_mgr,
 	gboolean new_owner_good;
 
 	/* Can't handle the signal if its not from the modem service */
-	if (   strcmp (MM_OLD_DBUS_SERVICE, name) != 0
-#if WITH_MODEM_MANAGER_1
-	    && strcmp (MM_NEW_DBUS_SERVICE, name) != 0
-#endif
-	    )
+	if (strcmp (MM_DBUS_SERVICE, name) != 0)
 		return;
 
 	old_owner_good = (old_owner && strlen (old_owner));
@@ -1096,11 +1064,7 @@ nm_device_bt_init (NMDeviceBt *self)
 	                                      self);
 
 	/* Initial check to see if ModemManager is running */
-	mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_OLD_DBUS_SERVICE);
-#if WITH_MODEM_MANAGER_1
-	if (!mm_running)
-		mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_NEW_DBUS_SERVICE);
-#endif
+	mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_DBUS_SERVICE);
 	set_mm_running (self, mm_running);
 }
 
@@ -1108,15 +1072,13 @@ static void
 constructed (GObject *object)
 {
 	NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object);
-	const guint8 *my_hwaddr;
-	guint my_hwaddr_len = 0;
+	const char *my_hwaddr;
 
 	G_OBJECT_CLASS (nm_device_bt_parent_class)->constructed (object);
 
-	my_hwaddr = nm_device_get_hw_address (NM_DEVICE (object), &my_hwaddr_len);
+	my_hwaddr = nm_device_get_hw_address (NM_DEVICE (object));
 	g_assert (my_hwaddr);
-	g_assert_cmpint (my_hwaddr_len, ==, ETH_ALEN);
-	memcpy (priv->bdaddr, my_hwaddr, ETH_ALEN);
+	priv->bdaddr = g_strdup (my_hwaddr);
 
 	/* Watch for BT device property changes */
 	g_signal_connect (priv->bt_device, "notify::" NM_BLUEZ_DEVICE_CONNECTED,
@@ -1203,6 +1165,7 @@ finalize (GObject *object)
 
 	g_free (priv->rfcomm_iface);
 	g_free (priv->name);
+	g_free (priv->bdaddr);
 
 	G_OBJECT_CLASS (nm_device_bt_parent_class)->finalize (object);
 }
@@ -1221,7 +1184,7 @@ nm_device_bt_class_init (NMDeviceBtClass *klass)
 	object_class->dispose = dispose;
 	object_class->finalize = finalize;
 
-	device_class->get_hw_address_length = get_hw_address_length;
+	device_class->get_generic_capabilities = get_generic_capabilities;
 	device_class->can_auto_connect = can_auto_connect;
 	device_class->deactivate = deactivate;
 	device_class->act_stage2_config = act_stage2_config;
@@ -1238,27 +1201,24 @@ nm_device_bt_class_init (NMDeviceBtClass *klass)
 	/* Properties */
 	g_object_class_install_property
 		(object_class, PROP_BT_NAME,
-		 g_param_spec_string (NM_DEVICE_BT_NAME,
-		                      "Bluetooth device name",
-		                      "Bluetooth device name",
+		 g_param_spec_string (NM_DEVICE_BT_NAME, "", "",
 		                      NULL,
-		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+		                      G_PARAM_STATIC_STRINGS));
 
 	g_object_class_install_property
 		(object_class, PROP_BT_CAPABILITIES,
-		 g_param_spec_uint (NM_DEVICE_BT_CAPABILITIES,
-		                    "Bluetooth device capabilities",
-		                    "Bluetooth device capabilities",
+		 g_param_spec_uint (NM_DEVICE_BT_CAPABILITIES, "", "",
 		                    NM_BT_CAPABILITY_NONE, G_MAXUINT, NM_BT_CAPABILITY_NONE,
-		                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+		                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+		                    G_PARAM_STATIC_STRINGS));
 
 	g_object_class_install_property
 		(object_class, PROP_BT_DEVICE,
-		 g_param_spec_object (NM_DEVICE_BT_DEVICE,
-		                      "NMBluezDevice object for the Device",
-		                      "NMBluezDevice object for the Device",
+		 g_param_spec_object (NM_DEVICE_BT_DEVICE, "", "",
 		                      NM_TYPE_BLUEZ_DEVICE,
-		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+		                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+		                      G_PARAM_STATIC_STRINGS));
 
 	/* Signals */
 	signals[PPP_STATS] =
@@ -1273,6 +1233,4 @@ nm_device_bt_class_init (NMDeviceBtClass *klass)
 	nm_dbus_manager_register_exported_type (nm_dbus_manager_get (),
 	                                        G_TYPE_FROM_CLASS (klass),
 	                                        &dbus_glib_nm_device_bt_object_info);
-
-	dbus_g_error_domain_register (NM_BT_ERROR, NULL, NM_TYPE_BT_ERROR);
 }
diff --git a/src/devices/bluetooth/nm-device-bt.h b/src/devices/bluetooth/nm-device-bt.h
index 83732bc0..c1e95d91 100644
--- a/src/devices/bluetooth/nm-device-bt.h
+++ b/src/devices/bluetooth/nm-device-bt.h
@@ -18,8 +18,8 @@
  * Copyright (C) 2009 Red Hat, Inc.
  */
 
-#ifndef NM_DEVICE_BT_H
-#define NM_DEVICE_BT_H
+#ifndef __NETWORKMANAGER_DEVICE_BT_H__
+#define __NETWORKMANAGER_DEVICE_BT_H__
 
 #include <nm-device.h>
 #include "nm-bluez-device.h"
@@ -34,12 +34,6 @@ G_BEGIN_DECLS
 #define NM_IS_DEVICE_BT_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_DEVICE_BT))
 #define NM_DEVICE_BT_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_DEVICE_BT, NMDeviceBtClass))
 
-typedef enum {
-	NM_BT_ERROR_CONNECTION_NOT_BT = 0,   /*< nick=ConnectionNotBt >*/
-	NM_BT_ERROR_CONNECTION_INVALID,      /*< nick=ConnectionInvalid >*/
-	NM_BT_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/
-} NMBtError;
-
 #define NM_DEVICE_BT_NAME         "name"
 #define NM_DEVICE_BT_CAPABILITIES "bt-capabilities"
 #define NM_DEVICE_BT_DEVICE       "bt-device"
@@ -71,4 +65,4 @@ gboolean nm_device_bt_modem_added (NMDeviceBt *device,
 
 G_END_DECLS
 
-#endif /* NM_DEVICE_BT_H */
+#endif /* __NETWORKMANAGER_DEVICE_BT_H__ */