diff --git a/lib/include/btdevice.h b/lib/include/btdevice.h
index 260ed867b70a24b6ba7ce49c33b9c25da9a12c64..bbd37fafdc1896e539e52b9f3053868451c4c30d 100644
--- a/lib/include/btdevice.h
+++ b/lib/include/btdevice.h
@@ -26,6 +26,8 @@ namespace statemachine
 	struct pairing_done;
 	struct pairing_failed;
 	struct connecting;
+	struct pin_code_request;
+	struct link_key_notification;
 }
 
 /*
@@ -115,6 +117,8 @@ public:
 	friend struct statemachine::pairing_done;
 	friend struct statemachine::pairing_failed;
 	friend struct statemachine::connecting;
+	friend struct statemachine::pin_code_request;
+	friend struct statemachine::link_key_notification;
 
 	/*
 	 * Create a device with specific device info. addr is the only
@@ -320,8 +324,6 @@ private:
 	{
 		CONNECT,
 		PAIR,
-		AUTH_SUCCESSFUL,
-		AUTH_FAILED,
 		LINK_KEY_REQUEST,
 		PIN_REQUEST,
 		IO_CAPABILITY_REQUEST_REPLY_SUCCEEDED,
diff --git a/lib/src/btdevice.cpp b/lib/src/btdevice.cpp
index 8381f4e064a9e3a3b668a564a5000f71c7bfa46a..5ce6c7f0daef9930943726a639cf8e9284a0c138 100644
--- a/lib/src/btdevice.cpp
+++ b/lib/src/btdevice.cpp
@@ -252,12 +252,21 @@ void btdevice::encryption_change(bool success, bool enabled)
 	if (success)
 	{
 		if (enabled)
+		{
 			syslog(LOG_DEBUG, "Encryption enabled for %s", s_addr.c_str());
+			sm->process_event(sm::event_encryption_enabled());
+		}
 		else
+		{
 			syslog(LOG_DEBUG, "Encryption disabled for %s", s_addr.c_str());
+			sm->process_event(sm::event_encryption_disabled());
+		}
 	}
 	else
+	{
 		syslog(LOG_ERR, "Encryption change failed for %s", s_addr.c_str());
+		sm->process_event(sm::event_encryption_disabled());
+	}
 }
 
 void btdevice::neg_link_key_reply(bool success)
@@ -349,9 +358,10 @@ void btdevice::link_key_notification(blue::key new_link_key)
 	if (paired || current_state == device_state::PAIRING)
 	{
 		link_key = new_link_key;
-		enable_encryption();
 	}
 
+	sm->process_event(sm::event_link_key_notification());
+
 	emit_event<&device_observer::link_key_notification>(*this);
 
 	emit_event<&device_observer::device_event>(*this,
@@ -446,9 +456,9 @@ void btdevice::user_confirmation_request_negative_reply(bool success)
 void btdevice::auth_compl(bool success)
 {
 	if (success)
-		process_state(device_event::AUTH_SUCCESSFUL);
+		sm->process_event(sm::event_auth_successful());
 	else
-		process_state(device_event::AUTH_FAILED);
+		sm->process_event(sm::event_auth_failed());
 
 	emit_event<&device_observer::device_event>(*this,
 			NG_HCI_EVENT_AUTH_COMPL, success);
@@ -456,7 +466,7 @@ void btdevice::auth_compl(bool success)
 
 void btdevice::pin_code_req()
 {
-	process_state(device_event::PIN_REQUEST);
+	sm->process_event(sm::event_pin_code_request());
 }
 
 void btdevice::remote_name(bool success, std::string name)
@@ -499,20 +509,12 @@ void btdevice::process_state(device_event event)
 			current_state = device_state::PAIRING;
 			sm->process_event(sm::event_start_pairing());
 			break;
-		case device_event::AUTH_SUCCESSFUL:
-			sm->process_event(sm::event_auth_successful());
-			break;
-		case device_event::AUTH_FAILED:
-			break;
 		case device_event::LINK_KEY_REQUEST:
 			if (current_state == device_state::PAIRING)
 				sm->process_event(sm::event_link_key_request());
 			else
 				socket->send_link_key_reply(this, addr, link_key);
 			break;
-		case device_event::PIN_REQUEST:
-			socket->send_pin_code_reply(this, addr, pin);
-			break;
 		case device_event::IO_CAPABILITY_REQUEST_REPLY_SUCCEEDED:
 			syslog(LOG_DEBUG, "%s: io_capability_request_reply succeeded",
 				   addr.str().c_str());
diff --git a/lib/src/btdevice_statemachine.h b/lib/src/btdevice_statemachine.h
index d3fba4a3cc5dafa7dc5d362b451f2791e189156f..b1241dcd2964341a405cb9d1f0fc910c10aaaea2 100644
--- a/lib/src/btdevice_statemachine.h
+++ b/lib/src/btdevice_statemachine.h
@@ -51,7 +51,6 @@ struct event_connect : sc::event<event_connect> {};
 struct event_connect_failed : sc::event<event_connect_failed> {};
 struct event_connect_successful : sc::event<event_connect_successful> {};
 struct event_send_auth_request : sc::event<event_send_auth_request> {};
-struct event_auth_request_failed : sc::event<event_auth_request_failed> {};
 struct event_link_key_request : sc::event<event_link_key_request> {};
 struct event_link_key_neg_rep_failed :
 	sc::event<event_link_key_neg_rep_failed> {};
@@ -69,7 +68,12 @@ struct event_secure_simple_pairing_failed :
 struct event_pairing_done : sc::event<event_pairing_done> {};
 struct event_done : sc::event<event_done> {};
 struct event_auth_successful : sc::event<event_auth_successful> {};
+struct event_auth_failed : sc::event<event_auth_failed> {};
 struct event_disconnected : sc::event<event_disconnected> {};
+struct event_pin_code_request : sc::event<event_pin_code_request> {};
+struct event_link_key_notification : sc::event<event_link_key_notification> {};
+struct event_encryption_enabled : sc::event<event_encryption_enabled> {};
+struct event_encryption_disabled : sc::event<event_encryption_disabled> {};
 
 /*
  * State machine definition
@@ -132,10 +136,13 @@ struct requesting_auth;
 struct link_key_request;
 struct io_capability_request;
 struct user_confirmation_request;
+struct pairing_enable_encryption;
 struct pairing_done;
 struct pairing_failed;
 struct enable_encryption;
 struct connecting;
+struct pin_code_request;
+struct link_key_notification;
 
 struct normal : sc::state<normal, btdevice_sm, idle>, state_logger
 {
@@ -226,7 +233,7 @@ struct pairing_connecting : sc::state<pairing_connecting, pairing>, state_logger
 struct requesting_auth : sc::state<requesting_auth, pairing>, state_logger
 {
 	typedef mpl::list<
-		sc::transition<event_auth_request_failed, pairing_failed>,
+		sc::transition<event_auth_failed, pairing_failed>,
 		sc::transition<event_link_key_request, link_key_request>> reactions;
 
 	requesting_auth(my_context ctx) : my_base(ctx),
@@ -241,8 +248,8 @@ struct link_key_request : sc::state<link_key_request, pairing>,
 {
 	typedef mpl::list<
 		sc::transition<event_link_key_neg_rep_failed, pairing_failed>,
-		sc::transition<event_io_capability_request, io_capability_request>>
-			reactions;
+		sc::transition<event_io_capability_request, io_capability_request>,
+		sc::transition<event_pin_code_request, pin_code_request>> reactions;
 
 	link_key_request(my_context ctx) : my_base(ctx),
 		state_logger(ctx_device(), "link_key_request")
@@ -251,6 +258,30 @@ struct link_key_request : sc::state<link_key_request, pairing>,
 	}
 };
 
+struct pin_code_request : sc::state<pin_code_request, pairing>,
+	state_logger
+{
+	typedef sc::transition<event_link_key_notification,
+	                       pairing_enable_encryption> reactions;
+
+	pin_code_request(my_context ctx) : my_base(ctx),
+		state_logger(ctx_device(), "pin_code_request")
+	{
+		btdevice &d = ctx_device();
+		d.socket->send_pin_code_reply(&d, d.addr, d.pin);
+	}
+};
+
+struct link_key_notification : sc::state<link_key_notification, pairing>,
+	state_logger
+{
+	link_key_notification(my_context ctx) : my_base(ctx),
+		state_logger(ctx_device(), "link_key_notification")
+	{
+		post_event(event_pairing_done());
+	}
+};
+
 struct io_capability_request : sc::state<io_capability_request, pairing>,
 	state_logger
 {
@@ -273,7 +304,8 @@ struct user_confirmation_request :
 	typedef mpl::list<
 		sc::transition<event_user_confirmation_request_reply_failed,
 		               pairing_failed>,
-		sc::transition<event_secure_simple_pairing_successful, pairing_done>,
+		sc::transition<event_secure_simple_pairing_successful,
+		               pairing_enable_encryption>,
 		sc::transition<event_secure_simple_pairing_failed, pairing_failed>>
 			reactions;
 
@@ -284,6 +316,20 @@ struct user_confirmation_request :
 	}
 };
 
+struct pairing_enable_encryption :
+	sc::state<pairing_enable_encryption, pairing>,
+	state_logger
+{
+	typedef mpl::list<
+		sc::transition<event_encryption_enabled, pairing_done>,
+		sc::transition<event_encryption_disabled, pairing_failed>> reactions;
+
+	pairing_enable_encryption(my_context ctx) : my_base(ctx),
+		state_logger(ctx_device(), "pairing_enable_encryption")
+	{
+		ctx_device().enable_encryption();
+	}
+};
 struct pairing_done :
 	sc::state<pairing_done, pairing>,
 	state_logger
diff --git a/lib/src/hci_socket.cpp b/lib/src/hci_socket.cpp
index ced8493aa72248335d3a0c71714b60da45820885..d2426848639553b449db956fa4bfa7770b2cf98f 100644
--- a/lib/src/hci_socket.cpp
+++ b/lib/src/hci_socket.cpp
@@ -170,7 +170,7 @@ void hci_socket::enable_simple_pairing()
 	// enabled before secure connection support.
 	ng_hci_write_simple_pairing_cp cp;
 
-	cp.simple_pairing = 1;
+	cp.simple_pairing = 0;
 
 	hci_cmd(
 		NG_HCI_OPCODE(NG_HCI_OGF_HC_BASEBAND, NG_HCI_OCF_WRITE_SIMPLE_PAIRING),