Detect Remote Disconnect

This commit is contained in:
Florian Märkl 2019-08-03 20:20:10 +02:00
parent 389676899c
commit bea03d667a
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
11 changed files with 91 additions and 12 deletions

View file

@ -94,7 +94,7 @@ class StreamSession : public QObject
signals:
void CurrentImageUpdated();
void SessionQuit(ChiakiQuitReason reason);
void SessionQuit(ChiakiQuitReason reason, const QString &reason_str);
private slots:
#if CHIAKI_GUI_ENABLE_QT_GAMEPAD

View file

@ -46,7 +46,7 @@ class StreamWindow: public QMainWindow
private slots:
void FramesAvailable();
void SessionQuit(ChiakiQuitReason reason);
void SessionQuit(ChiakiQuitReason reason, const QString &reason_str);
};
#endif // CHIAKI_GUI_STREAMWINDOW_H

View file

@ -71,7 +71,7 @@ int main(int argc, char *argv[])
connect_info.did = parser.value(did_option);
chiaki_connect_video_profile_preset(&connect_info.video_profile,
CHIAKI_VIDEO_RESOLUTION_PRESET_540p,
CHIAKI_VIDEO_RESOLUTION_PRESET_360p,
CHIAKI_VIDEO_FPS_PRESET_30);
if(connect_info.registkey.isEmpty() || connect_info.ostype.isEmpty() || connect_info.auth.isEmpty() || connect_info.morning.isEmpty() || connect_info.did.isEmpty())

View file

@ -257,7 +257,7 @@ void StreamSession::Event(ChiakiEvent *event)
switch(event->type)
{
case CHIAKI_EVENT_QUIT:
emit SessionQuit(event->quit.reason);
emit SessionQuit(event->quit.reason, event->quit.reason_str ? QString::fromUtf8(event->quit.reason_str) : QString());
break;
}
}

View file

@ -83,10 +83,13 @@ void StreamWindow::FramesAvailable()
}
}
void StreamWindow::SessionQuit(ChiakiQuitReason reason)
void StreamWindow::SessionQuit(ChiakiQuitReason reason, const QString &reason_str)
{
if(reason == CHIAKI_QUIT_REASON_STOPPED)
return;
QMessageBox::critical(this, tr("Session has quit"), tr("Chiaki Session has quit:") + "\n" + chiaki_quit_reason_string(reason));
QString m = tr("Chiaki Session has quit") + ":\n" + chiaki_quit_reason_string(reason);
if(!reason_str.isEmpty())
m += "\n" + tr("Reason") + ": \"" + reason_str + "\"";
QMessageBox::critical(this, tr("Session has quit"), m);
close();
}

View file

@ -35,6 +35,7 @@ typedef enum
CHIAKI_ERR_MEMORY,
CHIAKI_ERR_OVERFLOW,
CHIAKI_ERR_NETWORK,
CHIAKI_ERR_DISCONNECTED,
CHIAKI_ERR_INVALID_DATA,
CHIAKI_ERR_BUF_TOO_SMALL,
CHIAKI_ERR_MUTEX_LOCKED,

View file

@ -86,7 +86,8 @@ typedef enum {
CHIAKI_QUIT_REASON_SESSION_REQUEST_RP_CRASH,
CHIAKI_QUIT_REASON_CTRL_UNKNOWN,
CHIAKI_QUIT_REASON_CTRL_CONNECTION_REFUSED,
CHIAKI_QUIT_REASON_STREAM_CONNECTION_UNKNOWN
CHIAKI_QUIT_REASON_STREAM_CONNECTION_UNKNOWN,
CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_DISCONNECTED
} ChiakiQuitReason;
CHIAKI_EXPORT const char *chiaki_quit_reason_string(ChiakiQuitReason reason);
@ -94,6 +95,7 @@ CHIAKI_EXPORT const char *chiaki_quit_reason_string(ChiakiQuitReason reason);
typedef struct chiaki_quit_event_t
{
ChiakiQuitReason reason;
const char *reason_str;
} ChiakiQuitEvent;
typedef struct chiaki_audio_stream_info_event_t
@ -145,6 +147,7 @@ typedef struct chiaki_session_t
ChiakiECDH ecdh;
ChiakiQuitReason quit_reason;
char *quit_reason_str; // additional reason string from remote
ChiakiEventCallback event_cb;
void *event_cb_user;

View file

