diff --git a/src/stream.cpp b/src/stream.cpp index 3379878c..4685b05f 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -53,6 +53,11 @@ extern "C" { #define IDX_SET_ADAPTIVE_TRIGGERS 15 #define IDX_SET_INPUT_POLICY 16 +#define INPUT_POLICY_REASON_STREAM_START 0 +#define INPUT_POLICY_REASON_USER_TOGGLE 1 +#define INPUT_POLICY_REASON_HOST_ACK 2 +#define INPUT_POLICY_REASON_HOST_OVERRIDE 3 + static const short packetTypes[] = { 0x0305, // Start A 0x0307, // Start B @@ -475,6 +480,30 @@ namespace stream { << " mouse="sv << effective_mouse << " gamepad="sv << effective_gamepad; } + static int send_session_input_policy(session_t *session, uint8_t reason) { + if (!session->control.peer) { + return -1; + } + + control_set_input_policy_t plaintext; + plaintext.header.type = packetTypes[IDX_SET_INPUT_POLICY]; + plaintext.header.payloadLength = sizeof(plaintext) - sizeof(control_header_v2); + plaintext.allow_keyboard = session->input_policy.allow_keyboard.load(std::memory_order_relaxed) ? 1 : 0; + plaintext.allow_mouse = session->input_policy.allow_mouse.load(std::memory_order_relaxed) ? 1 : 0; + plaintext.allow_gamepad = session->input_policy.allow_gamepad.load(std::memory_order_relaxed) ? 1 : 0; + plaintext.reason = reason; + + std::array + encrypted_payload; + + auto payload = encode_control(session, util::view(plaintext), encrypted_payload); + if (session->broadcast_ref->control_server.send(payload, session->control.peer)) { + return -1; + } + + return 0; + } + /** * First part of cipher must be struct of type control_encrypted_t * @@ -993,6 +1022,10 @@ namespace stream { server->map(packetTypes[IDX_START_B], [&](session_t *session, const std::string_view &payload) { BOOST_LOG(debug) << "type [IDX_START_B]"sv; + + if (send_session_input_policy(session, INPUT_POLICY_REASON_STREAM_START)) { + BOOST_LOG(warning) << "Unable to send initial session input policy"sv; + } }); server->map(packetTypes[IDX_LOSS_STATS], [&](session_t *session, const std::string_view &payload) { @@ -1137,6 +1170,10 @@ namespace stream { policy->allow_mouse != 0, policy->allow_gamepad != 0, policy->reason); + + if (send_session_input_policy(session, INPUT_POLICY_REASON_HOST_ACK)) { + BOOST_LOG(warning) << "Unable to send input policy acknowledgment"sv; + } }); // This thread handles latency-sensitive control messages