Index: include/NetworkManager.h
===================================================================
--- include/NetworkManager.h	(revision 2563)
+++ include/NetworkManager.h	(working copy)
@@ -33,6 +33,7 @@
 #define	NM_DBUS_INTERFACE_DEVICE	"org.freedesktop.NetworkManager.Device"
 #define NM_DBUS_INTERFACE_DEVICE_WIRED "org.freedesktop.NetworkManager.Device.Wired"
 #define NM_DBUS_INTERFACE_DEVICE_WIRELESS "org.freedesktop.NetworkManager.Device.Wireless"
+#define NM_DBUS_INTERFACE_DEVICE_BLUETOOTH "org.freedesktop.NetworkManager.Device.Bluetooth"
 #define NM_DBUS_PATH_ACCESS_POINT "/org/freedesktop/NetworkManager/AccessPoint"
 #define NM_DBUS_INTERFACE_ACCESS_POINT "org.freedesktop.NetworkManager.AccessPoint"
 
@@ -64,7 +65,8 @@
 {
 	DEVICE_TYPE_UNKNOWN = 0,
 	DEVICE_TYPE_802_3_ETHERNET,
-	DEVICE_TYPE_802_11_WIRELESS
+	DEVICE_TYPE_802_11_WIRELESS,
+	DEVICE_TYPE_BLUETOOTH
 } NMDeviceType;
 
 
Index: configure.in
===================================================================
--- configure.in	(revision 2563)
+++ configure.in	(working copy)
@@ -170,6 +170,10 @@
 AC_SUBST(HAL_CFLAGS)
 AC_SUBST(HAL_LIBS)
 
+PKG_CHECK_MODULES(BLUEZ, bluez)
+AC_SUBST(BLUEZ_CFLAGS)
+AC_SUBST(BLUEZ_LIBS)
+
 if test x"$with_gnome" != xno; then
 	PKG_CHECK_MODULES(GTK, gtk+-2.0)
 	AC_SUBST(GTK_CFLAGS)
Index: src/nm-hal-manager.c
===================================================================
--- src/nm-hal-manager.c	(revision 2563)
+++ src/nm-hal-manager.c	(working copy)
@@ -6,6 +6,7 @@
 #include "nm-utils.h"
 #include "nm-device-802-11-wireless.h"
 #include "nm-device-802-3-ethernet.h"