@ -66,6 +66,8 @@ typedef struct chiaki_stream_connection_t
bool state_finished;
bool state_failed;
bool should_stop;
bool remote_disconnected;
char *remote_disconnect_reason;
} ChiakiStreamConnection;
CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_init(ChiakiStreamConnection *stream_connection, ChiakiSession *session);

View file

@ -32,6 +32,8 @@ CHIAKI_EXPORT const char *chiaki_error_string(ChiakiErrorCode code)
return "Memory error";
case CHIAKI_ERR_NETWORK:
return "Network error";
case CHIAKI_ERR_DISCONNECTED:
return "Disconnected";
case CHIAKI_ERR_INVALID_DATA:
return "Invalid data";
case CHIAKI_ERR_BUF_TOO_SMALL:

View file

@ -103,6 +103,8 @@ CHIAKI_EXPORT const char *chiaki_quit_reason_string(ChiakiQuitReason reason)
return "Connection Refused in Ctrl";
case CHIAKI_QUIT_REASON_STREAM_CONNECTION_UNKNOWN:
return "Unknown Error in Stream Connection";
case CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_DISCONNECTED:
return "Remote has disconnected from Stream Connection";
case CHIAKI_QUIT_REASON_NONE:
default:
return "Unknown";
@ -186,6 +188,7 @@ CHIAKI_EXPORT void chiaki_session_fini(ChiakiSession *session)
{
if(!session)
return;
free(session->quit_reason_str);
chiaki_stream_connection_fini(&session->stream_connection);
chiaki_stop_pipe_fini(&session->stop_pipe);
chiaki_cond_fini(&session->state_cond);
@ -357,7 +360,13 @@ static void *session_thread_func(void *arg)
chiaki_mutex_unlock(&session->state_mutex);
err = chiaki_stream_connection_run(&session->stream_connection);
chiaki_mutex_lock(&session->state_mutex);
if(err != CHIAKI_ERR_SUCCESS && err != CHIAKI_ERR_CANCELED)
if(err == CHIAKI_ERR_DISCONNECTED)
{
CHIAKI_LOGE(&session->log, "Remote disconnected from StreamConnection");
session->quit_reason = CHIAKI_QUIT_REASON_STREAM_CONNECTION_REMOTE_DISCONNECTED;
session->quit_reason_str = strdup(session->stream_connection.remote_disconnect_reason);
}
else if(err != CHIAKI_ERR_SUCCESS && err != CHIAKI_ERR_CANCELED)
{
CHIAKI_LOGE(&session->log, "StreamConnection run failed");
session->quit_reason = CHIAKI_QUIT_REASON_STREAM_CONNECTION_UNKNOWN;
@ -388,6 +397,7 @@ quit:
CHIAKI_LOGI(&session->log, "Session has quit");
quit_event.type = CHIAKI_EVENT_QUIT;
quit_event.quit.reason = session->quit_reason;
quit_event.quit.reason_str = session->quit_reason_str;
session_send_event(session, &quit_event);
return NULL;

View file

@ -88,6 +88,8 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_init(ChiakiStreamConnecti
stream_connection->state_finished = false;
stream_connection->state_failed = false;
stream_connection->should_stop = false;
stream_connection->remote_disconnected = false;
stream_connection->remote_disconnect_reason = NULL;
return CHIAKI_ERR_SUCCESS;
@ -101,6 +103,8 @@ error:
CHIAKI_EXPORT void chiaki_stream_connection_fini(ChiakiStreamConnection *stream_connection)
{
free(stream_connection->remote_disconnect_reason);
chiaki_gkcrypt_free(stream_connection->gkcrypt_remote);
chiaki_gkcrypt_free(stream_connection->gkcrypt_local);
@ -116,7 +120,7 @@ CHIAKI_EXPORT void chiaki_stream_connection_fini(ChiakiStreamConnection *stream_
static bool state_finished_cond_check(void *user)
{
ChiakiStreamConnection *stream_connection = user;
return stream_connection->state_finished || stream_connection->should_stop;
return stream_connection->state_finished || stream_connection->should_stop || stream_connection->remote_disconnected;
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_run(ChiakiStreamConnection *stream_connection)
@ -145,7 +149,6 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_run(ChiakiStreamConnectio
#define CHECK_STOP(quit_label) do { \
if(stream_connection->should_stop) \
{ \
session->quit_reason = CHIAKI_QUIT_REASON_STOPPED; \
goto quit_label; \
} } while(0)
@ -259,7 +262,15 @@ disconnect:
stream_connection_send_disconnect(stream_connection);
if(stream_connection->should_stop)
{
CHIAKI_LOGI(stream_connection->log, "StreamConnection was requested to stop");
err = CHIAKI_ERR_CANCELED;
}
else if(stream_connection->remote_disconnected)
{
CHIAKI_LOGI(stream_connection->log, "StreamConnection closing after Remote disconnected");
err = CHIAKI_ERR_DISCONNECTED;
}
close_takion:
chiaki_mutex_unlock(&stream_connection->state_mutex);
@ -329,6 +340,36 @@ static void stream_connection_takion_data(ChiakiStreamConnection *stream_connect
chiaki_mutex_unlock(&stream_connection->state_mutex);
}
static void stream_connection_takion_data_handle_disconnect(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size)
{
tkproto_TakionMessage msg;
memset(&msg, 0, sizeof(msg));
char reason[256];
ChiakiPBDecodeBuf decode_buf;
decode_buf.size = 0;
decode_buf.max_size = sizeof(reason) - 1;
decode_buf.buf = (uint8_t *)reason;
msg.disconnect_payload.reason.arg = &decode_buf;
msg.disconnect_payload.reason.funcs.decode = chiaki_pb_decode_buf;
pb_istream_t stream = pb_istream_from_buffer(buf, buf_size);
bool r = pb_decode(&stream, tkproto_TakionMessage_fields, &msg);
if(!r)
{
CHIAKI_LOGE(stream_connection->log, "StreamConnection failed to decode data protobuf");
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_ERROR, buf, buf_size);
return;
}
reason[decode_buf.size] = '\0';
CHIAKI_LOGI(stream_connection->log, "Remote disconnected from StreamConnection with reason \"%s\"", reason);
stream_connection->remote_disconnected = true;
free(stream_connection->remote_disconnect_reason);
stream_connection->remote_disconnect_reason = strdup(reason);
chiaki_cond_signal(&stream_connection->state_cond);
}
static void stream_connection_takion_data_idle(ChiakiStreamConnection *stream_connection, uint8_t *buf, size_t buf_size)
{
@ -344,8 +385,11 @@ static void stream_connection_takion_data_idle(ChiakiStreamConnection *stream_co
return;
}
//CHIAKI_LOGD(stream_connection->log, "StreamConnection received data");
//chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_DEBUG, buf, buf_size);
CHIAKI_LOGV(stream_connection->log, "StreamConnection received data");
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_VERBOSE, buf, buf_size);
if(msg.type == tkproto_TakionMessage_PayloadType_DISCONNECT)
stream_connection_takion_data_handle_disconnect(stream_connection, buf, buf_size);
}
static ChiakiErrorCode stream_connection_init_crypt(ChiakiStreamConnection *stream_connection)
@ -397,6 +441,12 @@ static void stream_connection_takion_data_expect_bang(ChiakiStreamConnection *st
if(msg.type != tkproto_TakionMessage_PayloadType_BANG || !msg.has_bang_payload)
{
if(msg.type == tkproto_TakionMessage_PayloadType_DISCONNECT)
{
stream_connection_takion_data_handle_disconnect(stream_connection, buf, buf_size);
return;
}
CHIAKI_LOGE(stream_connection->log, "StreamConnection expected bang payload but received something else");
return;
}
@ -531,6 +581,12 @@ static void stream_connection_takion_data_expect_streaminfo(ChiakiStreamConnecti
if(msg.type != tkproto_TakionMessage_PayloadType_STREAMINFO || !msg.has_stream_info_payload)
{
if(msg.type == tkproto_TakionMessage_PayloadType_DISCONNECT)
{
stream_connection_takion_data_handle_disconnect(stream_connection, buf, buf_size);
return;
}
CHIAKI_LOGE(stream_connection->log, "StreamConnection expected streaminfo payload but received something else");
chiaki_log_hexdump(stream_connection->log, CHIAKI_LOG_VERBOSE, buf, buf_size);
return;
@ -710,6 +766,8 @@ static ChiakiErrorCode stream_connection_send_disconnect(ChiakiStreamConnection
return CHIAKI_ERR_UNKNOWN;
}
CHIAKI_LOGI(stream_connection->log, "StreamConnection sending Disconnect");
buf_size = stream.bytes_written;
ChiakiErrorCode err = chiaki_takion_send_message_data(&stream_connection->takion, 1, 1, buf, buf_size);