[meego-commits] 5144: Changes to Trunk/bluez

Anas Nashif nashif at linux.intel.com
Thu Jul 1 03:01:41 UTC 2010


Hi,
I have made the following changes to bluez in project Trunk. Please review and accept ASAP.

Thank You,
Anas Nashif

[This message was auto-generated]

---

Request #5144:

  submit:   Trunk:Testing/bluez(r10) -> Trunk/bluez


Message:
    migrate from Testing after handset day1

State:   new          2010-06-30T14:58:04 nashif
Comment: None



changes files:
--------------
--- bluez.changes
+++ bluez.changes
@@ -0,0 +1,5 @@
+* Wed Jun 30 2010 Zhu Yanhai <yanhai.zhu at linux.intel.com> 4.66
+- Upgrade to 4.66
+- Remove unnecessary patch correct-ref.patch
+- Switch to build with Spectacle
+

old:
----
  bluez-4.65.tar.gz
  correct-ref.patch

new:
----
  bluez-4.66.tar.gz
  bluez.yaml

spec files:
-----------
--- bluez.spec
+++ bluez.spec
@@ -1,34 +1,44 @@
-Summary: Bluetooth utilities
+# 
+# Do not Edit! Generated by:
+# spectacle version 0.17
+# 
+# >> macros
+# << macros
+
 Name: bluez
-Version: 4.65
+Summary:    Bluetooth utilities
+Version:    4.66
 Release: 1
-License: GPLv2+
 Group: Applications/System
-Source: http://www.kernel.org/pub/linux/bluetooth/%{name}-%{version}.tar.gz
-Source1: bluetooth.init
-
-Patch1: bluez-fsync.patch
-Patch2: remove-duplicate-wrong-udev-rule-for-dell-mice.patch
-Patch3: enable_HFP.patch
-Patch4: set_RememberPowered_as_false.patch
-Patch5: correct-ref.patch
-
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+License:    GPLv2+
 URL: http://www.bluez.org/
-
-BuildRequires: flex
-BuildRequires: dbus-devel >= 0.90
-BuildRequires: libusb-devel, glib2-devel, alsa-lib-devel
-BuildRequires: gst-plugins-base-devel, gstreamer-devel
-BuildRequires: libsndfile-devel
-
-
-Requires: fastinit, bluez-libs = %{version}
+Source0:    http://www.kernel.org/pub/linux/bluetooth/%{name}-%{version}.tar.gz
+Source1:    bluetooth.init
+Source100:  bluez.yaml
+Patch0:     bluez-fsync.patch
+Patch1:     remove-duplicate-wrong-udev-rule-for-dell-mice.patch
+Patch2:     enable_HFP.patch
+Patch3:     set_RememberPowered_as_false.patch
+Requires:   fastinit
+Requires:   bluez-libs = %{version}
 Requires: dbus >= 0.60
 Requires: hwdata >= 0.215
 Requires: ofono >= 0.2
-Requires(preun): /sbin/chkconfig, /sbin/service
-Requires(post): /sbin/chkconfig, /sbin/service
+Requires(preun): /sbin/chkconfig
+Requires(preun): /sbin/service
+Requires(post): /sbin/chkconfig
+Requires(post): /sbin/service
+Requires(postun): /sbin/service
+Requires(postun): /sbin/chkconfig
+BuildRequires:  pkgconfig(dbus-1)
+BuildRequires:  pkgconfig(libusb)
+BuildRequires:  pkgconfig(alsa)
+BuildRequires:  pkgconfig(sndfile)
+BuildRequires:  flex
+BuildRequires:  glib2-devel
+BuildRequires:  gst-plugins-base-devel
+BuildRequires:  gstreamer-devel
+
 
 %description
 Utilities for use in Bluetooth applications:
@@ -44,57 +54,78 @@
 
 The BLUETOOTH trademarks are owned by Bluetooth SIG, Inc., U.S.A.
 
+
+
 %package libs
 Summary: Libraries for use in Bluetooth applications
 Group: System/Libraries
+Requires:   %{name} = %{version}-%{release}
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description libs
+Libraries for use in Bluetooth applications.
 
 %package libs-devel
 Summary: Development libraries for Bluetooth applications
 Group: Development/Libraries
+Requires:   %{name} = %{version}-%{release}
 Requires: bluez-libs = %{version}
 
+%description libs-devel
+bluez-libs-devel contains development libraries and headers for
+use in Bluetooth applications.
+
+
 %package cups
 Summary: CUPS printer backend for Bluetooth printers
 Group: System/Daemons
+Requires:   %{name} = %{version}-%{release}
 Requires: bluez-libs = %{version}
 Requires: cups
 
-%package gstreamer
-Summary: GStreamer support for SBC audio format
-Group: System/Daemons
-Requires: bluez-libs = %{version}
+%description cups
+This package contains the CUPS backend
 
 %package alsa
 Summary: ALSA support for Bluetooth audio devices
 Group: System/Daemons
+Requires:   %{name} = %{version}-%{release}
 Requires: bluez-libs = %{version}
 
-%description cups
-This package contains the CUPS backend 
-
-%description gstreamer
-This package contains gstreamer plugins for the Bluetooth SBC audio format
-
 %description alsa
 This package contains ALSA support for Bluetooth audio devices
 
-%description libs
-Libraries for use in Bluetooth applications.
+%package gstreamer
+Summary:    GStreamer support for SBC audio format
+Group:      System/Daemons
+Requires:   %{name} = %{version}-%{release}
+Requires:   bluez-libs = %{version}
+
+%description gstreamer
+This package contains gstreamer plugins for the Bluetooth SBC audio format
 
-%description libs-devel
-bluez-libs-devel contains development libraries and headers for
-use in Bluetooth applications.
 
 %prep
+%setup -q -n %{name}-%{version}
 
-%setup -q
+# bluez-fsync.patch
+%patch0 -p1
+# remove-duplicate-wrong-udev-rule-for-dell-mice.patch
 %patch1 -p1
+# enable_HFP.patch
 %patch2 -p1
+# set_RememberPowered_as_false.patch
 %patch3 -p1
-%patch4 -p1
-%patch5 -p1
+# >> setup
+# << setup
+
 %build
-%reconfigure --enable-cups \
+# >> build pre
+# << build pre
+
+%reconfigure --disable-static \
+    --enable-cups \
 	--enable-hid2hci \
 	--enable-dfutool \
 	--enable-bccmd \
@@ -106,12 +137,19 @@
 	--enable-usb \
 	--enable-tools \
 	--with-telephony=dummy
-make
 
+make %{?jobs:-j%jobs}
+
+# >> build post
+# << build post
 %install
-rm -rf $RPM_BUILD_ROOT
+rm -rf %{buildroot}
+# >> install pre
+# << install pre
 %make_install
 
+# >> install post
+
 install -D -m0755 %SOURCE1 $RPM_BUILD_ROOT%{_sysconfdir}/rc.d/init.d/bluetooth
 
 # Remove the cups backend from libdir, and install it in /usr/lib whatever the install
@@ -120,14 +158,33 @@
 
 install -d -m0755 $RPM_BUILD_ROOT/%{_localstatedir}/lib/bluetooth
 
-%clean
-rm -rf $RPM_BUILD_ROOT
+# << install post
+
+
+
+
+
+
 
 %post libs -p /sbin/ldconfig
 
 %postun libs -p /sbin/ldconfig
 
+
+
+
+
+
+
+
+
+
+
+
+
 %files
+%defattr(-,root,root,-)
+# >> files
 %defattr(-, root, root)
 %{_bindir}/*
 %{_sbindir}/*
@@ -138,28 +195,46 @@
 %exclude /etc/rc.d/init.d/*
 %{_localstatedir}/lib/bluetooth
 /etc/udev/*
+# << files
+
 
 %files libs
+%defattr(-,root,root,-)
+# >> files libs
 %defattr(-, root, root)
 %{_libdir}/libbluetooth.so.*
 %doc AUTHORS COPYING INSTALL README
+# << files libs
 
 %files libs-devel
+%defattr(-,root,root,-)
+# >> files libs-devel
 %defattr(-, root, root)
 %{_libdir}/libbluetooth.so
 %dir %{_includedir}/bluetooth
 %{_includedir}/bluetooth/*
 %{_libdir}/pkgconfig/bluez.pc
+# << files libs-devel
 
 %files cups
+%defattr(-,root,root,-)
+# >> files cups
 %defattr(-, root, root)
 /usr/lib/cups/backend/bluetooth
-
-%files gstreamer
-%defattr(-, root, root)
-%{_libdir}/gstreamer-*/*.so
+# << files cups
 
 %files alsa
+%defattr(-,root,root,-)
+# >> files alsa
 %defattr(-, root, root)
 %{_libdir}/alsa-lib/*.so
 /etc/alsa/bluetooth.conf
+# << files alsa
+
+%files gstreamer
+%defattr(-,root,root,-)
+# >> files gstreamer
+%defattr(-, root, root)
+%{_libdir}/gstreamer-*/*.so
+# << files gstreamer
+

other changes:
--------------

++++++ bluez-4.65.tar.gz -> bluez-4.66.tar.gz
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,15 @@
+ver 4.66:
+	Fix regression with full debug enabling via SIGUSR2.
+	Fix redundant speaker/microphone gains being sent.
+	Fix not emitting PropertyChanged for SpeakerGain/MicrophoneGain.
+	Fix issue with storage usage when a record is not found in memory.
+	Fix issue with DiscoverServices not retrieving any records.
+	Fix audio profile disconnection order to match whitepaper.
+	Fix auto-accept confirmation when local agent has NoInputNoOutput.
+	Fix remote just-works SSP when MITM protection is required.
+	Fix performing dedicated bonding without MITM requirement.
+	Add support for storing debug link keys in runtime memory.
+
 ver 4.65:
 	Fix issues with general bonding being default setting now.
 	Fix driver removal upon device removal.
--- audio/a2dp.c
+++ audio/a2dp.c
@@ -879,6 +879,7 @@
 		DBG("Sink %p: ReConfigure_Ind", sep);
 	else
 		DBG("Source %p: ReConfigure_Ind", sep);
+
 	return TRUE;
 }
 
--- audio/avdtp.c
+++ audio/avdtp.c
@@ -2270,8 +2270,6 @@
 						AVDTP_STATE_IDLE);
 	} else
 		connection_lost(session, EIO);
-
-	return;
 }
 
 static void auth_cb(DBusError *derr, void *user_data)
