From a8d2c6c29fd0065156fe8c1bdd3e81102a96a837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Sun, 20 Dec 2020 17:03:05 +0100 Subject: [PATCH] Begin Stream v12 --- lib/include/chiaki/feedback.h | 14 +++++++++++--- lib/include/chiaki/launchspec.h | 2 ++ lib/include/chiaki/takion.h | 1 + lib/src/feedback.c | 10 +++++++++- lib/src/launchspec.c | 18 +++++++++++++++--- lib/src/session.c | 5 +++-- lib/src/streamconnection.c | 7 +++++-- lib/src/takion.c | 23 ++++++++++++++++++----- 8 files changed, 64 insertions(+), 16 deletions(-) diff --git a/lib/include/chiaki/feedback.h b/lib/include/chiaki/feedback.h index 6573a83..264af5c 100644 --- a/lib/include/chiaki/feedback.h +++ b/lib/include/chiaki/feedback.h @@ -21,13 +21,21 @@ typedef struct chiaki_feedback_state_t int16_t right_y; } ChiakiFeedbackState; -#define CHIAKI_FEEDBACK_STATE_BUF_SIZE 0x19 +#define CHIAKI_FEEDBACK_STATE_BUF_SIZE_MAX 0x1c + +#define CHIAKI_FEEDBACK_STATE_BUF_SIZE_V9 0x19 /** - * @param buf buffer of at least CHIAKI_FEEDBACK_STATE_BUF_SIZE + * @param buf buffer of at least CHIAKI_FEEDBACK_STATE_BUF_SIZE_V9 */ -CHIAKI_EXPORT void chiaki_feedback_state_format(uint8_t *buf, ChiakiFeedbackState *state); +CHIAKI_EXPORT void chiaki_feedback_state_format_v9(uint8_t *buf, ChiakiFeedbackState *state); +#define CHIAKI_FEEDBACK_STATE_BUF_SIZE_V12 0x1c + +/** + * @param buf buffer of at least CHIAKI_FEEDBACK_STATE_BUF_SIZE_V12 + */ +CHIAKI_EXPORT void chiaki_feedback_state_format_v12(uint8_t *buf, ChiakiFeedbackState *state); #define CHIAKI_HISTORY_EVENT_SIZE_MAX 0x5 diff --git a/lib/include/chiaki/launchspec.h b/lib/include/chiaki/launchspec.h index 0606280..770eb2a 100644 --- a/lib/include/chiaki/launchspec.h +++ b/lib/include/chiaki/launchspec.h @@ -14,12 +14,14 @@ extern "C" { typedef struct chiaki_launch_spec_t { + ChiakiTarget target; unsigned int mtu; unsigned int rtt; uint8_t *handshake_key; unsigned int width; unsigned int height; unsigned int max_fps; + ChiakiCodec codec; unsigned int bw_kbps_sent; } ChiakiLaunchSpec; diff --git a/lib/include/chiaki/takion.h b/lib/include/chiaki/takion.h index 01b5521..dba5872 100644 --- a/lib/include/chiaki/takion.h +++ b/lib/include/chiaki/takion.h @@ -110,6 +110,7 @@ typedef struct chiaki_takion_connect_info_t typedef struct chiaki_takion_t { ChiakiLog *log; + uint8_t version; /** * Whether encryption should be used. diff --git a/lib/src/feedback.c b/lib/src/feedback.c index 05c29b9..d5a46bc 100644 --- a/lib/src/feedback.c +++ b/lib/src/feedback.c @@ -10,7 +10,7 @@ #endif #include -CHIAKI_EXPORT void chiaki_feedback_state_format(uint8_t *buf, ChiakiFeedbackState *state) +CHIAKI_EXPORT void chiaki_feedback_state_format_v9(uint8_t *buf, ChiakiFeedbackState *state) { buf[0x0] = 0xa0; // TODO buf[0x1] = 0xff; // TODO @@ -35,6 +35,14 @@ CHIAKI_EXPORT void chiaki_feedback_state_format(uint8_t *buf, ChiakiFeedbackStat *((chiaki_unaligned_uint16_t *)(buf + 0x17)) = htons((uint16_t)state->right_y); } +CHIAKI_EXPORT void chiaki_feedback_state_format_v12(uint8_t *buf, ChiakiFeedbackState *state) +{ + chiaki_feedback_state_format_v9(buf, state); + buf[0x10] = 0x0; + buf[0x1a] = 0x0; + buf[0x1b] = 0x1; // 1 for Shock, 0 for Sense +} + CHIAKI_EXPORT ChiakiErrorCode chiaki_feedback_history_event_set_button(ChiakiFeedbackHistoryEvent *event, uint64_t button, uint8_t state) { // some buttons use a third byte for the state, some don't diff --git a/lib/src/launchspec.c b/lib/src/launchspec.c index d3b71b0..9da96ba 100644 --- a/lib/src/launchspec.c +++ b/lib/src/launchspec.c @@ -58,7 +58,9 @@ static const char launchspec_fmt[] = "\"region\":\"US\"," "\"languagesUsed\":[\"en\",\"jp\"]" "}," - "\"handshakeKey\":\"%s\"" // 6 + "%s" // 6 + "%s" // 7 + "\"handshakeKey\":\"%s\"" // 8 "}"; CHIAKI_EXPORT int chiaki_launchspec_format(char *buf, size_t buf_size, ChiakiLaunchSpec *launch_spec) @@ -68,10 +70,20 @@ CHIAKI_EXPORT int chiaki_launchspec_format(char *buf, size_t buf_size, ChiakiLau if(err != CHIAKI_ERR_SUCCESS) return -1; + char *extras[2]; + if(chiaki_target_is_ps5(launch_spec->target)) // TODO: probably also for ps4, but only 12 + { + extras[0] = "\"videoCodec\":\"avc\","; // TODO: hevc too + extras[1] = "\"dynamicRange\":\"SDR\","; // TODO: HDR too + } + else + extras[0] = extras[1] = ""; + int written = snprintf(buf, buf_size, launchspec_fmt, launch_spec->width, launch_spec->height, launch_spec->max_fps, - launch_spec->bw_kbps_sent, launch_spec->mtu, launch_spec->rtt, handshake_key_b64); + launch_spec->bw_kbps_sent, launch_spec->mtu, launch_spec->rtt, + extras[0], extras[1], handshake_key_b64); if(written < 0 || written >= buf_size) return -1; return written; -} \ No newline at end of file +} diff --git a/lib/src/session.c b/lib/src/session.c index 067344a..8a0d06e 100644 --- a/lib/src/session.c +++ b/lib/src/session.c @@ -370,6 +370,7 @@ static void *session_thread_func(void *arg) ChiakiTarget server_target = CHIAKI_TARGET_PS4_UNKNOWN; success = session_thread_request_session(session, &server_target) == CHIAKI_ERR_SUCCESS; + // TODO: Check Network error return if(!success && chiaki_target_is_unknown(server_target)) { @@ -653,7 +654,7 @@ static ChiakiErrorCode session_thread_request_session(ChiakiSession *session, Ch CHIAKI_LOGE(session->log, "Session request connect failed eventually."); if(session->quit_reason == CHIAKI_QUIT_REASON_NONE) session->quit_reason = CHIAKI_QUIT_REASON_SESSION_REQUEST_UNKNOWN; - return false; + return CHIAKI_ERR_NETWORK; } CHIAKI_LOGI(session->log, "Connected to %s:%d", session->connect_info.hostname, SESSION_PORT); @@ -690,7 +691,7 @@ static ChiakiErrorCode session_thread_request_session(ChiakiSession *session, Ch { CHIAKI_SOCKET_CLOSE(session_sock); session->quit_reason = CHIAKI_QUIT_REASON_SESSION_REQUEST_UNKNOWN; - return false; + return CHIAKI_ERR_UNKNOWN; } const char *rp_version_str = chiaki_rp_version_string(session->target); diff --git a/lib/src/streamconnection.c b/lib/src/streamconnection.c index 25caeb6..c8ed43c 100644 --- a/lib/src/streamconnection.c +++ b/lib/src/streamconnection.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: LicenseRef-AGPL-3.0-only-OpenSSL +#include "chiaki/common.h" #include #include #include @@ -142,7 +143,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stream_connection_run(ChiakiStreamConnectio takion_info.ip_dontfrag = false; takion_info.enable_crypt = true; - takion_info.protocol_version = 9; + takion_info.protocol_version = chiaki_target_is_ps5(session->target) ? 12 : 9; takion_info.cb = stream_connection_takion_cb; takion_info.cb_user = stream_connection; @@ -694,6 +695,7 @@ static ChiakiErrorCode stream_connection_send_big(ChiakiStreamConnection *stream ChiakiSession *session = stream_connection->session; ChiakiLaunchSpec launch_spec; + launch_spec.target = session->target; launch_spec.mtu = session->mtu_in; launch_spec.rtt = session->rtt_us / 1000; launch_spec.handshake_key = session->handshake_key; @@ -701,6 +703,7 @@ static ChiakiErrorCode stream_connection_send_big(ChiakiStreamConnection *stream launch_spec.width = session->connect_info.video_profile.width; launch_spec.height = session->connect_info.video_profile.height; launch_spec.max_fps = session->connect_info.video_profile.max_fps; + launch_spec.codec = session->connect_info.video_profile.codec; launch_spec.bw_kbps_sent = session->connect_info.video_profile.bitrate; union @@ -755,7 +758,7 @@ static ChiakiErrorCode stream_connection_send_big(ChiakiStreamConnection *stream msg.type = tkproto_TakionMessage_PayloadType_BIG; msg.has_big_payload = true; - msg.big_payload.client_version = 9; + msg.big_payload.client_version = stream_connection->takion.version; msg.big_payload.session_key.arg = session->session_id; msg.big_payload.session_key.funcs.encode = chiaki_pb_encode_string; msg.big_payload.launch_spec.arg = launch_spec_buf.b64; diff --git a/lib/src/takion.c b/lib/src/takion.c index 3e4a463..3439410 100644 --- a/lib/src/takion.c +++ b/lib/src/takion.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: LicenseRef-AGPL-3.0-only-OpenSSL +#include "chiaki/feedback.h" #include #include #include @@ -180,17 +181,19 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_connect(ChiakiTakion *takion, Chiaki ChiakiErrorCode ret = CHIAKI_ERR_SUCCESS; takion->log = info->log; + takion->version = info->protocol_version; - switch(info->protocol_version) + switch(takion->version) { case 7: takion->av_packet_parse = chiaki_takion_v7_av_packet_parse; break; case 9: + case 12: takion->av_packet_parse = chiaki_takion_v9_av_packet_parse; break; default: - CHIAKI_LOGE(takion->log, "Unknown Takion Protocol Version %u", (unsigned int)info->protocol_version); + CHIAKI_LOGE(takion->log, "Unknown Takion Protocol Version %u", (unsigned int)takion->version); return CHIAKI_ERR_INVALID_DATA; } @@ -541,14 +544,24 @@ beach: CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_state(ChiakiTakion *takion, ChiakiSeqNum16 seq_num, ChiakiFeedbackState *feedback_state) { - uint8_t buf[0xc + CHIAKI_FEEDBACK_STATE_BUF_SIZE]; + uint8_t buf[0xc + CHIAKI_FEEDBACK_STATE_BUF_SIZE_MAX]; buf[0] = TAKION_PACKET_TYPE_FEEDBACK_STATE; *((chiaki_unaligned_uint16_t *)(buf + 1)) = htons(seq_num); buf[3] = 0; // TODO *((chiaki_unaligned_uint32_t *)(buf + 4)) = 0; // key pos *((chiaki_unaligned_uint32_t *)(buf + 8)) = 0; // gmac - chiaki_feedback_state_format(buf + 0xc, feedback_state); - return takion_send_feedback_packet(takion, buf, sizeof(buf)); + size_t buf_sz; + if(takion->version <= 9) + { + buf_sz = CHIAKI_FEEDBACK_STATE_BUF_SIZE_V9; + chiaki_feedback_state_format_v9(buf + 0xc, feedback_state); + } + else + { + buf_sz = CHIAKI_FEEDBACK_STATE_BUF_SIZE_V12; + chiaki_feedback_state_format_v9(buf + 0xc, feedback_state); + } + return takion_send_feedback_packet(takion, buf, buf_sz); } CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_feedback_history(ChiakiTakion *takion, ChiakiSeqNum16 seq_num, uint8_t *payload, size_t payload_size)