Make Ctrl stoppable

This commit is contained in:
Florian Märkl 2019-08-03 12:59:30 +02:00
commit 99fb690ad7
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
4 changed files with 46 additions and 26 deletions

View file

@ -20,6 +20,7 @@
#include "common.h" #include "common.h"
#include "thread.h" #include "thread.h"
#include "stoppipe.h"
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@ -32,6 +33,7 @@ typedef struct chiaki_ctrl_t
{ {
struct chiaki_session_t *session; struct chiaki_session_t *session;
ChiakiThread thread; ChiakiThread thread;
ChiakiStopPipe stop_pipe;
int sock; int sock;
uint8_t recv_buf[512]; uint8_t recv_buf[512];
size_t recv_buf_size; size_t recv_buf_size;
@ -39,6 +41,7 @@ typedef struct chiaki_ctrl_t
} 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 ChiakiErrorCode chiaki_ctrl_join(ChiakiCtrl *ctrl); CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_join(ChiakiCtrl *ctrl);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -174,13 +174,6 @@ static inline void chiaki_session_set_video_sample_cb(ChiakiSession *session, Ch
session->video_sample_cb_user = user; session->video_sample_cb_user = user;
} }
static inline void chiaki_session_set_quit_reason(ChiakiSession *session, ChiakiQuitReason reason)
{
if(session->quit_reason != CHIAKI_QUIT_REASON_NONE)
return;
session->quit_reason = reason;
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -30,6 +30,8 @@
#define SESSION_CTRL_PORT 9295 #define SESSION_CTRL_PORT 9295
#define CTRL_EXPECT_TIMEOUT 5000
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,
@ -42,18 +44,38 @@ static void *ctrl_thread_func(void *user);
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);
if(err != CHIAKI_ERR_SUCCESS)
return err;
return chiaki_thread_create(&ctrl->thread, ctrl_thread_func, ctrl); return chiaki_thread_create(&ctrl->thread, ctrl_thread_func, ctrl);
} }
CHIAKI_EXPORT void chiaki_ctrl_stop(ChiakiCtrl *ctrl)
{
chiaki_stop_pipe_stop(&ctrl->stop_pipe);
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_join(ChiakiCtrl *ctrl) CHIAKI_EXPORT ChiakiErrorCode chiaki_ctrl_join(ChiakiCtrl *ctrl)
{ {
return chiaki_thread_join(&ctrl->thread, NULL); ChiakiErrorCode err = chiaki_thread_join(&ctrl->thread, NULL);
chiaki_stop_pipe_fini(&ctrl->stop_pipe);
return err;
} }
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);
static void ctrl_failed(ChiakiCtrl *ctrl, ChiakiQuitReason reason)
{
ChiakiErrorCode mutex_err = chiaki_mutex_lock(&ctrl->session->state_mutex);
assert(mutex_err == CHIAKI_ERR_SUCCESS);
ctrl->session->quit_reason = reason;
ctrl->session->ctrl_failed = true;
chiaki_mutex_unlock(&ctrl->session->state_mutex);
chiaki_cond_signal(&ctrl->session->state_cond);
}
static void *ctrl_thread_func(void *user) static void *ctrl_thread_func(void *user)
{ {
ChiakiCtrl *ctrl = user; ChiakiCtrl *ctrl = user;
@ -61,11 +83,7 @@ static void *ctrl_thread_func(void *user)
ChiakiErrorCode err = ctrl_connect(ctrl); ChiakiErrorCode err = ctrl_connect(ctrl);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
{ {
chiaki_session_set_quit_reason(ctrl->session, CHIAKI_QUIT_REASON_CTRL_UNKNOWN); ctrl_failed(ctrl, CHIAKI_QUIT_REASON_CTRL_UNKNOWN);
chiaki_mutex_lock(&ctrl->session->state_mutex);
ctrl->session->ctrl_failed = true;
chiaki_mutex_unlock(&ctrl->session->state_mutex);
chiaki_cond_signal(&ctrl->session->state_cond);
return NULL; return NULL;
} }
@ -100,7 +118,15 @@ static void *ctrl_thread_func(void *user)
if(overflow) if(overflow)
{ {
chiaki_session_set_quit_reason(ctrl->session, CHIAKI_QUIT_REASON_CTRL_UNKNOWN); ctrl_failed(ctrl, CHIAKI_QUIT_REASON_CTRL_UNKNOWN);
break;
}
err = chiaki_stop_pipe_select_single(&ctrl->stop_pipe, ctrl->sock, UINT64_MAX);
if(err != CHIAKI_ERR_SUCCESS)
{
if(err == CHIAKI_ERR_CANCELED)
CHIAKI_LOGI(&ctrl->session->log, "Ctrl requested to stop");
break; break;
} }
@ -108,7 +134,7 @@ static void *ctrl_thread_func(void *user)
if(received <= 0) if(received <= 0)
{ {
if(received < 0) if(received < 0)
chiaki_session_set_quit_reason(ctrl->session, CHIAKI_QUIT_REASON_CTRL_UNKNOWN); ctrl_failed(ctrl, CHIAKI_QUIT_REASON_CTRL_UNKNOWN);
break; break;
} }
@ -288,7 +314,7 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
if(sock < 0) if(sock < 0)
{ {
CHIAKI_LOGE(&session->log, "Session ctrl socket creation failed."); CHIAKI_LOGE(&session->log, "Session ctrl socket creation failed.");
chiaki_session_set_quit_reason(session, CHIAKI_QUIT_REASON_CTRL_UNKNOWN); ctrl_failed(ctrl, CHIAKI_QUIT_REASON_CTRL_UNKNOWN);
return CHIAKI_ERR_NETWORK; return CHIAKI_ERR_NETWORK;
} }
@ -298,10 +324,7 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
{ {
int errsv = errno; int errsv = errno;
CHIAKI_LOGE(&session->log, "Ctrl connect failed: %s", strerror(errsv)); CHIAKI_LOGE(&session->log, "Ctrl connect failed: %s", strerror(errsv));
if(errsv == ECONNREFUSED) ctrl_failed(ctrl, errsv == ECONNREFUSED ? CHIAKI_QUIT_REASON_SESSION_REQUEST_CONNECTION_REFUSED : CHIAKI_QUIT_REASON_CTRL_UNKNOWN);
session->quit_reason = CHIAKI_QUIT_REASON_SESSION_REQUEST_CONNECTION_REFUSED;
else
session->quit_reason = CHIAKI_QUIT_REASON_NONE;
close(sock); close(sock);
return CHIAKI_ERR_NETWORK; return CHIAKI_ERR_NETWORK;
} }
@ -371,9 +394,10 @@ 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, NULL, UINT64_MAX); // TODO: stop pipe! err = chiaki_recv_http_header(sock, buf, sizeof(buf), &header_size, &received_size, &ctrl->stop_pipe, CTRL_EXPECT_TIMEOUT);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
{ {
if(err != CHIAKI_ERR_CANCELED)
CHIAKI_LOGE(&session->log, "Failed to receive ctrl request response"); CHIAKI_LOGE(&session->log, "Failed to receive ctrl request response");
goto error; goto error;
} }

View file

@ -68,6 +68,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_session_init(ChiakiSession *session, Chiaki
goto error_state_mutex; goto error_state_mutex;
session->should_stop = false; session->should_stop = false;
session->ctrl_session_id_received = false;
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)
@ -212,12 +213,11 @@ static void *session_thread_func(void *arg)
chiaki_rpcrypt_init(&session->rpcrypt, session->nonce, session->connect_info.morning); chiaki_rpcrypt_init(&session->rpcrypt, session->nonce, session->connect_info.morning);
usleep(5000); // PS4 doesn't always react right away, sleep a bit
chiaki_cond_timedwait_pred(&session->state_cond, &session->state_mutex, 10, session_check_state_pred, session);
CHIAKI_LOGI(&session->log, "Starting ctrl"); CHIAKI_LOGI(&session->log, "Starting ctrl");
session->ctrl_session_id_received = false;
ChiakiErrorCode err = chiaki_ctrl_start(&session->ctrl, session); ChiakiErrorCode err = chiaki_ctrl_start(&session->ctrl, session);
if(err != CHIAKI_ERR_SUCCESS) if(err != CHIAKI_ERR_SUCCESS)
QUIT(quit); QUIT(quit);
@ -306,7 +306,7 @@ quit_audio_receiver:
session->audio_receiver = NULL; session->audio_receiver = NULL;
quit_ctrl: quit_ctrl:
// TODO: stop ctrl chiaki_ctrl_stop(&session->ctrl);
chiaki_ctrl_join(&session->ctrl); chiaki_ctrl_join(&session->ctrl);
CHIAKI_LOGI(&session->log, "Ctrl stopped"); CHIAKI_LOGI(&session->log, "Ctrl stopped");