From d668423775c5e9c9dd9c1c1487b0ca763a836533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Sun, 25 Aug 2019 16:38:13 +0200 Subject: [PATCH] Support multiple PIN Entries --- gui/include/loginpindialog.h | 2 +- gui/include/streamsession.h | 2 +- gui/include/streamwindow.h | 2 +- gui/src/loginpindialog.cpp | 8 +++++- gui/src/streamsession.cpp | 3 +- gui/src/streamwindow.cpp | 4 +-- lib/include/chiaki/ctrl.h | 2 ++ lib/include/chiaki/session.h | 4 +++ lib/src/ctrl.c | 55 ++++++++++++++++++++++++++++++++++-- lib/src/session.c | 12 ++++++-- 10 files changed, 81 insertions(+), 13 deletions(-) diff --git a/gui/include/loginpindialog.h b/gui/include/loginpindialog.h index 2784694..fc6d0e5 100644 --- a/gui/include/loginpindialog.h +++ b/gui/include/loginpindialog.h @@ -36,7 +36,7 @@ class LoginPINDialog : public QDialog void UpdateButtons(); public: - explicit LoginPINDialog(QWidget *parent = nullptr); + explicit LoginPINDialog(bool incorrect, QWidget *parent = nullptr); QString GetPIN() { return pin; } }; diff --git a/gui/include/streamsession.h b/gui/include/streamsession.h index c695e0b..3c17ca8 100644 --- a/gui/include/streamsession.h +++ b/gui/include/streamsession.h @@ -105,7 +105,7 @@ class StreamSession : public QObject signals: void CurrentImageUpdated(); void SessionQuit(ChiakiQuitReason reason, const QString &reason_str); - void LoginPINRequested(); + void LoginPINRequested(bool incorrect); private slots: void UpdateGamepads(); diff --git a/gui/include/streamwindow.h b/gui/include/streamwindow.h index ab698f6..5e67e6e 100644 --- a/gui/include/streamwindow.h +++ b/gui/include/streamwindow.h @@ -47,7 +47,7 @@ class StreamWindow: public QMainWindow private slots: void SessionQuit(ChiakiQuitReason reason, const QString &reason_str); - void LoginPINRequested(); + void LoginPINRequested(bool incorrect); void ToggleFullscreen(); }; diff --git a/gui/src/loginpindialog.cpp b/gui/src/loginpindialog.cpp index a9a35ea..51e0836 100644 --- a/gui/src/loginpindialog.cpp +++ b/gui/src/loginpindialog.cpp @@ -23,16 +23,22 @@ #include #include #include +#include #define PIN_LENGTH 4 static const QRegularExpression pin_re(QString("[0-9]").repeated(PIN_LENGTH)); -LoginPINDialog::LoginPINDialog(QWidget *parent) : QDialog(parent) +LoginPINDialog::LoginPINDialog(bool incorrect, QWidget *parent) : QDialog(parent) { + setWindowTitle(tr("Console Login PIN")); + auto layout = new QVBoxLayout(this); setLayout(layout); + if(incorrect) + layout->addWidget(new QLabel(tr("Entered PIN was incorrect!"), this)); + pin_edit = new QLineEdit(this); pin_edit->setPlaceholderText(tr("Login PIN")); pin_edit->setValidator(new QRegularExpressionValidator(pin_re, pin_edit)); diff --git a/gui/src/streamsession.cpp b/gui/src/streamsession.cpp index 7dbd244..0c3f0da 100644 --- a/gui/src/streamsession.cpp +++ b/gui/src/streamsession.cpp @@ -30,6 +30,7 @@ #include #include +#include StreamSessionConnectInfo::StreamSessionConnectInfo() { @@ -332,7 +333,7 @@ void StreamSession::Event(ChiakiEvent *event) emit SessionQuit(event->quit.reason, event->quit.reason_str ? QString::fromUtf8(event->quit.reason_str) : QString()); break; case CHIAKI_EVENT_LOGIN_PIN_REQUEST: - emit LoginPINRequested(); + emit LoginPINRequested(event->login_pin_request.pin_incorrect); break; } } diff --git a/gui/src/streamwindow.cpp b/gui/src/streamwindow.cpp index 4bb4ccb..acb7071 100644 --- a/gui/src/streamwindow.cpp +++ b/gui/src/streamwindow.cpp @@ -104,9 +104,9 @@ void StreamWindow::SessionQuit(ChiakiQuitReason reason, const QString &reason_st close(); } -void StreamWindow::LoginPINRequested() +void StreamWindow::LoginPINRequested(bool incorrect) { - auto dialog = new LoginPINDialog(this); + auto dialog = new LoginPINDialog(incorrect, this); dialog->setAttribute(Qt::WA_DeleteOnClose); connect(dialog, &QDialog::finished, this, [this, dialog](int result) { grabKeyboard(); diff --git a/lib/include/chiaki/ctrl.h b/lib/include/chiaki/ctrl.h index e2ab838..ce7af8c 100644 --- a/lib/include/chiaki/ctrl.h +++ b/lib/include/chiaki/ctrl.h @@ -45,6 +45,8 @@ typedef struct chiaki_ctrl_t ChiakiStopPipe notif_pipe; ChiakiMutex notif_mutex; + bool login_pin_requested; + chiaki_socket_t sock; uint8_t recv_buf[512]; size_t recv_buf_size; diff --git a/lib/include/chiaki/session.h b/lib/include/chiaki/session.h index f4811da..566988a 100644 --- a/lib/include/chiaki/session.h +++ b/lib/include/chiaki/session.h @@ -121,6 +121,10 @@ typedef struct chiaki_event_t union { ChiakiQuitEvent quit; + struct + { + bool pin_incorrect; // false on first request, true if the pin entered before was incorrect + } login_pin_request; }; } ChiakiEvent; diff --git a/lib/src/ctrl.c b/lib/src/ctrl.c index fc6651e..21c64c7 100644 --- a/lib/src/ctrl.c +++ b/lib/src/ctrl.c @@ -49,15 +49,22 @@ typedef enum ctrl_message_type_t { CTRL_MESSAGE_TYPE_HEARTBEAT_REQ = 0xfe, CTRL_MESSAGE_TYPE_HEARTBEAT_REP = 0x1fe, CTRL_MESSAGE_TYPE_LOGIN_PIN_REQ = 0x4, - CTRL_MESSAGE_TYPE_LOGIN_PIN_REP = 0x8004 + CTRL_MESSAGE_TYPE_LOGIN_PIN_REP = 0x8004, + CTRL_MESSAGE_TYPE_LOGIN = 0x5 } CtrlMessageType; +typedef enum ctrl_login_state_t { + CTRL_LOGIN_STATE_SUCCESS = 0x0, + CTRL_LOGIN_STATE_PIN_INCORRECT = 0x1 +} CtrlLoginState; + static void *ctrl_thread_func(void *user); static ChiakiErrorCode ctrl_message_send(ChiakiCtrl *ctrl, CtrlMessageType type, const uint8_t *payload, size_t payload_size); static void ctrl_message_received_session_id(ChiakiCtrl *ctrl, uint8_t *payload, size_t payload_size); static void ctrl_message_received_heartbeat_req(ChiakiCtrl *ctrl, uint8_t *payload, size_t payload_size); static void ctrl_message_received_login_pin_req(ChiakiCtrl *ctrl, uint8_t *payload, size_t payload_size); +static void ctrl_message_received_login(ChiakiCtrl *ctrl, uint8_t *payload, size_t payload_size); CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_start(ChiakiCtrl *ctrl, ChiakiSession *session) { @@ -65,6 +72,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_start(ChiakiCtrl *ctrl, ChiakiSession ctrl->should_stop = false; ctrl->login_pin_entered = false; + ctrl->login_pin_requested = false; ctrl->login_pin = NULL; ctrl->login_pin_size = 0; @@ -307,9 +315,12 @@ static void ctrl_message_received(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t * case CTRL_MESSAGE_TYPE_LOGIN_PIN_REQ: ctrl_message_received_login_pin_req(ctrl, payload, payload_size); break; + case CTRL_MESSAGE_TYPE_LOGIN: + ctrl_message_received_login(ctrl, payload, payload_size); + break; default: CHIAKI_LOGW(ctrl->session->log, "Received Ctrl Message with unknown type %#x", msg_type); - chiaki_log_hexdump(ctrl->session->log, CHIAKI_LOG_VERBOSE, payload, payload_size); + chiaki_log_hexdump(ctrl->session->log, CHIAKI_LOG_WARNING, payload, payload_size); break; } } @@ -385,12 +396,50 @@ static void ctrl_message_received_login_pin_req(ChiakiCtrl *ctrl, uint8_t *paylo CHIAKI_LOGI(ctrl->session->log, "Ctrl received Login PIN request"); - chiaki_mutex_lock(&ctrl->session->state_mutex); + ctrl->login_pin_requested = true; + + ChiakiErrorCode err = chiaki_mutex_lock(&ctrl->session->state_mutex); + assert(err == CHIAKI_ERR_SUCCESS); ctrl->session->ctrl_login_pin_requested = true; chiaki_mutex_unlock(&ctrl->session->state_mutex); chiaki_cond_signal(&ctrl->session->state_cond); } +static void ctrl_message_received_login(ChiakiCtrl *ctrl, uint8_t *payload, size_t payload_size) +{ + if(payload_size != 1) + { + CHIAKI_LOGW(ctrl->session->log, "Ctrl received Login message with payload of size %llx", (unsigned long long)payload_size); + if(payload_size < 1) + return; + } + + CtrlLoginState state = payload[0]; + switch(state) + { + case CTRL_LOGIN_STATE_SUCCESS: + CHIAKI_LOGI(ctrl->session->log, "Ctrl received Login message: success"); + ctrl->login_pin_requested = false; + break; + case CTRL_LOGIN_STATE_PIN_INCORRECT: + CHIAKI_LOGI(ctrl->session->log, "Ctrl received Login message: PIN incorrect"); + if(ctrl->login_pin_requested) + { + CHIAKI_LOGI(ctrl->session->log, "Ctrl requesting PIN from Session again"); + ChiakiErrorCode err = chiaki_mutex_lock(&ctrl->session->state_mutex); + assert(err == CHIAKI_ERR_SUCCESS); + ctrl->session->ctrl_login_pin_requested = true; + chiaki_mutex_unlock(&ctrl->session->state_mutex); + chiaki_cond_signal(&ctrl->session->state_cond); + } + else + CHIAKI_LOGW(ctrl->session->log, "Ctrl Login PIN incorrect message, but PIN was not requested"); + break; + default: + CHIAKI_LOGI(ctrl->session->log, "Ctrl received Login message with state: %x", state); + break; + } +} typedef struct ctrl_response_t { diff --git a/lib/src/session.c b/lib/src/session.c index 23528c4..c3c6f98 100644 --- a/lib/src/session.c +++ b/lib/src/session.c @@ -365,13 +365,19 @@ static void *session_thread_func(void *arg) if(session->ctrl_failed) goto ctrl_failed; - if(session->ctrl_login_pin_requested) + bool pin_incorrect = false; + while(session->ctrl_login_pin_requested) { session->ctrl_login_pin_requested = false; - CHIAKI_LOGI(session->log, "Ctrl requested Login PIN"); + if(pin_incorrect) + CHIAKI_LOGI(session->log, "Login PIN was incorrect, requested again by Ctrl"); + else + CHIAKI_LOGI(session->log, "Ctrl requested Login PIN"); ChiakiEvent event = { 0 }; event.type = CHIAKI_EVENT_LOGIN_PIN_REQUEST; + event.login_pin_request.pin_incorrect = pin_incorrect; session_send_event(session, &event); + pin_incorrect = true; chiaki_cond_timedwait_pred(&session->state_cond, &session->state_mutex, UINT64_MAX, session_check_state_pred_pin, session); CHECK_STOP(quit_ctrl); @@ -387,7 +393,7 @@ static void *session_thread_func(void *arg) session->login_pin_size = 0; // wait for session id again - chiaki_cond_timedwait_pred(&session->state_cond, &session->state_mutex, SESSION_EXPECT_TIMEOUT_MS, session_check_state_pred_session_id, session); + chiaki_cond_timedwait_pred(&session->state_cond, &session->state_mutex, SESSION_EXPECT_TIMEOUT_MS, session_check_state_pred_ctrl_start, session); CHECK_STOP(quit_ctrl); }