@@ -3194,7 +3192,7 @@
 int avdtp_discover(struct avdtp *session, avdtp_discover_cb_t cb,
 			void *user_data)
 {
-	int ret;
+	int err;
 
 	if (session->discov_cb)
 		return -EBUSY;
@@ -3206,13 +3204,13 @@
 		return 0;
 	}
 
-	ret = send_request(session, FALSE, NULL, AVDTP_DISCOVER, NULL, 0);
-	if (ret == 0) {
+	err = send_request(session, FALSE, NULL, AVDTP_DISCOVER, NULL, 0);
+	if (err == 0) {
 		session->discov_cb = cb;
 		session->user_data = user_data;
 	}
 
-	return ret;
+	return err;
 }
 
 int avdtp_get_seps(struct avdtp *session, uint8_t acp_type, uint8_t media_type,
@@ -3337,7 +3335,7 @@
 	struct setconf_req *req;
 	struct avdtp_stream *new_stream;
 	unsigned char *ptr;
-	int ret, caps_len;
+	int err, caps_len;
 	struct avdtp_service_capability *cap;
 	GSList *l;
 
@@ -3378,10 +3376,10 @@
 		ptr += cap->length + 2;
 	}
 
-	ret = send_request(session, FALSE, new_stream,
+	err = send_request(session, FALSE, new_stream,
 				AVDTP_SET_CONFIGURATION, req,
 				sizeof(struct setconf_req) + caps_len);
-	if (ret < 0)
+	if (err < 0)
 		stream_free(new_stream);
 	else {
 		lsep->info.inuse = 1;
@@ -3394,7 +3392,7 @@
 
 	g_free(req);
 
-	return ret;
+	return err;
 }
 
 int avdtp_reconfigure(struct avdtp *session, GSList *caps,
--- audio/device.c
+++ audio/device.c
@@ -345,6 +345,11 @@
 			device_remove_control_timer(dev);
 			avrcp_disconnect(dev);
 		}
+		if (priv->hs_state != HEADSET_STATE_DISCONNECTED &&
+								priv->dc_req) {
+			headset_shutdown(dev);
+			break;
+		}
 		if (priv->hs_state == HEADSET_STATE_DISCONNECTED)
 			device_set_state(dev, AUDIO_STATE_DISCONNECTED);
 		else if (old_state == SINK_STATE_CONNECTING) {
@@ -519,10 +524,15 @@
 
 	priv->dc_req = dbus_message_ref(msg);
 
-	if (priv->hs_state != HEADSET_STATE_DISCONNECTED)
-		headset_shutdown(dev);
-	else if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED)
+	if (dev->control) {
+		device_remove_control_timer(dev);
+		avrcp_disconnect(dev);
+	}
+
+	if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED)
 		sink_shutdown(dev->sink);
+	else if (priv->hs_state != HEADSET_STATE_DISCONNECTED)
+		headset_shutdown(dev);
 	else {
 		dbus_message_unref(priv->dc_req);
 		priv->dc_req = NULL;
--- audio/gateway.c
+++ audio/gateway.c
@@ -204,7 +204,7 @@
 
 	dbus_error_init(&derr);
 	if (!dbus_set_error_from_message(&derr, reply)) {
-		DBG("Agent reply: file descriptor passed successfuly");
+		DBG("Agent reply: file descriptor passed successfully");
 		change_state(dev, GATEWAY_STATE_CONNECTED);
 		goto done;
 	}
@@ -234,7 +234,7 @@
 	}
 
 	if (!gw->agent) {
-		error("Handfree Agent not registered");
+		error("Handsfree Agent not registered");
 		goto fail;
 	}
 
@@ -561,6 +561,19 @@
 	{ NULL, NULL }
 };
 
+static void path_unregister(void *data)
+{
+	struct audio_device *dev = data;
+
+	DBG("Unregistered interface %s on path %s",
+		AUDIO_GATEWAY_INTERFACE, dev->path);
+
+	gateway_close(dev);
+
+	g_free(dev->gateway);
+	dev->gateway = NULL;
+}
+
 void gateway_unregister(struct audio_device *dev)
 {
 	if (dev->gateway->agent)
@@ -578,7 +591,7 @@
 	if (!g_dbus_register_interface(dev->conn, dev->path,
 					AUDIO_GATEWAY_INTERFACE,
 					gateway_methods, gateway_signals,
-					NULL, dev, NULL))
+					NULL, dev, path_unregister))
 		return NULL;
 
 	return g_new0(struct gateway, 1);
--- audio/headset.c
+++ audio/headset.c
@@ -950,37 +950,32 @@
 	return 0;
 }
 
-static int signal_gain_setting(struct audio_device *device, const char *buf)
+static int headset_set_gain(struct audio_device *device, uint16_t gain, char type)
 {
 	struct headset *hs = device->headset;
 	struct headset_slc *slc = hs->slc;
-	const char *property;
-	const char *name;
-	dbus_uint16_t gain;
-
-	if (strlen(buf) < 8) {
-		error("Too short string for Gain setting");
-		return -EINVAL;
-	}
-
-	gain = (dbus_uint16_t) strtol(&buf[7], NULL, 10);
+	const char *name, *property;
 
 	if (gain > 15) {
-		error("Invalid gain value received: %u", gain);
+		error("Invalid gain value: %u", gain);
 		return -EINVAL;
 	}
 
-	switch (buf[5]) {
+	switch (type) {
 	case HEADSET_GAIN_SPEAKER:
-		if (slc->sp_gain == gain)
-			goto ok;
+		if (slc->sp_gain == gain) {
+			DBG("Ignoring no-change in speaker gain");
+			return 0;
+		}
 		name = "SpeakerGainChanged";
 		property = "SpeakerGain";
 		slc->sp_gain = gain;
 		break;
 	case HEADSET_GAIN_MICROPHONE:
-		if (slc->mic_gain == gain)
-			goto ok;
+		if (slc->mic_gain == gain) {
+			DBG("Ignoring no-change in microphone gain");
+			return 0;
+		}
 		name = "MicrophoneGainChanged";
 		property = "MicrophoneGain";
 		slc->mic_gain = gain;
@@ -999,7 +994,26 @@
 				AUDIO_HEADSET_INTERFACE, property,
 				DBUS_TYPE_UINT16, &gain);
 
-ok:
+	return 0;
+}
+
+static int signal_gain_setting(struct audio_device *device, const char *buf)
+{
+	struct headset *hs = device->headset;
+	dbus_uint16_t gain;
+	int err;
+
+	if (strlen(buf) < 8) {
+		error("Too short string for Gain setting");
+		return -EINVAL;
+	}
+
+	gain = (dbus_uint16_t) strtol(&buf[7], NULL, 10);
+
+	err = headset_set_gain(device, gain, buf[5]);
+	if (err < 0)
+		return err;
+
 	return headset_send(hs, "\r\nOK\r\n");
 }
 
@@ -1891,7 +1905,6 @@
 {
 	struct audio_device *device = data;
 	struct headset *hs = device->headset;
-	struct headset_slc *slc = hs->slc;
 	DBusMessage *reply;
 	int err;
 
@@ -1900,7 +1913,8 @@
 						".NotConnected",
 						"Device not Connected");
 
-	if (gain > 15)
+	err = headset_set_gain(device, gain, type);
+	if (err < 0)
 		return g_dbus_create_error(msg, ERROR_INTERFACE
 						".InvalidArgument",
 						"Must be less than or equal to 15");
@@ -1909,31 +1923,13 @@
 	if (!reply)
 		return NULL;
 
-	if (hs->state != HEADSET_STATE_PLAYING)
-		goto done;
-
-	err = headset_send(hs, "\r\n+VG%c=%u\r\n", type, gain);
-	if (err < 0) {
-		dbus_message_unref(reply);
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
+	if (hs->state == HEADSET_STATE_PLAYING) {
+		err = headset_send(hs, "\r\n+VG%c=%u\r\n", type, gain);
+		if (err < 0) {
+			dbus_message_unref(reply);
+			return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
 						"%s", strerror(-err));
-	}
-
-done:
-	if (type == HEADSET_GAIN_SPEAKER) {
-		slc->sp_gain = gain;
-		g_dbus_emit_signal(conn, device->path,
-					AUDIO_HEADSET_INTERFACE,
-					"SpeakerGainChanged",
-					DBUS_TYPE_UINT16, &gain,
-					DBUS_TYPE_INVALID);
-	} else {
-		slc->mic_gain = gain;
-		g_dbus_emit_signal(conn, device->path,
-					AUDIO_HEADSET_INTERFACE,
-					"MicrophoneGainChanged",
-					DBUS_TYPE_UINT16, &gain,
-					DBUS_TYPE_INVALID);
+		}
 	}
 
 	return reply;
--- audio/manager.c
+++ audio/manager.c
@@ -194,7 +194,7 @@
 			headset_update(device, uuid16, uuidstr);
 		else
 			device->headset = headset_init(device, uuid16,
-							uuidstr);
+								uuidstr);
 		break;
 	case HANDSFREE_AGW_SVCLASS_ID:
 		DBG("Found Handsfree AG record");
@@ -603,7 +603,6 @@
 drop:
 	g_io_channel_shutdown(chan, TRUE, NULL);
 	g_io_channel_unref(chan);
-	return;
 }
 
 static int headset_server_init(struct audio_adapter *adapter)
@@ -850,7 +849,7 @@
 {
 	struct audio_adapter *adp;
 	const gchar *path = adapter_get_path(adapter);
-	int ret;
+	int err;
 
 	DBG("path %s", path);
 
@@ -858,13 +857,11 @@
 	if (!adp)
 		return -EINVAL;
 
-	ret = headset_server_init(adp);
-	if (ret < 0) {
+	err = headset_server_init(adp);
+	if (err < 0)
 		audio_adapter_unref(adp);
-		return ret;
-	}
 
-	return 0;
+	return err;
 }
 
 static void headset_server_remove(struct btd_adapter *adapter)
@@ -935,7 +932,7 @@
 		adp->hfp_hs_server = NULL;
 	}
 
-	audio_adapter_ref(adp);
+	audio_adapter_unref(adp);
 }
 
 static int a2dp_server_probe(struct btd_adapter *adapter)
@@ -943,7 +940,7 @@
 	struct audio_adapter *adp;
 	const gchar *path = adapter_get_path(adapter);
 	bdaddr_t src;
-	int ret;
+	int err;
 
 	DBG("path %s", path);
 
