mgmt: Add support for auth_failed event and bonding_complete hooks

This patch adds support for the mgmt_auth_failed event together with the
related bonding_complete failure hooks to the core daemon.
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index 455c1b1..2add44f 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -431,3 +431,12 @@
 Event Parameters	Controller_Index (2 Octets)
 			Address (6 Octets)
 			Value (4 Octets)
+
+
+Authentication Failed Event
+===========================
+
+Event Code		0x0010
+Event Parameters	Controller_Index (2 Octets)
+			Address (6 Octets)
+			Status (1 Octet)
diff --git a/lib/mgmt.h b/lib/mgmt.h
index 158e8a3..b3eabac 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -268,3 +268,10 @@
 	bdaddr_t bdaddr;
 	uint32_t value;
 } __packed;
+
+#define MGMT_EV_AUTH_FAILED		0x0010
+struct mgmt_ev_auth_failed {
+	uint16_t index;
+	bdaddr_t bdaddr;
+	uint8_t status;
+} __packed;
diff --git a/plugins/mgmtops.c b/plugins/mgmtops.c
index 63b6cf2..36b6e98 100644
--- a/plugins/mgmtops.c
+++ b/plugins/mgmtops.c
@@ -451,6 +451,8 @@
 	btd_event_link_key_notify(&info->bdaddr, &ev->key.bdaddr,
 					ev->key.val, ev->key.type,
 					ev->key.pin_len);
+
+	btd_event_bonding_complete(&info->bdaddr, &ev->key.bdaddr, 0);
 }
 
 static void mgmt_device_connected(int sk, void *buf, size_t len)
@@ -532,6 +534,9 @@
 	info = &controllers[index];
 
 	btd_event_conn_failed(&info->bdaddr, &ev->bdaddr, ev->status);
+
+	/* In the case of security mode 3 devices */
+	btd_event_bonding_complete(&info->bdaddr, &ev->bdaddr, ev->status);
 }
 
 static int mgmt_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin)
@@ -992,6 +997,9 @@
 	info = &controllers[index];
 
 	btd_event_disconn_complete(&info->bdaddr, &rp->bdaddr);
+
+	btd_event_bonding_complete(&info->bdaddr, &rp->bdaddr,
+						HCI_CONNECTION_TERMINATED);
 }
 
 static void pair_device_complete(int sk, void *buf, size_t len)
@@ -1162,6 +1170,31 @@
 	DBG("index %u error_code %u", index, ev->error_code);
 }
 
+static void mgmt_auth_failed(int sk, void *buf, size_t len)
+{
+	struct controller_info *info;
+	struct mgmt_ev_auth_failed *ev = buf;
+	uint16_t index;
+
+	if (len < sizeof(*ev)) {
+		error("Too small mgmt_auth_failed event packet");
+		return;
+	}
+
+	index = btohs(bt_get_unaligned(&ev->index));
+
+	DBG("hci%u auth failed status %u", index, ev->status);
+
+	if (index > max_index) {
+		error("Unexpected index %u in auth_failed event", index);
+		return;
+	}
+
+	info = &controllers[index];
+
+	btd_event_bonding_complete(&info->bdaddr, &ev->bdaddr, ev->status);
+}
+
 static gboolean mgmt_event(GIOChannel *io, GIOCondition cond, gpointer user_data)
 {
 	char buf[MGMT_BUF_SIZE];
@@ -1250,6 +1283,9 @@
 	case MGMT_EV_USER_CONFIRM_REQUEST:
 		mgmt_user_confirm_request(sk, buf + MGMT_HDR_SIZE, len);
 		break;
+	case MGMT_EV_AUTH_FAILED:
+		mgmt_auth_failed(sk, buf + MGMT_HDR_SIZE, len);
+		break;
 	default:
 		error("Unknown Management opcode %u", opcode);
 		break;