Add Login PIN Support to lib

This commit is contained in:
Florian Märkl 2019-08-25 16:38:13 +02:00
commit a93b8718ef
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
6 changed files with 195 additions and 28 deletions

View file

@ -37,16 +37,25 @@ typedef struct chiaki_ctrl_t
{ {
struct chiaki_session_t *session; struct chiaki_session_t *session;
ChiakiThread thread; ChiakiThread thread;
ChiakiStopPipe stop_pipe;
bool should_stop;
bool login_pin_entered;
uint8_t *login_pin; // not owned
size_t login_pin_size;
ChiakiStopPipe notif_pipe;
ChiakiMutex notif_mutex;
chiaki_socket_t sock; chiaki_socket_t sock;
uint8_t recv_buf[512]; uint8_t recv_buf[512];
size_t recv_buf_size; size_t recv_buf_size;
uint64_t crypt_counter_local;
uint64_t crypt_counter_remote; uint64_t crypt_counter_remote;
} ChiakiCtrl; } ChiakiCtrl;
CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_start(ChiakiCtrl *ctrl, struct chiaki_session_t *session); CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_start(ChiakiCtrl *ctrl, struct chiaki_session_t *session);
CHIAKI_EXPORT void chiaki_ctrl_stop(ChiakiCtrl *ctrl); CHIAKI_EXPORT void chiaki_ctrl_stop(ChiakiCtrl *ctrl);
CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_join(ChiakiCtrl *ctrl); CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_join(ChiakiCtrl *ctrl);
CHIAKI_EXPORT void chiaki_ctrl_set_login_pin(ChiakiCtrl *ctrl, uint8_t *pin, size_t pin_size);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -111,6 +111,7 @@ typedef struct chiaki_audio_stream_info_event_t
typedef enum { typedef enum {
CHIAKI_EVENT_LOGIN_PIN_REQUEST,
CHIAKI_EVENT_QUIT CHIAKI_EVENT_QUIT
} ChiakiEventType; } ChiakiEventType;
@ -175,6 +176,10 @@ typedef struct chiaki_session_t
bool should_stop; bool should_stop;
bool ctrl_failed; bool ctrl_failed;
bool ctrl_session_id_received; bool ctrl_session_id_received;
bool ctrl_login_pin_requested;
bool login_pin_entered;
uint8_t *login_pin;
size_t login_pin_size;
ChiakiCtrl ctrl; ChiakiCtrl ctrl;
@ -193,6 +198,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_session_start(ChiakiSession *session);
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_stop(ChiakiSession *session); CHIAKI_EXPORT ChiakiErrorCode chiaki_session_stop(ChiakiSession *session);
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_join(ChiakiSession *session); CHIAKI_EXPORT ChiakiErrorCode chiaki_session_join(ChiakiSession *session);
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_set_controller_state(ChiakiSession *session, ChiakiControllerState *state); CHIAKI_EXPORT ChiakiErrorCode chiaki_session_set_controller_state(ChiakiSession *session, ChiakiControllerState *state);
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_set_login_pin(ChiakiSession *session, uint8_t *pin, size_t pin_size);
static inline void chiaki_session_set_event_cb(ChiakiSession *session, ChiakiEventCallback cb, void *user) static inline void chiaki_session_set_event_cb(ChiakiSession *session, ChiakiEventCallback cb, void *user)
{ {

View file

@ -45,6 +45,7 @@ CHIAKI_EXPORT void chiaki_stop_pipe_fini(ChiakiStopPipe *stop_pipe);
CHIAKI_EXPORT void chiaki_stop_pipe_stop(ChiakiStopPipe *stop_pipe); CHIAKI_EXPORT void chiaki_stop_pipe_stop(ChiakiStopPipe *stop_pipe);
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *stop_pipe, chiaki_socket_t fd, uint64_t timeout_ms); CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *stop_pipe, chiaki_socket_t fd, uint64_t timeout_ms);
static inline ChiakiErrorCode chiaki_stop_pipe_sleep(ChiakiStopPipe *stop_pipe, uint64_t timeout_ms) { return chiaki_stop_pipe_select_single(stop_pipe, CHIAKI_INVALID_SOCKET, timeout_ms); } static inline ChiakiErrorCode chiaki_stop_pipe_sleep(ChiakiStopPipe *stop_pipe, uint64_t timeout_ms) { return chiaki_stop_pipe_select_single(stop_pipe, CHIAKI_INVALID_SOCKET, timeout_ms); }
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_reset(ChiakiStopPipe *stop_pipe);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -47,40 +47,77 @@
typedef enum ctrl_message_type_t { typedef enum ctrl_message_type_t {
CTRL_MESSAGE_TYPE_SESSION_ID = 0x33, CTRL_MESSAGE_TYPE_SESSION_ID = 0x33,
CTRL_MESSAGE_TYPE_HEARTBEAT_REQ = 0xfe, CTRL_MESSAGE_TYPE_HEARTBEAT_REQ = 0xfe,
CTRL_MESSAGE_TYPE_HEARTBEAT_REP = 0x1fe CTRL_MESSAGE_TYPE_HEARTBEAT_REP = 0x1fe,
CTRL_MESSAGE_TYPE_LOGIN_PIN_REQ = 0x4,
CTRL_MESSAGE_TYPE_LOGIN_PIN_REP = 0x8004
} CtrlMessageType; } CtrlMessageType;
static void *ctrl_thread_func(void *user); 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);
CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_start(ChiakiCtrl *ctrl, ChiakiSession *session) CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_start(ChiakiCtrl *ctrl, ChiakiSession *session)
{ {
ctrl->session = session; ctrl->session = session;
ChiakiErrorCode err = chiaki_stop_pipe_init(&ctrl->stop_pipe);
ctrl->should_stop = false;
ctrl->login_pin_entered = false;
ctrl->login_pin = NULL;
ctrl->login_pin_size = 0;
ChiakiErrorCode err = chiaki_stop_pipe_init(&ctrl->notif_pipe);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
return err; return err;
err = chiaki_mutex_init(&ctrl->notif_mutex, false);
if(err != CHIAKI_ERR_SUCCESS)
goto error_notif_pipe;
err = chiaki_thread_create(&ctrl->thread, ctrl_thread_func, ctrl); err = chiaki_thread_create(&ctrl->thread, ctrl_thread_func, ctrl);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
{ goto error_notif_mutex;
chiaki_stop_pipe_fini(&ctrl->stop_pipe);
return err;
}
chiaki_thread_set_name(&ctrl->thread, "Chiaki Ctrl"); chiaki_thread_set_name(&ctrl->thread, "Chiaki Ctrl");
return err; return err;
error_notif_mutex:
chiaki_mutex_fini(&ctrl->notif_mutex);
error_notif_pipe:
chiaki_stop_pipe_fini(&ctrl->notif_pipe);
return err;
} }
CHIAKI_EXPORT void chiaki_ctrl_stop(ChiakiCtrl *ctrl) CHIAKI_EXPORT void chiaki_ctrl_stop(ChiakiCtrl *ctrl)
{ {
chiaki_stop_pipe_stop(&ctrl->stop_pipe); ChiakiErrorCode err = chiaki_mutex_lock(&ctrl->notif_mutex);
assert(err == CHIAKI_ERR_SUCCESS);
ctrl->should_stop = true;
chiaki_stop_pipe_stop(&ctrl->notif_pipe);
chiaki_mutex_unlock(&ctrl->notif_mutex);
} }
CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_join(ChiakiCtrl *ctrl) CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_join(ChiakiCtrl *ctrl)
{ {
ChiakiErrorCode err = chiaki_thread_join(&ctrl->thread, NULL); ChiakiErrorCode err = chiaki_thread_join(&ctrl->thread, NULL);
chiaki_stop_pipe_fini(&ctrl->stop_pipe); chiaki_stop_pipe_fini(&ctrl->notif_pipe);
chiaki_mutex_fini(&ctrl->notif_mutex);
return err; return err;
} }
CHIAKI_EXPORT void chiaki_ctrl_set_login_pin(ChiakiCtrl *ctrl, uint8_t *pin, size_t pin_size)
{
ChiakiErrorCode err = chiaki_mutex_lock(&ctrl->notif_mutex);
assert(err == CHIAKI_ERR_SUCCESS);
ctrl->login_pin_entered = true;
ctrl->login_pin = pin;
ctrl->login_pin_size = pin_size;
chiaki_stop_pipe_stop(&ctrl->notif_pipe);
chiaki_mutex_unlock(&ctrl->notif_mutex);
}
static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl); static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl);
static void ctrl_message_received(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t *payload, size_t payload_size); static void ctrl_message_received(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t *payload, size_t payload_size);
@ -108,6 +145,9 @@ static void *ctrl_thread_func(void *user)
CHIAKI_LOGI(ctrl->session->log, "Ctrl connected"); CHIAKI_LOGI(ctrl->session->log, "Ctrl connected");
err = chiaki_mutex_lock(&ctrl->notif_mutex);
assert(err == CHIAKI_ERR_SUCCESS);
while(true) while(true)
{ {
bool overflow = false; bool overflow = false;
@ -141,14 +181,35 @@ static void *ctrl_thread_func(void *user)
break; break;
} }
err = chiaki_stop_pipe_select_single(&ctrl->stop_pipe, ctrl->sock, UINT64_MAX); chiaki_mutex_unlock(&ctrl->notif_mutex);
if(err != CHIAKI_ERR_SUCCESS) err = chiaki_stop_pipe_select_single(&ctrl->notif_pipe, ctrl->sock, UINT64_MAX);
{ chiaki_mutex_lock(&ctrl->notif_mutex);
if(err == CHIAKI_ERR_CANCELED) if(err == CHIAKI_ERR_CANCELED)
{
if(ctrl->should_stop)
{
CHIAKI_LOGI(ctrl->session->log, "Ctrl requested to stop"); CHIAKI_LOGI(ctrl->session->log, "Ctrl requested to stop");
break; break;
} }
if(ctrl->login_pin_entered)
{
ctrl_message_send(ctrl, CTRL_MESSAGE_TYPE_LOGIN_PIN_REP, ctrl->login_pin, ctrl->login_pin_size);
ctrl->login_pin_entered = false;
chiaki_stop_pipe_reset(&ctrl->notif_pipe);
}
else
{
CHIAKI_LOGE(ctrl->session->log, "Ctrl notif pipe set without state");
break;
}
}
else if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(ctrl->session->log, "Ctrl select error: %s", chiaki_error_string(err));
break;
}
int received = recv(ctrl->sock, ctrl->recv_buf + ctrl->recv_buf_size, sizeof(ctrl->recv_buf) - ctrl->recv_buf_size, 0); int received = recv(ctrl->sock, ctrl->recv_buf + ctrl->recv_buf_size, sizeof(ctrl->recv_buf) - ctrl->recv_buf_size, 0);
if(received <= 0) if(received <= 0)
{ {
@ -160,6 +221,8 @@ static void *ctrl_thread_func(void *user)
ctrl->recv_buf_size += received; ctrl->recv_buf_size += received;
} }
chiaki_mutex_unlock(&ctrl->notif_mutex);
CHIAKI_SOCKET_CLOSE(ctrl->sock); CHIAKI_SOCKET_CLOSE(ctrl->sock);
return NULL; return NULL;
@ -194,10 +257,6 @@ static ChiakiErrorCode ctrl_message_send(ChiakiCtrl *ctrl, CtrlMessageType type,
return CHIAKI_ERR_SUCCESS; return CHIAKI_ERR_SUCCESS;
} }
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(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t *payload, size_t payload_size) static void ctrl_message_received(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t *payload, size_t payload_size)
{ {
if(payload_size > 0) if(payload_size > 0)
@ -218,6 +277,9 @@ static void ctrl_message_received(ChiakiCtrl *ctrl, uint16_t msg_type, uint8_t *
case CTRL_MESSAGE_TYPE_HEARTBEAT_REQ: case CTRL_MESSAGE_TYPE_HEARTBEAT_REQ:
ctrl_message_received_heartbeat_req(ctrl, payload, payload_size); ctrl_message_received_heartbeat_req(ctrl, payload, payload_size);
break; break;
case CTRL_MESSAGE_TYPE_LOGIN_PIN_REQ:
ctrl_message_received_login_pin_req(ctrl, payload, payload_size);
break;
default: default:
CHIAKI_LOGW(ctrl->session->log, "Received Ctrl Message with unknown type %#x", msg_type); 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_VERBOSE, payload, payload_size);
@ -265,7 +327,7 @@ static void ctrl_message_received_session_id(ChiakiCtrl *ctrl, uint8_t *payload,
continue; continue;
if(c >= '0' && c <= '9') if(c >= '0' && c <= '9')
continue; continue;
CHIAKI_LOGE(ctrl->session->log, "Received Session Id contains invalid characters"); CHIAKI_LOGE(ctrl->session->log, "Ctrl received Session Id contains invalid characters");
return; return;
} }
@ -276,19 +338,32 @@ static void ctrl_message_received_session_id(ChiakiCtrl *ctrl, uint8_t *payload,
chiaki_mutex_unlock(&ctrl->session->state_mutex); chiaki_mutex_unlock(&ctrl->session->state_mutex);
chiaki_cond_signal(&ctrl->session->state_cond); chiaki_cond_signal(&ctrl->session->state_cond);
CHIAKI_LOGI(ctrl->session->log, "Received valid Session Id: %s", ctrl->session->session_id); CHIAKI_LOGI(ctrl->session->log, "Ctrl received valid Session Id: %s", ctrl->session->session_id);
} }
static void ctrl_message_received_heartbeat_req(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)
{ {
if(payload_size != 0) if(payload_size != 0)
CHIAKI_LOGW(ctrl->session->log, "Received Heartbeat request with non-empty payload"); CHIAKI_LOGW(ctrl->session->log, "Ctrl received Heartbeat request with non-empty payload");
CHIAKI_LOGI(ctrl->session->log, "Received Ctrl Heartbeat, sending reply"); CHIAKI_LOGI(ctrl->session->log, "Ctrl received Heartbeat, sending reply");
ctrl_message_send(ctrl, CTRL_MESSAGE_TYPE_HEARTBEAT_REP, NULL, 0); ctrl_message_send(ctrl, CTRL_MESSAGE_TYPE_HEARTBEAT_REP, NULL, 0);
} }
static void ctrl_message_received_login_pin_req(ChiakiCtrl *ctrl, uint8_t *payload, size_t payload_size)
{
if(payload_size != 0)
CHIAKI_LOGW(ctrl->session->log, "Ctrl received Login PIN request with non-empty payload");
CHIAKI_LOGI(ctrl->session->log, "Ctrl received Login PIN request");
chiaki_mutex_lock(&ctrl->session->state_mutex);
ctrl->session->ctrl_login_pin_requested = true;
chiaki_mutex_unlock(&ctrl->session->state_mutex);
chiaki_cond_signal(&ctrl->session->state_cond);
}
typedef struct ctrl_response_t { typedef struct ctrl_response_t {
@ -322,6 +397,7 @@ static void parse_ctrl_response(CtrlResponse *response, ChiakiHttpResponse *http
static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl) static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
{ {
ctrl->crypt_counter_local = 0;
ctrl->crypt_counter_remote = 0; ctrl->crypt_counter_remote = 0;
ChiakiSession *session = ctrl->session; ChiakiSession *session = ctrl->session;
@ -361,7 +437,7 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
uint8_t auth_enc[CHIAKI_RPCRYPT_KEY_SIZE]; uint8_t auth_enc[CHIAKI_RPCRYPT_KEY_SIZE];
ChiakiErrorCode err = chiaki_rpcrypt_encrypt(&session->rpcrypt, 0, (uint8_t *)session->connect_info.regist_key, auth_enc, CHIAKI_RPCRYPT_KEY_SIZE); ChiakiErrorCode err = chiaki_rpcrypt_encrypt(&session->rpcrypt, ctrl->crypt_counter_local++, (uint8_t *)session->connect_info.regist_key, auth_enc, CHIAKI_RPCRYPT_KEY_SIZE);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
goto error; goto error;
char auth_b64[CHIAKI_RPCRYPT_KEY_SIZE*2]; char auth_b64[CHIAKI_RPCRYPT_KEY_SIZE*2];
@ -370,7 +446,7 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
goto error; goto error;
uint8_t did_enc[CHIAKI_RP_DID_SIZE]; uint8_t did_enc[CHIAKI_RP_DID_SIZE];
err = chiaki_rpcrypt_encrypt(&session->rpcrypt, 1, (uint8_t *)session->connect_info.did, did_enc, CHIAKI_RP_DID_SIZE); err = chiaki_rpcrypt_encrypt(&session->rpcrypt, ctrl->crypt_counter_local++, (uint8_t *)session->connect_info.did, did_enc, CHIAKI_RP_DID_SIZE);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
goto error; goto error;
char did_b64[CHIAKI_RP_DID_SIZE*2]; char did_b64[CHIAKI_RP_DID_SIZE*2];
@ -382,7 +458,7 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
size_t ostype_len = strlen(SESSION_OSTYPE) + 1; size_t ostype_len = strlen(SESSION_OSTYPE) + 1;
if(ostype_len > sizeof(ostype_enc)) if(ostype_len > sizeof(ostype_enc))
goto error; goto error;
err = chiaki_rpcrypt_encrypt(&session->rpcrypt, 2, (uint8_t *)SESSION_OSTYPE, ostype_enc, ostype_len); err = chiaki_rpcrypt_encrypt(&session->rpcrypt, ctrl->crypt_counter_local++, (uint8_t *)SESSION_OSTYPE, ostype_enc, ostype_len);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
goto error; goto error;
char ostype_b64[256]; char ostype_b64[256];
@ -422,7 +498,7 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
size_t header_size; size_t header_size;
size_t received_size; size_t received_size;
err = chiaki_recv_http_header(sock, buf, sizeof(buf), &header_size, &received_size, &ctrl->stop_pipe, CTRL_EXPECT_TIMEOUT); err = chiaki_recv_http_header(sock, buf, sizeof(buf), &header_size, &received_size, &ctrl->notif_pipe, CTRL_EXPECT_TIMEOUT);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
{ {
if(err != CHIAKI_ERR_CANCELED) if(err != CHIAKI_ERR_CANCELED)

View file

@ -161,6 +161,10 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_session_init(ChiakiSession *session, Chiaki
session->should_stop = false; session->should_stop = false;
session->ctrl_session_id_received = false; session->ctrl_session_id_received = false;
session->ctrl_login_pin_requested = false;
session->login_pin_entered = false;
session->login_pin = NULL;
session->login_pin_size = 0;
err = chiaki_stream_connection_init(&session->stream_connection, session); err = chiaki_stream_connection_init(&session->stream_connection, session);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
@ -204,6 +208,7 @@ CHIAKI_EXPORT void chiaki_session_fini(ChiakiSession *session)
{ {
if(!session) if(!session)
return; return;
free(session->login_pin);
free(session->quit_reason_str); free(session->quit_reason_str);
chiaki_stream_connection_fini(&session->stream_connection); chiaki_stream_connection_fini(&session->stream_connection);
chiaki_stop_pipe_fini(&session->stop_pipe); chiaki_stop_pipe_fini(&session->stop_pipe);
@ -253,6 +258,22 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_session_set_controller_state(ChiakiSession
return CHIAKI_ERR_SUCCESS; return CHIAKI_ERR_SUCCESS;
} }
CHIAKI_EXPORT ChiakiErrorCode chiaki_session_set_login_pin(ChiakiSession *session, uint8_t *pin, size_t pin_size)
{
uint8_t *buf = malloc(pin_size);
memcpy(buf, pin, pin_size);
if(!buf)
return CHIAKI_ERR_MEMORY;
ChiakiErrorCode err = chiaki_mutex_lock(&session->state_mutex);
assert(err == CHIAKI_ERR_SUCCESS);
if(session->login_pin_entered)
free(session->login_pin);
session->login_pin_entered = true;
session->login_pin = buf;
session->login_pin_size = pin_size;
chiaki_mutex_unlock(&session->state_mutex);
}
static void session_send_event(ChiakiSession *session, ChiakiEvent *event) static void session_send_event(ChiakiSession *session, ChiakiEvent *event)
{ {
if(!session->event_cb) if(!session->event_cb)
@ -264,11 +285,27 @@ static void session_send_event(ChiakiSession *session, ChiakiEvent *event)
static bool session_thread_request_session(ChiakiSession *session); static bool session_thread_request_session(ChiakiSession *session);
static bool session_check_state_pred(void *user) static bool session_check_state_pred(void *user)
{
ChiakiSession *session = user;
return session->should_stop
|| session->ctrl_failed;
}
static bool session_check_state_pred_ctrl_start(void *user)
{ {
ChiakiSession *session = user; ChiakiSession *session = user;
return session->should_stop return session->should_stop
|| session->ctrl_failed || session->ctrl_failed
|| session->ctrl_session_id_received; || session->ctrl_session_id_received
|| session->ctrl_login_pin_requested;
}
static bool session_check_state_pred_pin(void *user)
{
ChiakiSession *session = user;
return session->should_stop
|| session->ctrl_failed
|| session->login_pin_entered;
} }
#define ENABLE_SENKUSHA #define ENABLE_SENKUSHA
@ -312,11 +349,36 @@ static void *session_thread_func(void *arg)
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
QUIT(quit); QUIT(quit);
chiaki_cond_timedwait_pred(&session->state_cond, &session->state_mutex, SESSION_EXPECT_TIMEOUT_MS, session_check_state_pred, 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); CHECK_STOP(quit_ctrl);
if(session->ctrl_failed)
goto ctrl_failed;
if(session->ctrl_login_pin_requested)
{
session->ctrl_login_pin_requested = false;
CHIAKI_LOGI(session->log, "Ctrl requested Login PIN");
ChiakiEvent event = { 0 };
event.type = CHIAKI_EVENT_LOGIN_PIN_REQUEST;
session_send_event(session, &event);
chiaki_cond_timedwait_pred(&session->state_cond, &session->state_mutex, UINT64_MAX, session_check_state_pred_pin, session);
CHECK_STOP(quit_ctrl);
if(session->ctrl_failed)
goto ctrl_failed;
assert(session->login_pin_entered && session->login_pin);
chiaki_ctrl_set_login_pin(&session->ctrl, session->login_pin, session->login_pin_size);
session->login_pin_entered = false;
free(session->login_pin);
session->login_pin = NULL;
session->login_pin_size = 0;
}
if(!session->ctrl_session_id_received) if(!session->ctrl_session_id_received)
{ {
ctrl_failed:
CHIAKI_LOGE(session->log, "Ctrl has failed, shutting down"); CHIAKI_LOGE(session->log, "Ctrl has failed, shutting down");
if(session->quit_reason == CHIAKI_QUIT_REASON_NONE) if(session->quit_reason == CHIAKI_QUIT_REASON_NONE)
session->quit_reason = CHIAKI_QUIT_REASON_CTRL_UNKNOWN; session->quit_reason = CHIAKI_QUIT_REASON_CTRL_UNKNOWN;

View file

@ -136,3 +136,16 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *sto
return CHIAKI_ERR_TIMEOUT; return CHIAKI_ERR_TIMEOUT;
#endif #endif
} }
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_reset(ChiakiStopPipe *stop_pipe)
{
#ifdef _WIN32
BOOL r = WSAResetEvent(stop_pipe->event);
return r ? CHIAKI_ERR_SUCCESS : CHIAKI_ERR_UNKNOWN;
#else
uint8_t v;
int r;
while((r = read(stop_pipe->fds[0], &v, sizeof(v))) > 0);
return r < 0 ? CHIAKI_ERR_UNKNOWN : CHIAKI_ERR_SUCCESS;
#endif
}