frame.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #pragma once
  2. #include <cstddef>
  3. #include <cstdint>
  4. #include <span>
  5. namespace sunrise::middleware::bap {
  6. /** Supported BAP outer-frame encodings. */
  7. enum class FrameType : std::uint8_t {
  8. /** Plaintext outer marker used by client requests. */
  9. plaintext0 = 0,
  10. /** Authenticated AES-GCM outer marker used after bootstrap. */
  11. encrypted = 1,
  12. /** Plaintext outer marker used by bootstrap request and response frames. */
  13. plaintext2 = 2,
  14. };
  15. /** Request services implemented by the in-process Server. */
  16. enum class RequestService : std::uint16_t {
  17. /** Uploads activity-selection state and gets one runtime activity-session id back. */
  18. activityHostManager = 6,
  19. /** Carries one authenticated client-to-activity-host message. */
  20. activityMessage = 8,
  21. /** Carries one client-to-server Web Service request envelope. */
  22. webService = 10,
  23. /** Carries one Web Service request on the server-role channel, answered on 112. */
  24. webServiceServer = 110,
  25. /** Registers one family and SOID selector for later pushes. */
  26. subscribeFamily = 12,
  27. /** Releases one previously declared family root. */
  28. unsubscribeFamily = 14,
  29. /** Requests a relay endpoint for one activity-host id. */
  30. activityHost = 16,
  31. /** Requests the current client-configuration response. */
  32. clientConfig = 18,
  33. /** Requests the current purchased-offers result set. */
  34. purchasedOffers = 21,
  35. /** Turns one request id into the active account SOID. */
  36. accountTranslation = 23,
  37. /** Exchanges the SignOn token for secure-channel parameters. */
  38. serverHello = 25,
  39. /** Carries a one-way client notification with no response service. */
  40. notification29 = 29,
  41. /** Starts the plaintext channel with a fixed nonce echo. */
  42. start = 30,
  43. /** Requests the current server-to-client user-message response. */
  44. userMessage = 32,
  45. /** Requests the skill records the Client keeps in its skill manager. */
  46. skill = 34,
  47. /** Carries the unnamed request paired with response service 37. */
  48. request36 = 36,
  49. /** Carries the unnamed request paired with response service 39. */
  50. request38 = 38,
  51. /** Carries the unnamed request paired with response service 41. */
  52. request40 = 40,
  53. /** Carries one of the 8 matchmaking request variants. Body field two picks it. */
  54. matchmaking = 42,
  55. /** Carries the unnamed request paired with response service 49. */
  56. request48 = 48,
  57. /** Carries a clan protobuf request that the minimal liveness route leaves unparsed. */
  58. clan = 44,
  59. /** Registers the client as a notification subscriber. */
  60. registerSubscriber = 121,
  61. /** Carries a large one-way client notification with no response service. */
  62. notification171 = 171,
  63. /** Keeps an authenticated connection active. */
  64. echo = 250,
  65. /** Registers the client with the relay service. */
  66. registerRelayClient = 302,
  67. /** Wraps the client-owned Steam certificate for the response. */
  68. signSteamCertificate = 304,
  69. /** Carries the opaque request paired with response service 307. */
  70. accountFromMembership = 306,
  71. };
  72. /** Response services emitted by the in-process Server. */
  73. enum class ResponseService : std::uint16_t {
  74. /** Returns one runtime activity-session id and the least activity data. */
  75. activityHostManager = 7,
  76. /** Returns one server-to-client Web Service response envelope. */
  77. webService = 11,
  78. /** Returns one Web Service response on the server-role channel for request 110. */
  79. webServiceServer = 112,
  80. /** Acknowledges a family subscription with an empty status-200 body. */
  81. subscribeFamily = 13,
  82. /** Acknowledges a family unsubscribe with an empty status-200 body. */
  83. unsubscribeFamily = 15,
  84. /** Returns a relay endpoint for one activity-host id. */
  85. activityHost = 17,
  86. /** Returns the current client-configuration fields. */
  87. clientConfig = 19,
  88. /** Returns the purchased-offers result set. */
  89. purchasedOffers = 22,
  90. /** Returns one request id paired with the active account SOID. */
  91. accountTranslation = 24,
  92. /** Returns secure-channel parameters after SignOn token validation. */
  93. serverHello = 26,
  94. /** Echoes the fixed channel-start nonce. */
  95. start = 31,
  96. /** Returns the current user-message fields. */
  97. userMessage = 33,
  98. /** Returns an empty skill record list, which is a count of zero. */
  99. skill = 35,
  100. /** Acknowledges service 36 with an empty status-200 body. */
  101. response37 = 37,
  102. /** Acknowledges service 38 with an empty status-200 body. */
  103. response39 = 39,
  104. /** Acknowledges service 40 with an empty status-200 body. */
  105. response41 = 41,
  106. /** Returns the request-kind-specific matchmaking result. */
  107. matchmaking = 43,
  108. /** Acknowledges service 48 with an empty status-200 body. */
  109. response49 = 49,
  110. /** Returns schema-valid empty clan data with status 200. */
  111. clan = 45,
  112. /** Acknowledges notification subscriber registration. */
  113. registerSubscriber = 122,
  114. /** Acknowledges an authenticated keepalive. */
  115. echo = 251,
  116. /** Acknowledges relay registration. */
  117. registerRelayClient = 303,
  118. /** Returns the client-owned Steam certificate wrapper. */
  119. signSteamCertificate = 305,
  120. /** Acknowledges service 306 with an empty status-200 body. */
  121. accountFromMembership = 307,
  122. };
  123. /** Server-initiated services emitted without a response status field. */
  124. enum class NotificationService : std::uint16_t {
  125. /** Publishes one uncorrelated activity-host message. */
  126. activityMessage = 9,
  127. /** Publishes one or more queuez family updates. */
  128. queuezUpdate = 123,
  129. };
  130. /** Parsed BAP request header and borrowed body. */
  131. struct RequestFrame {
  132. FrameType frameType{};
  133. std::uint16_t messageId{};
  134. std::uint32_t taskId{};
  135. std::span<const std::byte> body{};
  136. };
  137. /** Parsed outer BAP frame and borrowed payload. */
  138. struct OuterFrame {
  139. FrameType frameType{};
  140. std::span<const std::byte> payload{};
  141. };
  142. /** Reads one BAP outer header and borrows the payload its length names. */
  143. [[nodiscard]] bool parse_frame(std::span<const std::byte> input, OuterFrame& frame) noexcept;
  144. /** Parses one decrypted or plaintext BAP request payload. */
  145. [[nodiscard]] bool parse_request_payload(std::span<const std::byte> input,
  146. FrameType frameType,
  147. RequestFrame& request) noexcept;
  148. /** Parses one complete plaintext BAP request frame. */
  149. [[nodiscard]] bool parse_request(std::span<const std::byte> input, RequestFrame& request) noexcept;
  150. /** Encodes one plaintext BAP response frame with status 200. */
  151. [[nodiscard]] bool encode_response(ResponseService service,
  152. std::uint32_t taskId,
  153. FrameType frameType,
  154. std::span<const std::byte> body,
  155. std::span<std::byte> output,
  156. std::size_t& written) noexcept;
  157. /** Encodes a BAP response inner header and body. */
  158. [[nodiscard]] bool encode_response_payload(ResponseService service,
  159. std::uint32_t taskId,
  160. std::span<const std::byte> body,
  161. std::span<std::byte> output,
  162. std::size_t& written) noexcept;
  163. /**
  164. * Encodes one 6-byte notification header and body. There is no response status field.
  165. * @param sequence Server-chosen notification sequence.
  166. * @param output Caller-owned payload storage.
  167. * @param written Receives encoded payload bytes.
  168. * @return True when sizes fit the wire length and output storage.
  169. */
  170. [[nodiscard]] bool encode_notification_payload(NotificationService service,
  171. std::uint32_t sequence,
  172. std::span<const std::byte> body,
  173. std::span<std::byte> output,
  174. std::size_t& written) noexcept;
  175. /** Encodes one BAP outer frame around an existing payload. */
  176. [[nodiscard]] bool encode_frame(FrameType frameType,
  177. std::span<const std::byte> payload,
  178. std::span<std::byte> output,
  179. std::size_t& written) noexcept;
  180. } // namespace sunrise::middleware::bap