+#include "nm-device-bluetooth.h"
 
 struct _NMHalManager {
 	LibHalContext *hal_ctx;
@@ -22,10 +23,12 @@
 	char *iface = NULL;
 
 	if (libhal_device_property_exists (ctx, udi, "net.interface", NULL)) {
-		/* Only use Ethernet and Wireless devices at the moment */
+		/* Only use Ethernet, Wireless and Bluetooth devices at the moment */
 		if (libhal_device_property_exists (ctx, udi, "info.category", NULL)) {
 			char *category = libhal_device_get_property_string (ctx, udi, "info.category", NULL);
-			if (category && (!strcmp (category, "net.80203") || !strcmp (category, "net.80211"))) {
+			if (category && (!strcmp (category, "net.80203") ||
+				!strcmp (category, "net.80211") ||
+				!strcmp (category, "net.bluetooth"))) {
 				char *temp = libhal_device_get_property_string (ctx, udi, "net.interface", NULL);
 				iface = g_strdup (temp);
 				libhal_free_string (temp);
@@ -44,6 +47,8 @@
 
 	if (libhal_device_property_exists (ctx, udi, "info.category", NULL))
 		category = libhal_device_get_property_string (ctx, udi, "info.category", NULL);
+	if (category && (!strcmp (category, "net.bluetooth")))
+		return DEVICE_TYPE_BLUETOOTH;
 	if (category && (!strcmp (category, "net.80211")))
 		return DEVICE_TYPE_802_11_WIRELESS;
 	else if (category && (!strcmp (category, "net.80203")))
@@ -83,12 +88,22 @@
 {
 	NMDevice *dev;
 	char *driver;
+	char *name;
+	char *uuid;
 	NMDeviceType type;
 
 	type = discover_device_type (ctx, udi);
 	driver = nm_get_device_driver_name (ctx, udi);
 
 	switch (type) {
+	case DEVICE_TYPE_BLUETOOTH:
+		name = libhal_device_get_property_string (ctx, udi,
+													"net.bluetooth.name", NULL);
+		uuid = libhal_device_get_property_string (ctx, udi,
+													"net.bluetooth.uuid", NULL);
+		dev = (NMDevice *) nm_device_bluetooth_new (iface, udi, driver, name,
+													uuid, FALSE, nm_data);
+		break;
 	case DEVICE_TYPE_802_11_WIRELESS:
 		dev = (NMDevice *) nm_device_802_11_wireless_new (iface, udi, driver, FALSE, nm_data);
 		break;
@@ -126,7 +141,9 @@
 
 	if ((dev = create_nm_device (manager->hal_ctx, manager->nm_data, iface, udi))) {
 		nm_info ("Now managing %s device '%s'.",
-				 NM_IS_DEVICE_802_11_WIRELESS (dev) ? "wireless (802.11)" : "wired Ethernet (802.3)",
+				 NM_IS_DEVICE_BLUETOOTH (dev) ? "bluetooth" :
+				 NM_IS_DEVICE_802_11_WIRELESS (dev) ? "wireless (802.11)" :
+				 "wired Ethernet (802.3)",
 				 nm_device_get_iface (dev));
 
 		nm_manager_add_device (manager->nm_manager, dev);
@@ -173,7 +190,9 @@
 
 	/*nm_debug ("nm_hal_device_new_capability() called with udi = %s, capability = %s", udi, capability );*/
 
-	if (capability && ((strcmp (capability, "net.80203") == 0) || (strcmp (capability, "net.80211") == 0))) {
+	if (capability && ((strcmp (capability, "net.80203") == 0) ||
+		(strcmp (capability, "net.80211") == 0) ||
+		(strcmp (capability, "net.bluetooth") == 0))) {
 		char *iface;
 
 		if ((iface = get_device_interface_from_hal (manager->hal_ctx, udi))) {
Index: src/nm-manager.c
===================================================================
--- src/nm-manager.c	(revision 2563)
+++ src/nm-manager.c	(working copy)
@@ -5,6 +5,7 @@
 #include "nm-dbus-manager.h"
 #include "nm-device-interface.h"
 #include "nm-device-802-11-wireless.h"
+#include "nm-device-bluetooth.h"
 #include "NetworkManagerSystem.h"
 // #include "NetworkManagerDbus.h"
 
@@ -15,10 +16,12 @@
 
 static void manager_state_changed (NMManager *manager);
 static void manager_set_wireless_enabled (NMManager *manager, gboolean enabled);
+static void manager_set_bluetooth_enabled (NMManager *manager, gboolean enabled);
 
 typedef struct {
 	GSList *devices;
 	gboolean wireless_enabled;
+	gboolean bluetooth_enabled;
 	gboolean sleeping;
 } NMManagerPrivate;
 
@@ -40,6 +43,7 @@
 	PROP_0,
 	PROP_STATE,
 	PROP_WIRELESS_ENABLED,
+	PROP_BLUETOOTH_ENABLED,
 
 	LAST_PROP
 };
@@ -73,6 +77,9 @@
 	case PROP_WIRELESS_ENABLED:
 		manager_set_wireless_enabled (NM_MANAGER (object), g_value_get_boolean (value));
 		break;
+	case PROP_BLUETOOTH_ENABLED:
+		manager_set_bluetooth_enabled (NM_MANAGER (object), g_value_get_boolean (value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -92,6 +99,9 @@
 	case PROP_WIRELESS_ENABLED:
 		g_value_set_boolean (value, priv->wireless_enabled);
 		break;
+	case PROP_BLUETOOTH_ENABLED:
+		g_value_set_boolean (value, priv->bluetooth_enabled);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 		break;
@@ -127,6 +137,14 @@
 							   TRUE,
 							   G_PARAM_READWRITE));
 
+	g_object_class_install_property
+		(object_class, PROP_BLUETOOTH_ENABLED,
+		 g_param_spec_boolean (NM_MANAGER_BLUETOOTH_ENABLED,
+							   "BluetoothEnabled",
+							   "Is bluetooth enabled",
+							   TRUE,
+							   G_PARAM_READWRITE));
+
 	/* signals */
 	signals[DEVICE_ADDED] =
 		g_signal_new ("device-added",
@@ -207,6 +225,28 @@
 }
 
 static void
+manager_set_bluetooth_enabled (NMManager *manager, gboolean enabled)
+{
+	NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
+	GSList *iter;
+
+	if (priv->bluetooth_enabled == enabled)
+		return;
+
+	priv->bluetooth_enabled = enabled;
+
+	/* Tear down all wireless devices */
+	for (iter = priv->devices; iter; iter = iter->next) {
+		if (NM_IS_DEVICE_BLUETOOTH (iter->data)) {
+			if (enabled)
+				nm_device_bring_up (NM_DEVICE (iter->data), FALSE);
+			else
+				nm_device_bring_down (NM_DEVICE (iter->data), FALSE);
+		}
+	}
+}
+
+static void
 manager_device_added (NMManager *manager, NMDevice *device)
 {
 	g_signal_emit (manager, signals[DEVICE_ADDED], 0, device);
Index: src/nm-manager.h
===================================================================
--- src/nm-manager.h	(revision 2563)
+++ src/nm-manager.h	(working copy)
@@ -15,6 +15,7 @@
 
 #define NM_MANAGER_STATE "state"
 #define NM_MANAGER_WIRELESS_ENABLED "wireless-enabled"
+#define NM_MANAGER_BLUETOOTH_ENABLED "bluetooth-enabled"
 
 typedef struct {
 	GObject parent;
Index: src/nm-device-bluetooth.c
===================================================================
--- src/nm-device-bluetooth.c	(revision 0)
+++ src/nm-device-bluetooth.c	(revision 0)
@@ -0,0 +1,348 @@
+/* NetworkManager -- Network link manager
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * (C) Copyright 2005 Red Hat, Inc.
+ */
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "nm-device-bluetooth.h"
+#include "nm-device-interface.h"
+#include "nm-device-private.h"
+#include "nm-activation-request.h"
+#include "NetworkManagerUtils.h"
+#include "nm-utils.h"
+
+static gboolean impl_device_bluetooth_activate (NMDeviceBluetooth *device,
+													 gboolean user_requested,
+													 GError **err);
+
+#include "nm-device-bluetooth-glue.h"
+
+
+G_DEFINE_TYPE (NMDeviceBluetooth, nm_device_bluetooth, NM_TYPE_DEVICE)
+
+#define NM_DEVICE_BLUETOOTH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BLUETOOTH, NMDeviceBluetoothPrivate))
+
+typedef struct {
+	gboolean	dispose_has_run;
+
+	char *		name;
+	char *		uuid;
+	bdaddr_t	hw_addr;
+} NMDeviceBluetoothPrivate;
+
+enum {
+	PROP_0,
+	PROP_HW_ADDRESS,
+	PROP_NAME,
+	PROP_UUID,
+
+	LAST_PROP
+};
+
+static GObject*
+constructor (GType type,
+			 guint n_construct_params,
+			 GObjectConstructParam *construct_params)
+{
+	GObject *object;
+
+	object = G_OBJECT_CLASS (nm_device_bluetooth_parent_class)->constructor (type,
+																			n_construct_params,
+																			construct_params);
+
+	return object;
+}
+
+static void
+nm_device_bluetooth_init (NMDeviceBluetooth * self)
+{
+	NMDeviceBluetoothPrivate *priv = NM_DEVICE_BLUETOOTH_GET_PRIVATE (self);
+
+	priv->dispose_has_run = FALSE;
+
+	memset (&(priv->hw_addr), 0, sizeof (bdaddr_t));
+	priv->name = NULL;
+
+	nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_BLUETOOTH);
+}
+
+static void
+real_update_link (NMDevice *dev)
+{
+	nm_device_set_active_link (dev, TRUE);
+}
+
+
+static gboolean
+real_is_up (NMDevice *device)
+{
+	return NM_DEVICE_CLASS (nm_device_bluetooth_parent_class)->is_up (device);
+}
+
+static gboolean
+real_bring_up (NMDevice *dev)
+{
+	NMDeviceBluetoothPrivate *priv = NM_DEVICE_BLUETOOTH_GET_PRIVATE (dev);
+	const char *iface;
+	guint32 caps;
+
+	iface = nm_device_get_iface (dev);
+
+	nm_device_set_active_link (dev, TRUE);
+
+	return TRUE;
+}
+
+
+static void
+real_bring_down (NMDevice *dev)
+{
+	const char *iface;
+
+	iface = nm_device_get_iface (dev);
+
+	nm_device_set_active_link (dev, TRUE);
+}
+
+NMDeviceBluetooth *
+nm_device_bluetooth_new (const char *iface,
+						 const char *udi,
+						 const char *driver,
+						 const char *name,
+						 const char *uuid,
+						 gboolean test_dev,
+						 NMData *app_data)
+{
+	GObject *obj;
+
+	g_return_val_if_fail (iface != NULL, NULL);
+	g_return_val_if_fail (udi != NULL, NULL);
+	g_return_val_if_fail (app_data != NULL, NULL);
+
+	obj = g_object_new (NM_TYPE_DEVICE_BLUETOOTH,
+						NM_DEVICE_INTERFACE_UDI, udi,
+						NM_DEVICE_INTERFACE_IFACE, iface,
+						NM_DEVICE_INTERFACE_DRIVER, driver,
+						NM_DEVICE_BLUETOOTH_NAME, name,
+						NM_DEVICE_BLUETOOTH_UUID, uuid,
+						NM_DEVICE_INTERFACE_APP_DATA, app_data,
+						NULL);
+
+	return NM_DEVICE_BLUETOOTH (obj);
+}
+
+
+void
+nm_device_bluetooth_activate (NMDeviceBluetooth *self,
+							   gboolean user_requested)
+{
+	NMDevice *device;
+	NMActRequest *req;
+
+	g_return_if_fail (NM_IS_DEVICE_BLUETOOTH (self));
+
+	device = NM_DEVICE (self);
+	req = nm_act_request_new (device,
+							  NULL,
+							  user_requested);
+
+	nm_device_activate (device, req);
+	nm_act_request_unref (req);
+}
+
+
+static gboolean
+impl_device_bluetooth_activate (NMDeviceBluetooth *device,
+								 gboolean user_requested,
+								 GError **err)
+{
+	nm_device_bluetooth_activate (device, user_requested);
+
+	return TRUE;
+}
+
+
+/*
+ * nm_device_bluetooth_get_address
+ *
+ * Get a device's hardware address
+ *
+ */
+void
+nm_device_bluetooth_get_address (NMDeviceBluetooth *self, bdaddr_t *addr)
+{
+	g_return_if_fail (self != NULL);
+	g_return_if_fail (addr != NULL);
+
+	bacpy(addr, &(NM_DEVICE_BLUETOOTH_GET_PRIVATE (self)->hw_addr));
+}
+
+
+static void
+real_set_hw_address (NMDevice *dev)
+{
+	NMDeviceBluetooth *self = NM_DEVICE_BLUETOOTH (dev);
+	struct ifreq req;
+	NMSock *sk;
+	int ret;
+
+	sk = nm_dev_sock_open (nm_device_get_iface (dev), DEV_GENERAL, __FUNCTION__, NULL);
+	if (!sk)
+		return;
+
+	memset (&req, 0, sizeof (struct ifreq));
+	strncpy (req.ifr_name, nm_device_get_iface (dev), sizeof (req.ifr_name) - 1);
+
+	ret = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFHWADDR, &req);
+	if (ret == 0)
+		memcpy (&(NM_DEVICE_BLUETOOTH_GET_PRIVATE (self)->hw_addr),
+				&(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr));
+
+	nm_dev_sock_close (sk);
+}
+
+
+static guint32
+real_get_generic_capabilities (NMDevice *dev)
+{
+	NMDeviceBluetooth *self = NM_DEVICE_BLUETOOTH (dev);
+	guint32 caps = NM_DEVICE_CAP_NONE;
+
+	caps |= NM_DEVICE_CAP_NM_SUPPORTED;
+
+	return caps;
+}
+
+static gboolean
+real_can_interrupt_activation (NMDevice *dev)
+{
+	gboolean interrupt = FALSE;
+
+	return interrupt;
+}
+
+static void
+nm_device_bluetooth_finalize (GObject *object)
+{
+	NMDeviceBluetoothPrivate *priv = NM_DEVICE_BLUETOOTH_GET_PRIVATE (object);
+
+	G_OBJECT_CLASS (nm_device_bluetooth_parent_class)->finalize (object);
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+			  const GValue *value, GParamSpec *pspec)
+{
+	NMDeviceBluetoothPrivate *priv = NM_DEVICE_BLUETOOTH_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_NAME:
+		priv->name = g_value_dup_string (value);
+		break;
+	case PROP_UUID:
+		priv->uuid = g_value_dup_string (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+			  GValue *value, GParamSpec *pspec)
+{
+	NMDeviceBluetooth *device = NM_DEVICE_BLUETOOTH (object);
+	NMDeviceBluetoothPrivate *priv = NM_DEVICE_BLUETOOTH_GET_PRIVATE (object);
+	bdaddr_t hw_addr;
+	char hw_addr_buf[20];
+
+	switch (prop_id) {
+	case PROP_HW_ADDRESS:
+		memset (hw_addr_buf, 0, 20);
+		nm_device_bluetooth_get_address (device, &hw_addr);
+		ba2str(&hw_addr, hw_addr_buf);
+		g_value_set_string (value, &hw_addr_buf[0]);
+		break;
+	case PROP_NAME:
+		g_value_set_string (value, priv->name);
+		break;
+	case PROP_UUID:
+		g_value_set_string (value, priv->uuid);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+nm_device_bluetooth_class_init (NMDeviceBluetoothClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass);
+
+	g_type_class_add_private (object_class, sizeof (NMDeviceBluetoothPrivate));
+
+	/* virtual methods */
+	object_class->constructor = constructor;
+	object_class->get_property = get_property;
+	object_class->set_property = set_property;
+	object_class->finalize = nm_device_bluetooth_finalize;
+
+	parent_class->get_generic_capabilities = real_get_generic_capabilities;
+	parent_class->is_up = real_is_up;
+	parent_class->bring_up = real_bring_up;
+	parent_class->bring_down = real_bring_down;
+	parent_class->update_link = real_update_link;
+	parent_class->can_interrupt_activation = real_can_interrupt_activation;
+	parent_class->set_hw_address = real_set_hw_address;
+
+	/* properties */
+	g_object_class_install_property
+		(object_class, PROP_HW_ADDRESS,
+		 g_param_spec_string (NM_DEVICE_BLUETOOTH_HW_ADDRESS,
+							  "MAC Address",
+							  "Hardware MAC address",
+							  NULL,
+							  G_PARAM_READABLE));
+
+	g_object_class_install_property
+		(object_class, PROP_NAME,
+		 g_param_spec_string (NM_DEVICE_BLUETOOTH_NAME,
+							  "Name",
+							  "Name",
+							  NULL,
+							  G_PARAM_READWRITE));
+
+	g_object_class_install_property
+		(object_class, PROP_UUID,
+		 g_param_spec_string (NM_DEVICE_BLUETOOTH_UUID,
+							  "UUID",
+							  "UUID",
+							  NULL,
+							  G_PARAM_READWRITE));
+
+	dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+									 &dbus_glib_nm_device_bluetooth_object_info);
+}
Index: src/nm-device-bluetooth.h
===================================================================
--- src/nm-device-bluetooth.h	(revision 0)
+++ src/nm-device-bluetooth.h	(revision 0)
@@ -0,0 +1,72 @@
+/* NetworkManager -- Network link manager
+ *
+ * Dan Williams <dcbw@redhat.com>
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * (C) Copyright 2005 Red Hat, Inc.
+ */
+
+#ifndef NM_DEVICE_BLUETOOTH_H
+#define NM_DEVICE_BLUETOOTH_H
+
+#include <glib-object.h>
+#include <bluetooth/bluetooth.h>
+
+#include "nm-device.h"
+#include "NetworkManagerMain.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_DEVICE_BLUETOOTH			(nm_device_bluetooth_get_type ())
+#define NM_DEVICE_BLUETOOTH(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BLUETOOTH, NMDeviceBluetooth))
+#define NM_DEVICE_BLUETOOTH_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass),  NM_TYPE_DEVICE_BLUETOOTH, NMDeviceBluetoothClass))
+#define NM_IS_DEVICE_BLUETOOTH(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_BLUETOOTH))
+#define NM_IS_DEVICE_BLUETOOTH_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_DEVICE_BLUETOOTH))
+#define NM_DEVICE_BLUETOOTH_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_DEVICE_BLUETOOTH, NMDeviceBluetoothClass))
+
+#define NM_DEVICE_BLUETOOTH_HW_ADDRESS "hw-address"
+#define NM_DEVICE_BLUETOOTH_NAME "name"
+#define NM_DEVICE_BLUETOOTH_UUID "uuid"
+
+typedef struct {
+	NMDevice parent;
+} NMDeviceBluetooth;
+
+typedef struct {
+	NMDeviceClass parent;
+} NMDeviceBluetoothClass;
+
+
+GType nm_device_bluetooth_get_type (void);
+
+
+NMDeviceBluetooth *nm_device_bluetooth_new (const char *iface,
+											const char *udi,
+											const char *driver,
+											const char *name,
+											const char *uuid,
+											gboolean test_dev,
+											NMData *app_data);
+
+void nm_device_bluetooth_activate (NMDeviceBluetooth *self,
+									gboolean user_requested);
+
+void nm_device_bluetooth_get_address (NMDeviceBluetooth *dev,
+										bdaddr_t *addr);
+
+G_END_DECLS
+
+#endif	/* NM_DEVICE_BLUETOOTH_H */
Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 2563)
+++ src/Makefile.am	(working copy)
@@ -23,6 +23,8 @@
 		nm-device-802-3-ethernet.h	\
 		nm-device-802-11-wireless.c	\
 		nm-device-802-11-wireless.h	\
+		nm-device-bluetooth.c		\
+		nm-device-bluetooth.h		\
 		NetworkManagerAP.c			\
 		NetworkManagerAP.h			\
 		NetworkManagerAPList.c		\
@@ -103,6 +105,9 @@
 nm-device-802-11-wireless-glue.h: $(top_srcdir)/introspection/nm-device-802-11-wireless.xml
 	dbus-binding-tool --prefix=nm_device_802_11_wireless --mode=glib-server --output=nm-device-802-11-wireless-glue.h $(top_srcdir)/introspection/nm-device-802-11-wireless.xml
 
+nm-device-bluetooth-glue.h: $(top_srcdir)/introspection/nm-device-bluetooth.xml
+	dbus-binding-tool --prefix=nm_device_bluetooth --mode=glib-server --output=nm-device-bluetooth-glue.h $(top_srcdir)/introspection/nm-device-bluetooth.xml
+
 nm-ip4-config-glue.h: $(top_srcdir)/introspection/nm-ip4-config.xml
 	dbus-binding-tool --prefix=nm_ip4_config --mode=glib-server --output=nm-ip4-config-glue.h $(top_srcdir)/introspection/nm-ip4-config.xml
 
@@ -115,6 +120,7 @@
 	nm-device-interface-glue.h			\
 	nm-device-802-3-ethernet-glue.h			\
 	nm-device-802-11-wireless-glue.h		\
+	nm-device-bluetooth-glue.h		\
 	nm-ip4-config-glue.h				\
 	$(NULL)
 
@@ -126,6 +132,7 @@
 	$(HAL_CFLAGS)									\
 	$(OPENSSL_CFLAGS)								\
 	$(LIBNL_CFLAGS)								\
+	$(BLUEZ_CFLAGS)									\
 	-DWPA_SUPPLICANT_BIN=\"$(WPA_SUPPLICANT_BINARY_PATH)\"	\
 	-DDBUS_API_SUBJECT_TO_CHANGE						\
 	-DG_DISABLE_DEPRECATED							\
@@ -145,7 +152,8 @@
 			$(HAL_LIBS)						\
 			$(IWLIB)							\
 			$(LIBNL_LIBS)						\
-			$(top_builddir)/utils/libnmutils.la	\
+			$(BLUEZ_LIBS)						\
+		$(top_builddir)/utils/libnmutils.la	\
 			./named-manager/libnamed-manager.la	\
 			./vpn-manager/libvpn-manager.la		\
 			./dhcp-manager/libdhcp-manager.la		\
Index: introspection/nm-manager.xml
===================================================================
--- introspection/nm-manager.xml	(revision 2563)
+++ introspection/nm-manager.xml	(working copy)
@@ -15,6 +15,9 @@
     <property name="WirelessEnabled" type="b" access="readwrite"/>
     <property name="State" type="u" access="read"/>
 
+    <property name="BluetoothEnabled" type="b" access="readwrite"/>
+    <property name="State" type="u" access="read"/>
+
     <signal name="StateChange">
       <arg name="state" type="u"/>
     </signal>
Index: introspection/nm-device-bluetooth.xml
===================================================================
--- introspection/nm-device-bluetooth.xml	(revision 0)
+++ introspection/nm-device-bluetooth.xml	(revision 0)
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+  <interface name="org.freedesktop.NetworkManager.Device.Bluetooth">
+    <method name="Activate">
+      <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_device_bluetooth_activate"/>
+      <arg name="user_requested" type="b" direction="in"/>
+    </method>
+
+    <property name="HwAddress" type="s" access="read"/>
+    <property name="Name" type="s" access="readwrite"/>
+    <property name="Uuid" type="s" access="readwrite"/>
+  </interface>
+</node>
Index: libnm-glib/nm-device-bluetooth.c
===================================================================
--- libnm-glib/nm-device-bluetooth.c	(revision 0)
+++ libnm-glib/nm-device-bluetooth.c	(revision 0)
@@ -0,0 +1,128 @@
+#include "nm-device-bluetooth.h"
+#include "nm-device-private.h"
+#include "nm-utils.h"
+
+#include "nm-device-bluetooth-bindings.h"
+
+G_DEFINE_TYPE (NMDeviceBluetooth, nm_device_bluetooth, NM_TYPE_DEVICE)
+
+#define NM_DEVICE_BLUETOOTH_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BLUETOOTH, NMDeviceBluetoothPrivate))
+
+typedef struct {
+	DBusGProxy *bluetooth_proxy;
+
+	gboolean disposed;
+} NMDeviceBluetoothPrivate;
+
+
+static void
+nm_device_bluetooth_init (NMDeviceBluetooth *device)
+{
+	NMDeviceBluetoothPrivate *priv = NM_DEVICE_BLUETOOTH_GET_PRIVATE (device);
+
+	priv->disposed = FALSE;
+}
+
+static GObject*
+constructor (GType type,
+			 guint n_construct_params,
+			 GObjectConstructParam *construct_params)
+{
+	GObject *object;
+	NMDeviceBluetoothPrivate *priv;
+
+	object = G_OBJECT_CLASS (nm_device_bluetooth_parent_class)->constructor (type,
+																				  n_construct_params,
+																				  construct_params);
+	if (!object)
+		return NULL;
+
+	priv = NM_DEVICE_BLUETOOTH_GET_PRIVATE (object);
+
+	priv->bluetooth_proxy = dbus_g_proxy_new_for_name (nm_device_get_connection (NM_DEVICE (object)),
+													  NM_DBUS_SERVICE,
+													  nm_device_get_path (NM_DEVICE (object)),
+													  NM_DBUS_INTERFACE_DEVICE_BLUETOOTH);
+	return object;
+}
+
+static void
+dispose (GObject *object)
+{
+	NMDeviceBluetoothPrivate *priv = NM_DEVICE_BLUETOOTH_GET_PRIVATE (object);
+
+	if (priv->disposed)
+		return;
+
+	priv->disposed = TRUE;
+
+	g_object_unref (priv->bluetooth_proxy);
+
+	G_OBJECT_CLASS (nm_device_bluetooth_parent_class)->dispose (object);
+}
+
+static void
+nm_device_bluetooth_class_init (NMDeviceBluetoothClass *device_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (device_class);
+
+	g_type_class_add_private (device_class, sizeof (NMDeviceBluetoothPrivate));
+
+	/* virtual methods */
+	object_class->constructor = constructor;
+	object_class->dispose = dispose;
+}
+
+NMDeviceBluetooth *
+nm_device_bluetooth_new (DBusGConnection *connection, const char *path)
+{
+	g_return_val_if_fail (connection != NULL, NULL);
+	g_return_val_if_fail (path != NULL, NULL);
+
+	return (NMDeviceBluetooth *) g_object_new (NM_TYPE_DEVICE_BLUETOOTH,
+												NM_DEVICE_CONNECTION, connection,
+												NM_DEVICE_PATH, path,
+												NULL);
+}
+
+char *
+nm_device_bluetooth_get_hw_address (NMDeviceBluetooth *device)
+{
+	g_return_val_if_fail (NM_IS_DEVICE_BLUETOOTH (device), NULL);
+
+	return nm_dbus_get_string_property (nm_device_get_properties_proxy (NM_DEVICE (device)),
+										NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, "HwAddress");
+}
+
+char *
+nm_device_bluetooth_get_name (NMDeviceBluetooth *device)
+{
+	g_return_val_if_fail (NM_IS_DEVICE_BLUETOOTH (device), NULL);
+
+	return nm_dbus_get_string_property (nm_device_get_properties_proxy (NM_DEVICE (device)),
+										NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, "Name");
+}
+
+char *
+nm_device_bluetooth_get_uuid (NMDeviceBluetooth *device)
+{
+	g_return_val_if_fail (NM_IS_DEVICE_BLUETOOTH (device), NULL);
+
+	return nm_dbus_get_string_property (nm_device_get_properties_proxy (NM_DEVICE (device)),
+										NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, "Uuid");
+}
+
+void
+nm_device_bluetooth_activate (NMDeviceBluetooth *device, gboolean user_requested)
+{
+	GError *err = NULL;
+
+	g_return_if_fail (NM_IS_DEVICE_BLUETOOTH (device));
+
+	if (!org_freedesktop_NetworkManager_Device_Bluetooth_activate
+		(NM_DEVICE_BLUETOOTH_GET_PRIVATE (device)->bluetooth_proxy, user_requested, &err)) {
+
+		g_warning ("Activation failed: %s", err->message);
+		g_error_free (err);
+	}
+}
Index: libnm-glib/nm-device-bluetooth.h
===================================================================
--- libnm-glib/nm-device-bluetooth.h	(revision 0)
+++ libnm-glib/nm-device-bluetooth.h	(revision 0)
@@ -0,0 +1,31 @@
+#ifndef NM_DEVICE_BLUETOOTH_H
+#define NM_DEVICE_BLUETOOTH_H
+
+#include "nm-device.h"
+
+#define NM_TYPE_DEVICE_BLUETOOTH            (nm_device_bluetooth_get_type ())
+#define NM_DEVICE_BLUETOOTH(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_BLUETOOTH, NMDeviceBluetooth))
+#define NM_DEVICE_BLUETOOTH_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_BLUETOOTH, NMDeviceBluetoothClass))
+#define NM_IS_DEVICE_BLUETOOTH(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_BLUETOOTH))
+#define NM_IS_DEVICE_BLUETOOTH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEVICE_BLUETOOTH))
+#define NM_DEVICE_BLUETOOTH_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_BLUETOOTH, NMDeviceBluetoothClass))
+
+typedef struct {
+	NMDevice parent;
+} NMDeviceBluetooth;
+
+typedef struct {
+	NMDeviceClass parent;
+} NMDeviceBluetoothClass;
+
+GType nm_device_bluetooth_get_type (void);
+
+NMDeviceBluetooth *nm_device_bluetooth_new         (DBusGConnection *connection,
+													const char *path);
+char *			nm_device_bluetooth_get_hw_address	(NMDeviceBluetooth *device);
+char *			nm_device_bluetooth_get_name		(NMDeviceBluetooth *device);
+char *			nm_device_bluetooth_get_uuid		(NMDeviceBluetooth *device);
+void			nm_device_bluetooth_activate		(NMDeviceBluetooth *device,
+													gboolean user_requested);
+
+#endif /* NM_DEVICE_BLUETOOTH_H */
Index: libnm-glib/nm-client.c
===================================================================
--- libnm-glib/nm-client.c	(revision 2563)
+++ libnm-glib/nm-client.c	(working copy)
@@ -296,13 +296,16 @@
 		g_object_get (client, "connection", &connection, NULL);
 		type = nm_device_type_for_path (connection, path);
 
-		switch (type) {
+	switch (type) {
 		case DEVICE_TYPE_802_3_ETHERNET:
 			device = NM_DEVICE (nm_device_802_3_ethernet_new (connection, path));
 			break;
 		case DEVICE_TYPE_802_11_WIRELESS:
 			device = NM_DEVICE (nm_device_802_11_wireless_new (connection, path));
 			break;
+		case DEVICE_TYPE_BLUETOOTH:
+			device = NM_DEVICE (nm_device_bluetooth_new (connection, path));
+			break;
 		default:
 			device = nm_device_new (connection, path);
 		}
@@ -447,6 +450,39 @@
 						  &value);
 }
 
+gboolean
+nm_client_bluetooth_get_enabled (NMClient *client)
+{
+	GValue value = {0,};
+	gboolean enabled = FALSE;
+
+	g_return_val_if_fail (NM_IS_CLIENT (client), enabled);
+
+	if (nm_dbus_get_property (DBUS_G_PROXY (client),
+							  NM_DBUS_INTERFACE,
+							  "BluetoothEnabled",
+							  &value))
+		enabled = g_value_get_boolean (&value);
+
+	return enabled;
+}
+
+void
+nm_client_bluetooth_set_enabled (NMClient *client, gboolean enabled)
+{
+	GValue value = {0,};
+
+	g_return_if_fail (NM_IS_CLIENT (client));
+
+	g_value_init (&value, G_TYPE_BOOLEAN);
+	g_value_set_boolean (&value, enabled);
+	nm_dbus_set_property (DBUS_G_PROXY (client),
+						  NM_DBUS_INTERFACE,
+						  "BluetoothEnabled",
+						  &value);
+}
+
+
 NMState
 nm_client_get_state (NMClient *client)
 {
Index: libnm-glib/Makefile.am
===================================================================
--- libnm-glib/Makefile.am	(revision 2563)
+++ libnm-glib/Makefile.am	(working copy)
@@ -5,6 +5,7 @@
 	nm-device-bindings.h \
 	nm-device-802-3-ethernet-bindings.h \
 	nm-device-802-11-wireless-bindings.h \
+	nm-device-bluetooth-bindings.h \
 	nm-access-point-bindings.h \
 	nm-marshal.h \
 	nm-marshal.c
@@ -22,6 +23,7 @@
 	nm-device.h		\
 	nm-device-802-3-ethernet.h \
 	nm-device-802-11-wireless.h \
+	nm-device-bluetooth.h \
 	nm-access-point.h \
 	nm-ip4-config.h \
 	nm-vpn-connection.h
@@ -32,6 +34,7 @@
 	nm-device-private.h	\
 	nm-device-802-3-ethernet.c \
 	nm-device-802-11-wireless.c \
+	nm-device-bluetooth.c \
 	nm-access-point.c	\
 	nm-ip4-config.c		\
 	nm-utils.c		\
@@ -74,6 +77,9 @@
 nm-device-802-11-wireless-bindings.h: $(top_srcdir)/introspection/nm-device-802-11-wireless.xml
 	dbus-binding-tool --prefix=nm_device_802_11_wireless --mode=glib-client --output=nm-device-802-11-wireless-bindings.h $(top_srcdir)/introspection/nm-device-802-11-wireless.xml
 
+nm-device-bluetooth-bindings.h: $(top_srcdir)/introspection/nm-device-bluetooth.xml
+	dbus-binding-tool --prefix=nm_device_bluetooth --mode=glib-client --output=nm-device-bluetooth-bindings.h $(top_srcdir)/introspection/nm-device-bluetooth.xml
+
 nm-access-point-bindings.h: $(top_srcdir)/introspection/nm-access-point.xml
 	dbus-binding-tool --prefix=nm_access_point --mode=glib-client --output=nm-access-point-bindings.h $(top_srcdir)/introspection/nm-access-point.xml
 
Index: libnm-glib/nm-client.h
===================================================================
--- libnm-glib/nm-client.h	(revision 2563)
+++ libnm-glib/nm-client.h	(working copy)
@@ -47,6 +47,8 @@
 
 gboolean  nm_client_wireless_get_enabled (NMClient *client);
 void      nm_client_wireless_set_enabled (NMClient *client, gboolean enabled);
+gboolean  nm_client_bluetooth_get_enabled(NMClient *client);
+void      nm_client_bluetooth_set_enabled(NMClient *client, gboolean enabled);
 NMState   nm_client_get_state            (NMClient *client);
 void      nm_client_sleep                (NMClient *client, gboolean sleep);
 
