diff --git a/lib/include/btdevice.h b/lib/include/btdevice.h index 83acdd89915ec66a28eaefceb4d9b85e086c3765..260ed867b70a24b6ba7ce49c33b9c25da9a12c64 100644 --- a/lib/include/btdevice.h +++ b/lib/include/btdevice.h @@ -20,6 +20,7 @@ class btdevice; namespace statemachine { struct btdevice_sm; + struct disconnected; struct idle; struct pairing_connecting; struct pairing_done; @@ -108,6 +109,7 @@ public: * pairing_finished(). */ friend struct statemachine::btdevice_sm; + friend struct statemachine::disconnected; friend struct statemachine::idle; friend struct statemachine::pairing_connecting; friend struct statemachine::pairing_done; @@ -322,7 +324,6 @@ private: AUTH_FAILED, LINK_KEY_REQUEST, PIN_REQUEST, - DISCONNECT_COMPLETED, IO_CAPABILITY_REQUEST_REPLY_SUCCEEDED, IO_CAPABILITY_REQUEST_REPLY_FAILED, USER_CONFIRMATION_REQUEST_REPLY_SUCCEEDED, diff --git a/lib/src/btdevice.cpp b/lib/src/btdevice.cpp index d1fd16039e66ed777189d1c6b9b98badcbedb5b3..8381f4e064a9e3a3b668a564a5000f71c7bfa46a 100644 --- a/lib/src/btdevice.cpp +++ b/lib/src/btdevice.cpp @@ -329,7 +329,7 @@ void btdevice::con_compl(bool success, uint16_t handle) void btdevice::discon_compl(bool success) { if (success) - process_state(device_event::DISCONNECT_COMPLETED); + sm->process_event(sm::event_disconnected()); emit_event<&device_observer::device_event>(*this, NG_HCI_EVENT_DISCON_COMPL, success); @@ -513,18 +513,6 @@ void btdevice::process_state(device_event event) case device_event::PIN_REQUEST: socket->send_pin_code_reply(this, addr, pin); break; - case device_event::DISCONNECT_COMPLETED: - connected = false; - con_handle = INVALID_HANDLE; - if (current_state == device_state::PAIRING) - { - // If we disconnect during pairing, reset the state - // machine by overwriting it with a new one. - sm = std::make_unique<sm::btdevice_sm>(*this); - sm->initiate(); - pairing_finished(false); - } - 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 d5dba92d0ddeb9a04aee3538216b10d535853e87..d3fba4a3cc5dafa7dc5d362b451f2791e189156f 100644 --- a/lib/src/btdevice_statemachine.h +++ b/lib/src/btdevice_statemachine.h @@ -69,6 +69,7 @@ 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_disconnected : sc::event<event_disconnected> {}; /* * State machine definition @@ -105,6 +106,10 @@ struct btdevice_sm : sc::state_machine<btdevice_sm, normal> device.connected = false; } + void pairing_cleanup(const event_disconnected &) + { + device.pairing_finished(false); + } private: btdevice &device; @@ -117,6 +122,7 @@ private: struct normal; struct pairing; +struct disconnected; struct init; struct idle; @@ -134,17 +140,34 @@ struct connecting; struct normal : sc::state<normal, btdevice_sm, idle>, state_logger { typedef mpl::list< - sc::transition<event_start_pairing, pairing>> reactions; + sc::transition<event_start_pairing, pairing>, + sc::transition<event_disconnected, disconnected>> reactions; normal(my_context ctx) : my_base(ctx), state_logger(ctx_device(), "normal") { } }; +struct disconnected : sc::state<disconnected, btdevice_sm>, state_logger +{ + typedef sc::transition<event_done, idle> reactions; + + disconnected(my_context ctx) : my_base(ctx), + state_logger(ctx_device(), "disconnected") + { + ctx_device().connected = false; + ctx_device().con_handle = INVALID_HANDLE; + + post_event(event_done()); + } +}; + struct pairing : sc::state<pairing, btdevice_sm, start_pairing>, state_logger { typedef mpl::list< - sc::transition<event_pairing_done, normal>> reactions; + sc::transition<event_pairing_done, normal>, + sc::transition<event_disconnected, disconnected, + btdevice_sm, &btdevice_sm::pairing_cleanup>> reactions; pairing(my_context ctx) : my_base(ctx), state_logger(ctx_device(), "pairing")