@@ -953,13 +950,11 @@
 
 	adapter_get_address(adapter, &src);
 
-	ret = a2dp_register(connection, &src, config);
-	if (ret < 0) {
+	err = a2dp_register(connection, &src, config);
+	if (err < 0)
 		audio_adapter_unref(adp);
-		return ret;
-	}
 
-	return 0;
+	return err;
 }
 
 static void a2dp_server_remove(struct btd_adapter *adapter)
--- audio/unix.c
+++ audio/unix.c
@@ -908,8 +908,6 @@
 	strncpy(rsp->object, dev->path, sizeof(rsp->object));
 
 	unix_ipc_sendmsg(client, &rsp->h);
-
-	return;
 }
 
 static void start_open(struct audio_device *dev, struct unix_client *client)
--- configure
+++ configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.63 for bluez 4.65.
+# Generated by GNU Autoconf 2.63 for bluez 4.66.
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -743,8 +743,8 @@
 # Identity of this package.
 PACKAGE_NAME='bluez'
 PACKAGE_TARNAME='bluez'
-PACKAGE_VERSION='4.65'
-PACKAGE_STRING='bluez 4.65'
+PACKAGE_VERSION='4.66'
+PACKAGE_STRING='bluez 4.66'
 PACKAGE_BUGREPORT=''
 
 ac_default_prefix=/usr/local
@@ -1598,7 +1598,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures bluez 4.65 to adapt to many kinds of systems.
+\`configure' configures bluez 4.66 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1668,7 +1668,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of bluez 4.65:";;
+     short | recursive ) echo "Configuration of bluez 4.66:";;
    esac
   cat <<\_ACEOF
 
@@ -1828,7 +1828,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-bluez configure 4.65
+bluez configure 4.66
 generated by GNU Autoconf 2.63
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1842,7 +1842,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by bluez $as_me 4.65, which was
+It was created by bluez $as_me 4.66, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   $ $0 $@
@@ -2692,7 +2692,7 @@
 
 # Define the identity of the package.
  PACKAGE='bluez'
- VERSION='4.65'
+ VERSION='4.66'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -14276,7 +14276,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by bluez $as_me 4.65, which was
+This file was extended by bluez $as_me 4.66, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -14339,7 +14339,7 @@
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-bluez config.status 4.65
+bluez config.status 4.66
 configured by $0, generated by GNU Autoconf 2.63,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
--- configure.ac
+++ configure.ac
@@ -1,5 +1,5 @@
 AC_PREREQ(2.60)
-AC_INIT(bluez, 4.65)
+AC_INIT(bluez, 4.66)
 
 AM_INIT_AUTOMAKE([foreign subdir-objects])
 AM_CONFIG_HEADER(config.h)
--- input/device.c
+++ input/device.c
@@ -596,8 +596,7 @@
 	close(req->ctrl_sock);
 
 cleanup:
-	if (req->rd_data)
-		free(req->rd_data);
+	free(req->rd_data);
 
 	g_free(req);
 }
@@ -662,8 +661,7 @@
 	err = ioctl_connadd(req);
 
 cleanup:
-	if (req->rd_data)
-		free(req->rd_data);
+	free(req->rd_data);
 	g_free(req);
 
 	return err;
--- lib/sdp.c
+++ lib/sdp.c
@@ -201,9 +201,9 @@
 	{ VIDEO_SOURCE_SVCLASS_ID,		"Video Source"			},
 	{ VIDEO_SINK_SVCLASS_ID,		"Video Sink"			},
 	{ VIDEO_DISTRIBUTION_SVCLASS_ID,	"Video Distribution"		},
-	{ MDP_SVCLASS_ID,			"MDP"				},
-	{ MDP_SOURCE_SVCLASS_ID,		"MDP Source"			},
-	{ MDP_SINK_SVCLASS_ID,			"MDP Sink"			},
+	{ HDP_SVCLASS_ID,			"HDP"				},
+	{ HDP_SOURCE_SVCLASS_ID,		"HDP Source"			},
+	{ HDP_SINK_SVCLASS_ID,			"HDP Sink"			},
 	{ APPLE_AGENT_SVCLASS_ID,		"Apple Agent"			},
 	{ 0 }
 };
@@ -2915,11 +2915,8 @@
 	}
 
 end:
-	if (req)
-		free(req);
-
-	if (rsp)
-		free(rsp);
+	free(req);
+	free(rsp);
 
 	return status;
 }
@@ -3025,11 +3022,8 @@
 		status = -1;
 	}
 end:
-	if (reqbuf)
-		free(reqbuf);
-
-	if (rspbuf)
-		free(rspbuf);
+	free(reqbuf);
+	free(rspbuf);
 
 	return status;
 }
@@ -3133,10 +3127,8 @@
 		status = -1;
 	}
 end:
-	if (reqbuf)
-		free(reqbuf);
-	if (rspbuf)
-		free(rspbuf);
+	free(reqbuf);
+	free(rspbuf);
 	return status;
 }
 
@@ -3472,10 +3464,8 @@
 	} while (cstate);
 
 end:
-	if (reqbuf)
-		free(reqbuf);
-	if (rspbuf)
-		free(rspbuf);
+	free(reqbuf);
+	free(rspbuf);
 
 	return status;
 }
@@ -3649,12 +3639,9 @@
 	}
 
 end:
-	if (reqbuf)
-		free(reqbuf);
-	if (rsp_concat_buf.data)
-		free(rsp_concat_buf.data);
-	if (rspbuf)
-		free(rspbuf);
+	free(reqbuf);
+	free(rsp_concat_buf.data);
+	free(rspbuf);
 	return rec;
 }
 
@@ -3777,9 +3764,8 @@
 
 	t = session->priv;
 
-	/* check if the buffer is already allocated */
-	if (t->rsp_concat_buf.data)
-		free(t->rsp_concat_buf.data);
+	/* clean possible allocated buffer */
+	free(t->rsp_concat_buf.data);
 	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
 
 	if (!t->reqbuf) {
@@ -3825,10 +3811,8 @@
 	return 0;
 end:
 
-	if (t->reqbuf) {
-		free(t->reqbuf);
-		t->reqbuf = NULL;
-	}
+	free(t->reqbuf);
+	t->reqbuf = NULL;
 
 	return -1;
 }
@@ -3881,9 +3865,8 @@
 
 	t = session->priv;
 
-	/* check if the buffer is already allocated */
-	if (t->rsp_concat_buf.data)
-		free(t->rsp_concat_buf.data);
+	/* clean possible allocated buffer */
+	free(t->rsp_concat_buf.data);
 	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
 
 	if (!t->reqbuf) {
@@ -3939,10 +3922,8 @@
 	return 0;
 end:
 
-	if (t->reqbuf) {
-		free(t->reqbuf);
-		t->reqbuf = NULL;
-	}
+	free(t->reqbuf);
+	t->reqbuf = NULL;
 
 	return -1;
 }
@@ -3996,9 +3977,8 @@
 
 	t = session->priv;
 
-	/* check if the buffer is already allocated */
-	if (t->rsp_concat_buf.data)
-		free(t->rsp_concat_buf.data);
+	/* clean possible allocated buffer */
+	free(t->rsp_concat_buf.data);
 	memset(&t->rsp_concat_buf, 0, sizeof(sdp_buf_t));
 
 	if (!t->reqbuf) {
@@ -4058,10 +4038,8 @@
 	return 0;
 end:
 
-	if (t->reqbuf) {
-		free(t->reqbuf);
-		t->reqbuf = NULL;
-	}
+	free(t->reqbuf);
+	t->reqbuf = NULL;
 
 	return -1;
 }
@@ -4286,8 +4264,7 @@
 			t->cb(pdu_id, status, pdata, size, t->udata);
 	}
 
-	if (rspbuf)
-		free(rspbuf);
+	free(rspbuf);
 
 	return err;
 }
@@ -4521,12 +4498,9 @@
 		}
 	}
 end:
-	if (rsp_concat_buf.data)
-		free(rsp_concat_buf.data);
-	if (reqbuf)
-		free(reqbuf);
-	if (rspbuf)
-		free(rspbuf);
+	free(rsp_concat_buf.data);
+	free(reqbuf);
+	free(rspbuf);
 	return status;
 }
 
@@ -4557,11 +4531,9 @@
 	t = session->priv;
 
 	if (t) {
-		if (t->reqbuf)
-			free(t->reqbuf);
+		free(t->reqbuf);
 
-		if (t->rsp_concat_buf.data)
-			free(t->rsp_concat_buf.data);
+		free(t->rsp_concat_buf.data);
 
 		free(t);
 	}
@@ -4668,8 +4640,7 @@
 	err = errno;
 	if (session->sock >= 0)
 		close(session->sock);
-	if (session->priv)
-		free(session->priv);
+	free(session->priv);
 	free(session);
 	errno = err;
 
--- lib/sdp.h
+++ lib/sdp.h
@@ -140,9 +140,9 @@
 #define VIDEO_SOURCE_SVCLASS_ID		0x1303
 #define VIDEO_SINK_SVCLASS_ID		0x1304
 #define VIDEO_DISTRIBUTION_SVCLASS_ID	0x1305
-#define MDP_SVCLASS_ID			0x1400
-#define MDP_SOURCE_SVCLASS_ID		0x1401
-#define MDP_SINK_SVCLASS_ID		0x1402
+#define HDP_SVCLASS_ID			0x1400
+#define HDP_SOURCE_SVCLASS_ID		0x1401
+#define HDP_SINK_SVCLASS_ID		0x1402
 #define APPLE_AGENT_SVCLASS_ID		0x2112
 
 /*
@@ -212,12 +212,22 @@
 #define VIDEO_SOURCE_PROFILE_ID		VIDEO_SOURCE_SVCLASS_ID
 #define VIDEO_SINK_PROFILE_ID		VIDEO_SINK_SVCLASS_ID
 #define VIDEO_DISTRIBUTION_PROFILE_ID	VIDEO_DISTRIBUTION_SVCLASS_ID
-#define MDP_PROFILE_ID			MDP_SVCLASS_ID
-#define MDP_SOURCE_PROFILE_ID		MDP_SROUCE_SVCLASS_ID
-#define MDP_SINK_PROFILE_ID		MDP_SINK_SVCLASS_ID
+#define HDP_PROFILE_ID			HDP_SVCLASS_ID
+#define HDP_SOURCE_PROFILE_ID		HDP_SOURCE_SVCLASS_ID
+#define HDP_SINK_PROFILE_ID		HDP_SINK_SVCLASS_ID
 #define APPLE_AGENT_PROFILE_ID		APPLE_AGENT_SVCLASS_ID
 
 /*
+ * Compatibility macros for the old MDP acronym
+ */
+#define MDP_SVCLASS_ID			HDP_SVCLASS_ID
+#define MDP_SOURCE_SVCLASS_ID		HDP_SOURCE_SVCLASS_ID
+#define MDP_SINK_SVCLASS_ID		HDP_SINK_SVCLASS_ID
+#define MDP_PROFILE_ID			HDP_PROFILE_ID
+#define MDP_SOURCE_PROFILE_ID		HDP_SOURCE_PROFILE_ID
+#define MDP_SINK_PROFILE_ID		HDP_SINK_PROFILE_ID
+
+/*
  * Attribute identifier codes
  */
 #define SDP_SERVER_RECORD_HANDLE		0x0000
--- sbc/sbc.c
+++ sbc/sbc.c
@@ -1138,8 +1138,7 @@
 	if (!sbc)
 		return;
 
-	if (sbc->priv_alloc_base)
-		free(sbc->priv_alloc_base);
+	free(sbc->priv_alloc_base);
 
 	memset(sbc, 0, sizeof(sbc_t));
 }
--- sbc/sbcdec.c
+++ sbc/sbcdec.c
@@ -259,15 +259,13 @@
 			break;
 
 		case 'd':
-			if (output)
-				free(output);
+			free(output);
 			output = strdup(optarg);
 			tofile = 0;
 			break;
 
 		case 'f' :
-			if (output)
-				free(output);
+			free(output);
 			output = strdup(optarg);
 			tofile = 1;
 			break;
@@ -289,8 +287,7 @@
 	for (i = 0; i < argc; i++)
 		decode(argv[i], output ? output : "/dev/dsp", tofile);
 
-	if (output)
-		free(output);
+	free(output);
 
 	return 0;
 }
--- src/adapter.c
+++ src/adapter.c
@@ -205,12 +205,13 @@
 	adapter->found_devices = NULL;
 }
 
-static int adapter_set_service_classes(struct btd_adapter *adapter, uint8_t value)
+static int adapter_set_service_classes(struct btd_adapter *adapter,
+							uint8_t value)
 {
 	int err;
 
-	/* Update only the service class, keep the limited bit, major/minor class
-	 * bits intact */
+	/* Update only the service class, keep the limited bit,
+	 * major/minor class bits intact */
 	adapter->wanted_cod &= 0x00ffff;
 	adapter->wanted_cod |= (value << 16);
 
@@ -831,7 +832,7 @@
 {
 	uint8_t class[3];
 	struct btd_adapter *adapter;
-	int ret;
+	int err;
 
 	if (status)
 		return;
@@ -865,17 +866,17 @@
 
 	if (adapter->wanted_cod & LIMITED_BIT &&
 			!(adapter->current_cod & LIMITED_BIT))
-		ret = adapter_ops->set_limited_discoverable(adapter->dev_id,
+		err = adapter_ops->set_limited_discoverable(adapter->dev_id,
 						adapter->wanted_cod, TRUE);
 	else if (!(adapter->wanted_cod & LIMITED_BIT) &&
 					adapter->current_cod & LIMITED_BIT)
-		ret = adapter_ops->set_limited_discoverable(adapter->dev_id,
+		err = adapter_ops->set_limited_discoverable(adapter->dev_id,
 						adapter->wanted_cod, FALSE);
 	else
-		ret = adapter_ops->set_class(adapter->dev_id,
+		err = adapter_ops->set_class(adapter->dev_id,
 							adapter->wanted_cod);
 
-	if (ret == 0)
+	if (err == 0)
 		adapter->pending_cod = adapter->wanted_cod;
 }
 
@@ -930,8 +931,9 @@
 	name = g_strdup((char *) dev->name);
 
 	if (connection)
-		emit_property_changed(connection, adapter->path, ADAPTER_INTERFACE,
-				"Name", DBUS_TYPE_STRING, &name);
+		emit_property_changed(connection, adapter->path,
+					ADAPTER_INTERFACE, "Name",
+					DBUS_TYPE_STRING, &name);
 	g_free(name);
 }
 
@@ -1155,19 +1157,10 @@
 			DBUS_TYPE_INVALID);
 
 	agent = device_get_agent(device);
-	if (!agent)
-		agent = adapter->agent;
 
 	if (agent && device_is_authorizing(device))
 		agent_cancel(agent);
 
-	agent = device_get_agent(device);
-
-	if (agent) {
-		agent_free(agent);
-		device_set_agent(device, NULL);
-	}
-
 	device_remove(device, remove_storage);
 }
 
@@ -1453,7 +1446,7 @@
 	struct session_req *req;
 	const char *sender = dbus_message_get_sender(msg);
 	uint8_t new_mode;
-	int ret;
+	int err;
 
 	if (!adapter->agent)
 		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
@@ -1479,11 +1472,11 @@
 	if (adapter->mode >= new_mode)
 		return dbus_message_new_method_return(msg);
 
-	ret = agent_confirm_mode_change(adapter->agent, mode2str(new_mode),
+	err = agent_confirm_mode_change(adapter->agent, mode2str(new_mode),
 					confirm_mode_cb, req, NULL);
-	if (ret < 0) {
+	if (err < 0) {
 		session_unref(req);
-		return failed_strerror(msg, -ret);
+		return failed_strerror(msg, -err);
 	}
 
 	return NULL;
@@ -1630,7 +1623,7 @@
 	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
 					DBUS_TYPE_OBJECT_PATH, &agent_path,
 					DBUS_TYPE_STRING, &capability,
-						DBUS_TYPE_INVALID) == FALSE)
+					DBUS_TYPE_INVALID) == FALSE)
 		return invalid_args(msg);
 
 	if (check_address(address) < 0)
@@ -1663,8 +1656,8 @@
 	return strcasecmp(dev_path, path);
 }
 
-static DBusMessage *remove_device(DBusConnection *conn,
-						DBusMessage *msg, void *data)
+static DBusMessage *remove_device(DBusConnection *conn, DBusMessage *msg,
+								void *data)
 {
 	struct btd_adapter *adapter = data;
 	struct btd_device *device;
@@ -1699,8 +1692,8 @@
 	return NULL;
 }
 
-static DBusMessage *find_device(DBusConnection *conn,
-					DBusMessage *msg, void *data)
+static DBusMessage *find_device(DBusConnection *conn, DBusMessage *msg,
+								void *data)
 {
 	struct btd_adapter *adapter = data;
 	struct btd_device *device;
@@ -1740,8 +1733,8 @@
 	adapter->agent = NULL;
 }
 
-static DBusMessage *register_agent(DBusConnection *conn,
-					DBusMessage *msg, void *data)
+static DBusMessage *register_agent(DBusConnection *conn, DBusMessage *msg,
+								void *data)
 {
 	const char *path, *name, *capability;
 	struct agent *agent;
@@ -1778,8 +1771,8 @@
 	return dbus_message_new_method_return(msg);
 }
 
-static DBusMessage *unregister_agent(DBusConnection *conn,
-					DBusMessage *msg, void *data)
+static DBusMessage *unregister_agent(DBusConnection *conn, DBusMessage *msg,
+								void *data)
 {
 	const char *path, *name;
 	struct btd_adapter *adapter = data;
@@ -1792,8 +1785,8 @@
 
 	if (!adapter->agent || !agent_matches(adapter->agent, name, path))
 		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".DoesNotExist",
-				"No such agent");
+					ERROR_INTERFACE ".DoesNotExist",
+					"No such agent");
 
 	agent_free(adapter->agent);
 	adapter->agent = NULL;
@@ -1963,7 +1956,7 @@
 	if (g_str_equal(mode, "off"))
 		strncpy((char *) adapter->dev.name, name, MAX_NAME_LENGTH);
 
-       /* Set device class */
+	/* Set device class */
 	if (adapter->initialized && adapter->wanted_cod) {
 		cls[1] = (adapter->wanted_cod >> 8) & 0xff;
 		cls[0] = adapter->wanted_cod & 0xff;
@@ -2006,13 +1999,13 @@
 }
 
 static void create_stored_device_from_linkkeys(char *key, char *value,
-						void *user_data)
+							void *user_data)
 {
 	struct btd_adapter *adapter = user_data;
 	struct btd_device *device;
 
-	if (g_slist_find_custom(adapter->devices,
-				key, (GCompareFunc) device_address_cmp))
+	if (g_slist_find_custom(adapter->devices, key,
+					(GCompareFunc) device_address_cmp))
 		return;
 
 	device = device_create(connection, adapter, key);
@@ -2023,7 +2016,7 @@
 }
 
 static void create_stored_device_from_blocked(char *key, char *value,
-						void *user_data)
+							void *user_data)
 {
 	struct btd_adapter *adapter = user_data;
 	struct btd_device *device;
@@ -2265,6 +2258,7 @@
 					DBUS_TYPE_BOOLEAN, &powered);
 
 	adapter_disable_cod_cache(adapter);
+
 	return 0;
 }
 
@@ -2843,7 +2837,8 @@
 				DBUS_TYPE_STRING, &paddr,
 				DBUS_TYPE_INVALID);
 
-		adapter->found_devices = g_slist_remove(adapter->found_devices, dev);
+		adapter->found_devices = g_slist_remove(adapter->found_devices,
+							dev);
 		dev_info_free(dev);
 	}
 
@@ -3055,10 +3050,6 @@
 	}
 
 	agent = device_get_agent(device);
-
-	if (!agent)
-		agent = adapter->agent;
-
 	if (!agent) {
 		g_free(auth);
 		return -EPERM;
@@ -3137,10 +3128,6 @@
 	 */
 
 	agent = device_get_agent(device);
-
-	if (!agent)
-		agent = adapter->agent;
-
 	if (!agent)
 		return -EPERM;
 
--- src/btio.h
+++ src/btio.h
@@ -21,8 +21,6 @@
  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
-#ifndef BT_IO_H
-#define BT_IO_H
 
 #include <glib.h>
 
@@ -93,4 +91,3 @@
 				GDestroyNotify destroy, GError **err,
 				BtIOOption opt1, ...);
 
-#endif
--- src/dbus-hci.c
+++ src/dbus-hci.c
@@ -61,7 +61,7 @@
 
 static DBusConnection *connection = NULL;
 
-static gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst,
+gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst,
 					struct btd_adapter **adapter,
 					struct btd_device **device,
 					gboolean create)
@@ -160,8 +160,8 @@
  *
  *****************************************************************/
 
-static void pincode_cb(struct agent *agent, DBusError *err, const char *pincode,
-			struct btd_device *device)
+static void pincode_cb(struct agent *agent, DBusError *err,
+				const char *pincode, struct btd_device *device)
 {
 	struct btd_adapter *adapter = device_get_adapter(device);
 	pin_code_reply_cp pr;
@@ -218,31 +218,41 @@
 								pincode_cb);
 }
 
-static void confirm_cb(struct agent *agent, DBusError *err, void *user_data)
+static int confirm_reply(struct btd_adapter *adapter,
+				struct btd_device *device, gboolean success)
 {
-	struct btd_device *device = user_data;
-	struct btd_adapter *adapter = device_get_adapter(device);
-	user_confirm_reply_cp cp;
 	int dd;
+	user_confirm_reply_cp cp;
 	uint16_t dev_id = adapter_get_dev_id(adapter);
 
 	dd = hci_open_dev(dev_id);
 	if (dd < 0) {
 		error("Unable to open hci%d", dev_id);
-		return;
+		return dd;
 	}
 
 	memset(&cp, 0, sizeof(cp));
 	device_get_address(device, &cp.bdaddr);
 
-	if (err)
-		hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY,
+	if (success)
+		hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_REPLY,
 					USER_CONFIRM_REPLY_CP_SIZE, &cp);
 	else
-		hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_REPLY,
+		hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY,
 					USER_CONFIRM_REPLY_CP_SIZE, &cp);
 
 	hci_close_dev(dd);
+
+	return 0;
+}
+
+static void confirm_cb(struct agent *agent, DBusError *err, void *user_data)
+{
+	struct btd_device *device = user_data;
+	struct btd_adapter *adapter = device_get_adapter(device);
+	gboolean success = (err == NULL) ? TRUE : FALSE;
+
+	confirm_reply(adapter, device, success);
 }
 
 static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey,
@@ -317,66 +327,65 @@
 {
 	struct btd_adapter *adapter;
 	struct btd_device *device;
-	uint8_t remcap, remauth, type;
-	uint16_t dev_id;
+	struct agent *agent;
+	uint8_t rem_cap, rem_auth, loc_cap, loc_auth;
+	gboolean bonding_initiator;
 
 	if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE))
 		return -ENODEV;
 
-	dev_id = adapter_get_dev_id(adapter);
-
-	if (get_auth_requirements(sba, dba, &type) < 0) {
-		int dd;
-
-		dd = hci_open_dev(dev_id);
-		if (dd < 0) {
-			error("Unable to open hci%d", dev_id);
-			return -1;
-		}
-
-		hci_send_cmd(dd, OGF_LINK_CTL,
-					OCF_USER_CONFIRM_NEG_REPLY, 6, dba);
-
-		hci_close_dev(dd);
-
-		return 0;
+	if (get_auth_requirements(sba, dba, &loc_auth) < 0) {
+		error("Unable to get local authentication requirements");
+		goto fail;
 	}
 
-	DBG("confirm authentication requirement is 0x%02x", type);
-
-	remcap = device_get_cap(device);
-	remauth = device_get_auth(device);
-
-	DBG("remote IO capabilities are 0x%02x", remcap);
-	DBG("remote authentication requirement is 0x%02x", remauth);
+	agent = device_get_agent(device);
+	if (agent == NULL) {
+		error("No agent available for user confirmation");
+		goto fail;
+	}
+
+	loc_cap = agent_get_io_capability(agent);
+
+	DBG("confirm IO capabilities are 0x%02x", loc_cap);
+	DBG("confirm authentication requirement is 0x%02x", loc_auth);
+
+	rem_cap = device_get_cap(device);
+	rem_auth = device_get_auth(device);
+
+	DBG("remote IO capabilities are 0x%02x", rem_cap);
+	DBG("remote authentication requirement is 0x%02x", rem_auth);
+
+	/* If we require MITM but the remote device can't provide that
+	 * (it has NoInputNoOutput) then reject the confirmation
+	 * request. The only exception is when we're dedicated bonding
+	 * initiators since then we always have the MITM bit set. */
+	bonding_initiator = device_is_bonding(device, NULL);
+	if (!bonding_initiator && (loc_auth & 0x01) && rem_cap == 0x03) {
+		error("Rejecting request: remote device can't provide MITM");
+		goto fail;
+	}
 
 	/* If no side requires MITM protection; auto-accept */
-	if (!(remauth & 0x01) &&
-			(type == 0xff || !(type & 0x01) || remcap == 0x03)) {
-		int dd;
+	if ((loc_auth == 0xff || !(loc_auth & 0x01) || rem_cap == 0x03) &&
+				(!(rem_auth & 0x01) || loc_cap == 0x03)) {
+		DBG("auto accept of confirmation");
 
 		/* Wait 5 milliseconds before doing auto-accept */
 		usleep(5000);
 
-		dd = hci_open_dev(dev_id);
-		if (dd < 0) {
-			error("Unable to open hci%d", dev_id);
-			return -1;
-		}
-
-		hci_send_cmd(dd, OGF_LINK_CTL,
-					OCF_USER_CONFIRM_REPLY, 6, dba);
+		if (confirm_reply(adapter, device, TRUE) < 0)
+			return -EIO;
 
-		hci_close_dev(dd);
-
-		DBG("auto accept of confirmation");
-
-		return device_request_authentication(device,
-						AUTH_TYPE_AUTO, 0, NULL);
+		return device_request_authentication(device, AUTH_TYPE_AUTO,
+								0, NULL);
 	}
 
 	return device_request_authentication(device, AUTH_TYPE_CONFIRM,
 							passkey, confirm_cb);
+
+fail:
+	return confirm_reply(adapter, device, FALSE);
 }
 
 int hcid_dbus_user_passkey(bdaddr_t *sba, bdaddr_t *dba)
@@ -428,7 +437,7 @@
 }
 
 void hcid_dbus_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer,
-					uint8_t status)
+								uint8_t status)
 {
 	struct btd_adapter *adapter;
 	struct btd_device *device;
@@ -660,15 +669,19 @@
 	struct btd_device *device;
 	struct btd_adapter *adapter;
 	uint8_t local_auth = 0xff, remote_auth, new_key_type;
-	gboolean bonding, stored;
+	gboolean bonding, temporary = FALSE;
 
 	if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
 		return -ENODEV;
 
-	if (key_type == 0x06 && old_key_type != 0xff)
-		new_key_type = old_key_type;
-	else
-		new_key_type = key_type;
+	new_key_type = key_type;
+
+	if (key_type == 0x06) {
+		if (device_get_debug_key(device, NULL))
+			old_key_type = 0x03;
+		if (old_key_type != 0xff)
+			new_key_type = old_key_type;
+	}
 
 	get_auth_requirements(local, peer, &local_auth);
 	remote_auth = device_get_auth(device);
@@ -677,7 +690,12 @@
 	DBG("local auth 0x%02x and remote auth 0x%02x",
 					local_auth, remote_auth);
 
-	/* Only store the link key if one of the following is true:
+	/* Clear any previous debug key */
+	device_set_debug_key(device, NULL);
+
+	/* Store the link key only in runtime memory if it's a debug
+	 * key, else store the link key persistently if one of the
+	 * following is true:
 	 * 1. this is a legacy link key
 	 * 2. this is a changed combination key and there was a previously
 	 *    stored one
@@ -685,8 +703,14 @@
 	 * 4. the local side had dedicated bonding as a requirement
 	 * 5. the remote side is using dedicated bonding since in that case
 	 *    also the local requirements are set to dedicated bonding
+	 * If none of the above match only keep the link key around for
+	 * this connection and set the temporary flag for the device.
 	 */
-	if (key_type < 0x03 || (key_type == 0x06 && old_key_type != 0xff) ||
+	if (new_key_type == 0x03) {
+		DBG("Storing debug key in runtime memory");
+		device_set_debug_key(device, key);
+	} else if (key_type < 0x03 ||
+				(key_type == 0x06 && old_key_type != 0xff) ||
 				(local_auth > 0x01 && remote_auth > 0x01) ||
 				(local_auth == 0x02 || local_auth == 0x03) ||
 				(remote_auth == 0x02 || remote_auth == 0x03)) {
@@ -700,10 +724,8 @@
 			error("write_link_key: %s (%d)", strerror(-err), -err);
 			return err;
 		}
-
-		stored = TRUE;
 	} else
-		stored = FALSE;
+		temporary = TRUE;
 
 	/* If this is not the first link key set a flag so a subsequent auth
 	 * complete event doesn't trigger SDP */
@@ -715,7 +737,7 @@
 	else if (!bonding && old_key_type == 0xff)
 		hcid_dbus_bonding_process_complete(local, peer, 0);
 
-	if (!stored)
+	if (temporary)
 		device_set_temporary(device, TRUE);
 
 	return 0;
@@ -879,6 +901,7 @@
 	struct btd_adapter *adapter;
 	struct btd_device *device;
 	struct agent *agent = NULL;
+	uint8_t agent_cap;
 
 	if (!get_adapter_and_device(local, remote, &adapter, &device, TRUE))
 		return -ENODEV;
@@ -910,9 +933,6 @@
 
 	/* For CreatePairedDevice use dedicated bonding */
 	agent = device_get_agent(device);
-	if (!agent)
-		agent = adapter_get_agent(adapter);
-
 	if (!agent) {
 		/* This is the non bondable mode case */
 		if (device_get_auth(device) > 0x01) {
@@ -935,11 +955,12 @@
 		return -1;
 	}
 
+	agent_cap = agent_get_io_capability(agent);
+
 	if (*auth == 0x00 || *auth == 0x04) {
 		/* If remote requests dedicated bonding follow that lead */
 		if (device_get_auth(device) == 0x02 ||
 				device_get_auth(device) == 0x03) {
-			uint8_t agent_cap = agent_get_io_capability(agent);
 
 			/* If both remote and local IO capabilities allow MITM
 			 * then require it, otherwise don't */
@@ -957,9 +978,12 @@
 					device_get_auth(device) == 0x01)
 			*auth = 0x00;
 
-		/* If remote requires MITM then also require it */
+		/* If remote requires MITM then also require it, unless
+		 * our IO capability is NoInputNoOutput (so some
+		 * just-works security cases can be tested) */
 		if (device_get_auth(device) != 0xff &&
-					(device_get_auth(device) & 0x01))
+					(device_get_auth(device) & 0x01) &&
+					agent_cap != 0x03)
 			*auth |= 0x01;
 	}
 
--- src/dbus-hci.h
+++ src/dbus-hci.h
@@ -45,6 +45,11 @@
 				uint8_t *key, uint8_t key_type,
 				int pin_length, uint8_t old_key_type);
 
+gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst,
+					struct btd_adapter **adapter,
+					struct btd_device **device,
+					gboolean create);
+
 DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status);
 
 const char *class_to_icon(uint32_t class);
--- src/device.c
+++ src/device.c
@@ -143,6 +143,9 @@
 
 	gboolean	authorizing;
 	gint		ref;
+
+	gboolean	has_debug_key;
+	uint8_t		debug_key[16];
 };
 
 static uint16_t uuid_list[] = {
@@ -574,9 +577,8 @@
 
 static inline DBusMessage *invalid_args(DBusMessage *msg)
 {
-	return g_dbus_create_error(msg,
-			ERROR_INTERFACE ".InvalidArguments",
-			"Invalid arguments in method call");
+	return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
+					"Invalid arguments in method call");
 }
 
 static DBusMessage *set_property(DBusConnection *conn,
@@ -1114,6 +1116,9 @@
 
 	DBG("Removing device %s", device->path);
 
+	if (device->agent)
+		agent_free(device->agent);
+
 	if (device->bonding)
 		device_cancel_bonding(device, HCI_OE_USER_ENDED_CONNECTION);
 
@@ -1268,12 +1273,6 @@
 						g_strdup(list->data),
 						(GCompareFunc) strcasecmp);
 	}
-
-	if (device->tmp_records) {
-		sdp_list_free(device->tmp_records,
-				(sdp_free_func_t) sdp_record_free);
-		device->tmp_records = NULL;
-	}
 }
 
 static void device_remove_drivers(struct btd_device *device, GSList *uuids)
@@ -1494,12 +1493,12 @@
 
 	update_services(req, recs);
 
-	if (device->tmp_records && req->records) {
+	if (device->tmp_records)
 		sdp_list_free(device->tmp_records,
 					(sdp_free_func_t) sdp_record_free);
-		device->tmp_records = req->records;
-		req->records = NULL;
-	}
+
+	device->tmp_records = req->records;
+	req->records = NULL;
 
 	if (!req->profiles_added && !req->profiles_removed) {
 		DBG("%s: No service update", device->path);
@@ -1523,7 +1522,7 @@
 
 	if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
 					"DiscoverServices"))
-		discover_services_reply(req, err, req->records);
+		discover_services_reply(req, err, device->tmp_records);
 	else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE,
 						"CreatePairedDevice"))
 		create_device_reply(device, req);
@@ -1677,15 +1676,10 @@
 	if (!device)
 		return NULL;
 
-	return  device->agent;
-}
-
-void device_set_agent(struct btd_device *device, struct agent *agent)
-{
-	if (!device)
-		return;
+	if (device->agent)
+		return device->agent;
 
-	device->agent = agent;
+	return adapter_get_agent(device->adapter);
 }
 
 gboolean device_is_busy(struct btd_device *device)
@@ -1853,7 +1847,7 @@
 {
 	struct btd_device *device = user_data;
 
-	device_set_agent(device, NULL);
+	device->agent = NULL;
 
 	if (device->authr)
 		device->authr->agent = NULL;
@@ -1907,7 +1901,7 @@
 		return FALSE;
 
 	reply = new_authentication_return(device->bonding->msg,
-					HCI_CONNECTION_TERMINATED);
+						HCI_CONNECTION_TERMINATED);
 	g_dbus_send_message(device->bonding->conn, reply);
 
 	bonding_request_free(device->bonding);
@@ -2032,6 +2026,7 @@
 	bdaddr_t src;
 	GError *err = NULL;
 	GIOChannel *io;
+	BtIOSecLevel sec_level;
 
 	adapter_get_address(adapter, &src);
 	ba2str(&src, srcaddr);
@@ -2052,12 +2047,19 @@
 				"Bonding already exists");
 	}
 
+	/* If our IO capability is NoInputNoOutput use medium security
+	 * level (i.e. don't require MITM protection) else use high
+	 * security level */
+	if (capability == 0x03)
+		sec_level = BT_IO_SEC_MEDIUM;
+	else
+		sec_level = BT_IO_SEC_HIGH;
 
 	io = bt_io_connect(BT_IO_L2RAW, bonding_connect_cb, device,
 				NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, &src,
 				BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
+				BT_IO_OPT_SEC_LEVEL, sec_level,
 				BT_IO_OPT_INVALID);
 	if (io == NULL) {
 		DBusMessage *reply;
@@ -2105,8 +2107,10 @@
 	if (auth && auth->type == AUTH_TYPE_NOTIFY && auth->agent)
 		agent_cancel(auth->agent);
 
-	if (status)
-		goto failed;
+	if (status) {
+		device_cancel_bonding(device, status);
+		return;
+	}
 
 	device->auth = 0xff;
 
@@ -2149,11 +2153,6 @@
 	}
 
 	device_set_paired(device, TRUE);
-
-	return;
-
-failed:
-	device_cancel_bonding(device, status);
 }
 
 gboolean device_is_creating(struct btd_device *device, const char *sender)
@@ -2212,8 +2211,8 @@
 	bonding_request_free(bonding);
 }
 
-static void pincode_cb(struct agent *agent, DBusError *err, const char *pincode,
-			void *data)
+static void pincode_cb(struct agent *agent, DBusError *err,
+					const char *pincode, void *data)
 {
 	struct authentication_req *auth = data;
 	struct btd_device *device = auth->device;
@@ -2243,8 +2242,8 @@
 	device->authr->agent = NULL;
 }
 
-static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey,
-			void *data)
+static void passkey_cb(struct agent *agent, DBusError *err,
+						uint32_t passkey, void *data)
 {
 	struct authentication_req *auth = data;
 	struct btd_device *device = auth->device;
@@ -2260,11 +2259,11 @@
 }
 
 int device_request_authentication(struct btd_device *device, auth_type_t type,
-				uint32_t passkey, void *cb)
+						uint32_t passkey, void *cb)
 {
 	struct authentication_req *auth;
 	struct agent *agent;
-	int ret;
+	int err;
 
 	DBG("%s: requesting agent authentication", device->path);
 
@@ -2287,34 +2286,34 @@
 
 	switch (type) {
 	case AUTH_TYPE_PINCODE:
-		ret = agent_request_pincode(agent, device, pincode_cb,
+		err = agent_request_pincode(agent, device, pincode_cb,
 								auth, NULL);
 		break;
 	case AUTH_TYPE_PASSKEY:
-		ret = agent_request_passkey(agent, device, passkey_cb,
+		err = agent_request_passkey(agent, device, passkey_cb,
 								auth, NULL);
 		break;
 	case AUTH_TYPE_CONFIRM:
-		ret = agent_request_confirmation(agent, device, passkey,
+		err = agent_request_confirmation(agent, device, passkey,
 						confirm_cb, auth, NULL);
 		break;
 	case AUTH_TYPE_NOTIFY:
-		ret = agent_display_passkey(agent, device, passkey);
+		err = agent_display_passkey(agent, device, passkey);
 		break;
 	case AUTH_TYPE_AUTO:
-		ret = 0;
+		err = 0;
 		break;
 	default:
-		ret = -EINVAL;
+		err = -EINVAL;
 	}
 
-	if (ret < 0) {
+	if (err < 0) {
 		error("Failed requesting authentication");
 		g_free(auth);
 		device->authr = NULL;
 	}
 
-	return ret;
+	return err;
 }
 
 static void cancel_authentication(struct authentication_req *auth)
@@ -2413,12 +2412,17 @@
 }
 
 const sdp_record_t *btd_device_get_record(struct btd_device *device,
-						const char *uuid)
+							const char *uuid)
 {
 	bdaddr_t src;
 
-	if (device->tmp_records)
-		return find_record_in_list(device->tmp_records, uuid);
+	if (device->tmp_records) {
+		const sdp_record_t *record;
+
+		record = find_record_in_list(device->tmp_records, uuid);
+		if (record != NULL)
+			return record;
+	}
 
 	adapter_get_address(device->adapter, &src);
 
@@ -2429,6 +2433,30 @@
 	return find_record_in_list(device->tmp_records, uuid);
 }
 
+gboolean device_set_debug_key(struct btd_device *device, uint8_t *key)
+{
+	if (key == NULL) {
+		device->has_debug_key = FALSE;
+		return TRUE;
+	}
+
+	memcpy(device->debug_key, key, 16);
+	device->has_debug_key = TRUE;
+
+	return TRUE;
+}
+
+gboolean device_get_debug_key(struct btd_device *device, uint8_t *key)
+{
+	if (!device->has_debug_key)
+		return FALSE;
+
+	if (key != NULL)
+		memcpy(key, device->debug_key, 16);
+
+	return TRUE;
+}
+
 int btd_register_device_driver(struct btd_device_driver *driver)
 {
 	device_drivers = g_slist_append(device_drivers, driver);
--- src/device.h
+++ src/device.h
@@ -50,7 +50,6 @@
 void device_get_address(struct btd_device *adapter, bdaddr_t *bdaddr);
 const gchar *device_get_path(struct btd_device *device);
 struct agent *device_get_agent(struct btd_device *device);
-void device_set_agent(struct btd_device *device, struct agent *agent);
 gboolean device_is_busy(struct btd_device *device);
 gboolean device_is_temporary(struct btd_device *device);
 gboolean device_is_paired(struct btd_device *device);
@@ -80,6 +79,8 @@
 gboolean device_is_authorizing(struct btd_device *device);
 void device_set_authorizing(struct btd_device *device, gboolean auth);
 void device_set_renewed_key(struct btd_device *device, gboolean renewed);
+gboolean device_set_debug_key(struct btd_device *device, uint8_t *key);
+gboolean device_get_debug_key(struct btd_device *device, uint8_t *key);
 void device_add_connection(struct btd_device *device, DBusConnection *conn,
 				uint16_t handle);
 void device_remove_connection(struct btd_device *device, DBusConnection *conn,
--- src/hcid.h
+++ src/hcid.h
@@ -60,6 +60,7 @@
 	gboolean	remember_powered;
 	gboolean	reverse_sdp;
 	gboolean	name_resolv;
+	gboolean	debug_keys;
 
 	uint8_t		scan;
 	uint8_t		mode;
--- src/log.c
+++ src/log.c
@@ -33,18 +33,13 @@
 
 #include "log.h"
 
-static inline void vinfo(const char *format, va_list ap)
-{
-	vsyslog(LOG_INFO, format, ap);
-}
-
 void info(const char *format, ...)
 {
 	va_list ap;
 
 	va_start(ap, format);
 
-	vinfo(format, ap);
+	vsyslog(LOG_INFO, format, ap);
 
 	va_end(ap);
 }
@@ -60,7 +55,7 @@
 	va_end(ap);
 }
 
-void debug(const char *format, ...)
+void btd_debug(const char *format, ...)
 {
 	va_list ap;
 
@@ -95,6 +90,14 @@
         return 0;
 }
 
+void __btd_toggle_debug()
+{
+	struct btd_debug_desc *desc;
+
+	for (desc = __start___debug; desc < __stop___debug; desc++)
+		desc->flags |= BTD_DEBUG_FLAG_PRINT;
+}
+
 void __btd_log_init(const char *debug, int detach)
 {
 	int option = LOG_NDELAY | LOG_PID;
--- src/log.h
+++ src/log.h
@@ -21,15 +21,14 @@
  *
  */
 
-#ifndef __LOGGING_H
-#define __LOGGING_H
-
 void info(const char *format, ...) __attribute__((format(printf, 1, 2)));
 void error(const char *format, ...) __attribute__((format(printf, 1, 2)));
-void debug(const char *format, ...) __attribute__((format(printf, 1, 2)));
+
+void btd_debug(const char *format, ...) __attribute__((format(printf, 1, 2)));
 
 void __btd_log_init(const char *debug, int detach);
 void __btd_log_cleanup(void);
+void __btd_toggle_debug();
 
 struct btd_debug_desc {
         const char *name;
@@ -44,7 +43,7 @@
  * @fmt: format string
  * @arg...: list of arguments
  *
- * Simple macro around debug() which also include the function
+ * Simple macro around btd_debug() which also include the function
  * name it is called in.
  */
 #define DBG(fmt, arg...) do { \
@@ -53,8 +52,7 @@
                 .file = __FILE__, .flags = BTD_DEBUG_FLAG_DEFAULT, \
         }; \
         if (__btd_debug_desc.flags & BTD_DEBUG_FLAG_PRINT) \
-                debug("%s:%s() " fmt, \
+                btd_debug("%s:%s() " fmt, \
                                         __FILE__, __FUNCTION__ , ## arg); \
 } while (0)
 
-#endif /* __LOGGING_H */
--- src/main.c
+++ src/main.c
@@ -201,6 +201,13 @@
 	else
 		main_opts.name_resolv = boolean;
 
+	boolean = g_key_file_get_boolean(config, "General",
+						"DebugKeys", &err);
+	if (err)
+		g_clear_error(&err);
+	else
+		main_opts.debug_keys = boolean;
+
 	main_opts.link_mode = HCI_LM_ACCEPT;
 
 	main_opts.link_policy = HCI_LP_RSWITCH | HCI_LP_SNIFF |
@@ -288,6 +295,11 @@
 	g_main_loop_quit(event_loop);
 }
 
+static void sig_debug(int sig)
+{
+	__btd_toggle_debug();
+}
+
 static gchar *option_debug = NULL;
 static gboolean option_detach = TRUE;
 static gboolean option_udev = FALSE;
@@ -406,6 +418,9 @@
 	sigaction(SIGTERM, &sa, NULL);
 	sigaction(SIGINT,  &sa, NULL);
 
+	sa.sa_handler = sig_debug;
+	sigaction(SIGUSR2, &sa, NULL);
+
 	sa.sa_handler = SIG_IGN;
 	sigaction(SIGPIPE, &sa, NULL);
 
--- src/main.conf
+++ src/main.conf
@@ -50,3 +50,8 @@
 # Enable name resolving after inquiry. Set it to 'false' if you don't need
 # remote devices name and want shorter discovery cycle. Defaults to 'true'.
 NameResolving = true
+
+# Enable runtime persistency of debug link keys. Default is false which
+# makes debug link keys valid only for the duration of the connection
+# that they were created for.
+DebugKeys = false
--- src/manager.c
+++ src/manager.c
@@ -116,8 +116,8 @@
 							DBUS_TYPE_INVALID))
 		return NULL;
 
-	/* hci_devid() would make sense to use here, except it
-	   is restricted to devices which are up */
+	/* hci_devid() would make sense to use here, except it is
+	 * restricted to devices which are up */
 	if (!strcmp(pattern, "any") || !strcmp(pattern, "00:00:00:00:00:00")) {
 		path = adapter_any_get_path();
 		if (path != NULL)
@@ -237,8 +237,8 @@
 	snprintf(base_path, sizeof(base_path), "/org/bluez/%d", getpid());
 
 	return g_dbus_register_interface(conn, "/", MANAGER_INTERFACE,
-			manager_methods, manager_signals,
-			NULL, NULL, NULL);
+					manager_methods, manager_signals,
+					NULL, NULL, NULL);
 }
 
 static void manager_update_adapters(void)
@@ -377,7 +377,8 @@
 {
 	GSList *match;
 
-	match = g_slist_find_custom(adapters, GINT_TO_POINTER(id), adapter_id_cmp);
+	match = g_slist_find_custom(adapters, GINT_TO_POINTER(id),
+							adapter_id_cmp);
 	if (!match)
 		return NULL;
 
@@ -392,9 +393,9 @@
 void manager_add_adapter(const char *path)
 {
 	g_dbus_emit_signal(connection, "/",
-			MANAGER_INTERFACE, "AdapterAdded",
-			DBUS_TYPE_OBJECT_PATH, &path,
-			DBUS_TYPE_INVALID);
+				MANAGER_INTERFACE, "AdapterAdded",
+				DBUS_TYPE_OBJECT_PATH, &path,
+				DBUS_TYPE_INVALID);
 
 	manager_update_adapters();
 
--- src/sdp-xml.c
+++ src/sdp-xml.c
@@ -728,12 +728,8 @@
 	if (elem->data)
 		sdp_data_free(elem->data);
 
-	if (elem->name)
-		free(elem->name);
-
-	if (elem->text)
-
-		free(elem->text);
+	free(elem->name);
+	free(elem->text);
 	free(elem);
 }
 
--- src/sdpd-request.c
+++ src/sdpd-request.c
@@ -526,8 +526,7 @@
 	}
 
 done:
-	if (cstate)
-		free(cstate);
+	free(cstate);
 	if (pattern)
 		sdp_list_free(pattern, free);
 
@@ -745,8 +744,7 @@
 	buf->buf_size += sizeof(uint16_t);
 
 done:
-	if (cstate)
-		free(cstate);
+	free(cstate);
 	if (seq)
 		sdp_list_free(seq, free);
 	if (status)
@@ -929,10 +927,8 @@
 	}
 
 done:
-	if (cstate)
-		free(cstate);
-	if (tmpbuf.data)
-		free(tmpbuf.data);
+	free(cstate);
+	free(tmpbuf.data);
 	if (pattern)
 		sdp_list_free(pattern, free);
 	if (seq)
--- src/security.c
+++ src/security.c
@@ -51,6 +51,7 @@
 #include "textfile.h"
 
 #include "adapter.h"
+#include "device.h"
 #include "dbus-hci.h"
 #include "storage.h"
 #include "manager.h"
@@ -126,7 +127,8 @@
 
 	do {
 		struct hci_req_data *data;
-		GSList *l = g_slist_find_custom(hci_req_queue, &dev_id, hci_req_find_by_devid);
+		GSList *l = g_slist_find_custom(hci_req_queue, &dev_id,
+							hci_req_find_by_devid);
 
 		if (!l)
 			break;
@@ -134,7 +136,8 @@
 		data = l->data;
 		data->status = REQ_SENT;
 
-		ret_val = hci_send_cmd(dd, data->ogf, data->ocf, data->clen, data->cparam);
+		ret_val = hci_send_cmd(dd, data->ogf, data->ocf,
+						data->clen, data->cparam);
 		if (ret_val < 0) {
 			hci_req_queue = g_slist_remove(hci_req_queue, data);
 			g_free(data->cparam);
@@ -151,10 +154,10 @@
 	GSList *l;
 	struct hci_req_data *match;
 
-
 	hci_req_queue = g_slist_append(hci_req_queue, data);
 
-	l = g_slist_find_custom(hci_req_queue, &data->dev_id, hci_req_find_by_devid);
+	l = g_slist_find_custom(hci_req_queue, &data->dev_id,
+							hci_req_find_by_devid);
 	match = l->data;
 
 	if (match->status == REQ_SENT)
@@ -299,12 +302,17 @@
 
 static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba)
 {
+	struct btd_adapter *adapter;
+	struct btd_device *device;
 	struct hci_auth_info_req req;
 	unsigned char key[16];
 	char sa[18], da[18];
 	uint8_t type;
 	int err;
 
+	if (!get_adapter_and_device(sba, dba, &adapter, &device, FALSE))
+		device = NULL;
+
 	ba2str(sba, sa); ba2str(dba, da);
 	info("link_key_request (sba=%s, dba=%s)", sa, da);
 
@@ -321,26 +329,30 @@
 
 	DBG("kernel auth requirements = 0x%02x", req.type);
 
-	err = read_link_key(sba, dba, key, &type);
-	if (err < 0) {
+	if (main_opts.debug_keys && device && device_get_debug_key(device, key))
+		type = 0x03;
+	else if (read_link_key(sba, dba, key, &type) < 0 || type == 0x03) {
 		/* Link key not found */
 		hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba);
-	} else {
-		/* Link key found */
+		return;
+	}
+
+	/* Link key found */
+
+	DBG("link key type = 0x%02x", type);
+
+	/* Don't use unauthenticated combination keys if MITM is
+	 * required */
+	if (type == 0x04 && req.type != 0xff && (req.type & 0x01))
+		hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY,
+								6, dba);
+	else {
 		link_key_reply_cp lr;
+
 		memcpy(lr.link_key, key, 16);
 		bacpy(&lr.bdaddr, dba);
 
-		DBG("stored link key type = 0x%02x", type);
-
-		/* Don't use debug link keys (0x03) and also don't use
-		 * unauthenticated combination keys if MITM is required */
-		if (type == 0x03 || (type == 0x04 && req.type != 0xff &&
-							(req.type & 0x01)))
-			hci_send_cmd(dev, OGF_LINK_CTL,
-					OCF_LINK_KEY_NEG_REPLY, 6, dba);
-		else
-			hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY,
+		hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY,
 						LINK_KEY_REPLY_CP_SIZE, &lr);
 	}
 }
@@ -769,7 +781,8 @@
 	}
 }
 
-static inline void inquiry_result_with_rssi(int dev, bdaddr_t *sba, int plen, void *ptr)
+static inline void inquiry_result_with_rssi(int dev, bdaddr_t *sba,
+							int plen, void *ptr)
 {
 	uint8_t num = *(uint8_t *) ptr++;
 	int i;
@@ -808,7 +821,8 @@
 	}
 }
 
-static inline void extended_inquiry_result(int dev, bdaddr_t *sba, int plen, void *ptr)
+static inline void extended_inquiry_result(int dev, bdaddr_t *sba,
+							int plen, void *ptr)
 {
 	uint8_t num = *(uint8_t *) ptr++;
 	int i;
@@ -828,7 +842,8 @@
 	}
 }
 
-static inline void remote_features_information(int dev, bdaddr_t *sba, void *ptr)
+static inline void remote_features_information(int dev, bdaddr_t *sba,
+								void *ptr)
 {
 	evt_read_remote_features_complete *evt = ptr;
 	bdaddr_t dba;
@@ -867,7 +882,8 @@
 	cp_name.pscan_rep_mode = 0x02;
 
 	data = hci_req_data_new(dev_id, &evt->bdaddr, OGF_LINK_CTL,
-				OCF_REMOTE_NAME_REQ, EVT_REMOTE_NAME_REQ_COMPLETE,
+				OCF_REMOTE_NAME_REQ,
+				EVT_REMOTE_NAME_REQ_COMPLETE,
 				&cp_name, REMOTE_NAME_REQ_CP_SIZE);
 
 	hci_req_queue_append(data);
@@ -876,7 +892,8 @@
 	ba2str(sba, local_addr);
 	ba2str(&evt->bdaddr, peer_addr);
 
-	create_name(filename, sizeof(filename), STORAGEDIR, local_addr, "manufacturers");
+	create_name(filename, sizeof(filename), STORAGEDIR, local_addr,
+							"manufacturers");
 
 	str = textfile_get(filename, peer_addr);
 	if (!str) {
@@ -886,7 +903,8 @@
 		cp.handle = evt->handle;
 
 		data = hci_req_data_new(dev_id, &evt->bdaddr, OGF_LINK_CTL,
-					OCF_READ_REMOTE_VERSION, EVT_READ_REMOTE_VERSION_COMPLETE,
+					OCF_READ_REMOTE_VERSION,
+					EVT_READ_REMOTE_VERSION_COMPLETE,
 					&cp, READ_REMOTE_VERSION_CP_SIZE);
 
 		hci_req_queue_append(data);
@@ -945,7 +963,8 @@
 	error("IO channel not found in the io_data table");
 }
 
-static gboolean io_security_event(GIOChannel *chan, GIOCondition cond, gpointer data)
+static gboolean io_security_event(GIOChannel *chan, GIOCondition cond,
+								gpointer data)
 {
 	unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr = buf;
 	struct hci_dev_info *di = data;
--- src/storage.c
+++ src/storage.c
@@ -763,8 +763,7 @@
 	/* If the old setting is the same as the requested one, we're done */
 	if (trusted == trust) {
 		g_slist_free(services);
-		if (str)
-			free(str);
+		free(str);
 		return 0;
 	}
 
@@ -784,8 +783,7 @@
 
 	g_slist_free(services);
 
-	if (str)
-		free(str);
+	free(str);
 
 	return ret;
 }
--- test/ipctest.c
+++ test/ipctest.c
@@ -1029,8 +1029,7 @@
 		if (sscanf(line, "%*s %as", &address) != 1)
 			DBG("set with bdaddr BDADDR");
 
-		if (u->address)
-			free(u->address);
+		free(u->address);
 
 		u->address = address;
 		DBG("bdaddr %s", u->address);
@@ -1049,8 +1048,7 @@
 			DBG("set with profile [hsp|a2dp]");
 		}
 
-		if (profile)
-			free(profile);
+		free(profile);
 		DBG("profile %s", u->transport == BT_CAPABILITIES_TRANSPORT_SCO ?
 			"hsp" : "a2dp");
 	}
--- test/test-device
+++ test/test-device
@@ -22,6 +22,7 @@
 	print "  name <address>"
 	print "  alias <address> [alias]"
 	print "  trusted <address> [yes/no]"
+	print "  blocked <address> [yes/no]"
 	sys.exit(1)
 
 if (sys.argv[1] == "list"):
--- tools/sdptool.c
+++ tools/sdptool.c
@@ -322,9 +322,9 @@
 	{ 0x1303, "VideoSource", NULL, 0 },
 	{ 0x1304, "VideoSink", NULL, 0 },
 	{ 0x1305, "VideoDistribution", NULL, 0 },
-	{ 0x1400, "MDP", NULL, 0 },
-	{ 0x1401, "MDPSource", NULL, 0 },
-	{ 0x1402, "MDPSink", NULL, 0 },
+	{ 0x1400, "HDP", NULL, 0 },
+	{ 0x1401, "HDPSource", NULL, 0 },
+	{ 0x1402, "HDPSink", NULL, 0 },
 	{ 0x2112, "AppleAgent", NULL, 0 },
 };
 
@@ -513,14 +513,16 @@
  */
 static void print_tree_attr_func(void *value, void *userData)
 {
-	sdp_data_t *sdpdata = NULL;
+	sdp_data_t *sdpdata = value;
 	uint16_t attrId;
 	struct service_context *service = (struct service_context *) userData;
 	struct attrib_context context;
 	struct attrib_def *attrDef = NULL;
 	int i;
 
-	sdpdata = (sdp_data_t *)value;
+	if (!sdpdata)
+		return;
+
 	attrId = sdpdata->attrId;
 	/* Search amongst the generic attributes */
 	for (i = 0; i < attrib_max; i++)
@@ -549,10 +551,7 @@
 	context.attrib = attrDef;
 	context.member_index = 0;
 	/* Parse attribute members */
-	if (sdpdata)
-		sdp_data_printf(sdpdata, &context, 2);
-	else
-		printf("  NULL value\n");
+	sdp_data_printf(sdpdata, &context, 2);
 	/* Update service */
 	service->service = context.service;
 }
@@ -723,6 +722,9 @@
 	struct attrib_def *def = NULL;
 	int i;
 
+	if (!data)
+		return;
+
 	/* Search amongst the generic attributes */
 	for (i = 0; i < attrib_max; i++)
 		if (attrib_names[i].num == data->attrId) {
@@ -735,10 +737,7 @@
 	else
 		printf("\tAttribute 0x%04x\n", data->attrId);
 
-	if (data)
-		print_raw_data(data, 2);
-	else
-		printf("  NULL value\n");
+	print_raw_data(data, 2);
 }
 
 static void print_raw_attr(sdp_record_t *rec)

++++++ bluez.yaml (new)
--- bluez.yaml
+++ bluez.yaml
+Name: bluez
+Summary: Bluetooth utilities
+Version: 4.66
+Release: 1
+Group: Applications/System
+License: GPLv2+
+URL: http://www.bluez.org/
+Sources:
+    - http://www.kernel.org/pub/linux/bluetooth/%{name}-%{version}.tar.gz
+    - bluetooth.init
+Patches:
+    - bluez-fsync.patch
+    - remove-duplicate-wrong-udev-rule-for-dell-mice.patch
+    - enable_HFP.patch
+    - set_RememberPowered_as_false.patch
+Description: |
+    Utilities for use in Bluetooth applications:
+    	--ciptool
+    	--dfutool
+    	--hcitool
+    	--l2ping
+    	--rfcomm
+    	--sdptool
+    	--hciattach
+    	--hciconfig
+    	--hid2hci
+    
+    The BLUETOOTH trademarks are owned by Bluetooth SIG, Inc., U.S.A.
+
+Requires:
+    - fastinit
+    - bluez-libs = %{version}
+    - dbus >= 0.60
+    - hwdata >= 0.215
+    - ofono >= 0.2
+RequiresPreUn:
+    - /sbin/chkconfig
+    - /sbin/service
+RequiresPost:
+    - /sbin/chkconfig
+    - /sbin/service
+
+PkgConfigBR:
+    - dbus-1
+    - libusb
+    - alsa
+    - sndfile
+
+PkgBR:
+    - flex
+    - glib2-devel
+    - gst-plugins-base-devel
+    - gstreamer-devel
+Configure: reconfigure
+ConfigOptions:
+    - --enable-cups
+    - --enable-hid2hci
+    - --enable-dfutool
+    - --enable-bccmd
+    - --enable-hidd
+    - --enable-pand
+    - --enable-dund
+    - --enable-gstreamer
+    - --enable-alsa
+    - --enable-usb
+    - --enable-tools
+    - --with-telephony=dummy
+Builder: make
+SubPackages:
+    - Name: libs
+      Summary: Libraries for use in Bluetooth applications
+      Group: System/Libraries
+      Description: Libraries for use in Bluetooth applications.
+
+    - Name: libs-devel
+      Summary: Development libraries for Bluetooth applications
+      Group: Development/Libraries
+      Description: |
+          bluez-libs-devel contains development libraries and headers for
+          use in Bluetooth applications.
+      Requires:
+          - bluez-libs = %{version}
+
+    - Name: cups
+      Summary: CUPS printer backend for Bluetooth printers
+      Group: System/Daemons
+      Description: This package contains the CUPS backend
+      Requires:
+          - bluez-libs = %{version}
+          - cups
+
+    - Name: alsa
+      Summary: ALSA support for Bluetooth audio devices
+      Group: System/Daemons
+      Description: This package contains ALSA support for Bluetooth audio devices
+      Requires:
+          - bluez-libs = %{version}
+
+    - Name: gstreamer
+      Summary: GStreamer support for SBC audio format
+      Group: System/Daemons
+      Description: This package contains gstreamer plugins for the Bluetooth SBC audio format
+      Requires:
+          - bluez-libs = %{version}
+

++++++ deleted files:
--- correct-ref.patch



More information about the MeeGo-commits mailing list