// // tb_transport_private.h // Tightbeam #ifndef __TIGHTBEAM_TRANSPORT_PRIVATE_H #define __TIGHTBEAM_TRANSPORT_PRIVATE_H #include __ptrcheck_abi_assume_single() #include #include TB_ASSUME_NONNULL_BEGIN __TB_BEGIN_DECLS typedef struct tb_transport_static_context_s { _Alignas(8) char _opaque[TB_TRANSPORT_CONTEXT_SIZE]; } tb_transport_static_context_s, *tb_transport_static_context_t; struct tb_transport_connection_blocks_s { tb_transport_message_handler_b __TB_UNSAFE_UNRETAINED _Nullable connection_message_handler; tb_transport_message_handler_f _Nullable connection_message_handler_f; void* _Nullable connection_message_handler_context; } __TB_WARN_UNUSED_RESULT; struct tb_transport_vtable_s { tb_transport_send_message_f transport_send_message; tb_transport_activate_f transport_client_activate; tb_transport_activate_f transport_service_activate; tb_transport_construct_message_buffer_f transport_construct_message; tb_transport_destruct_message_buffer_f transport_destruct_message; tb_transport_reset_message_buffer_f transport_reset_message; tb_transport_supports_multipart_messages_f transport_supports_multipart_messages; tb_transport_get_tx_buffer_size_f transport_get_tx_buffer_size; tb_transport_destruct_f transport_destruct; tb_transport_construct_message_buffer_2_f transport_construct_message_2; tb_transport_destruct_message_buffer_2_f transport_destruct_message_2; tb_transport_reset_message_buffer_2_f transport_reset_message_2; } __TB_WARN_UNUSED_RESULT; typedef struct _tb_transport_s { /// A vtable of methods that the owning connection will call into. This /// represents the API surface from the connection to the (->) transport. struct tb_transport_vtable_s vtable; const struct tb_transport_vtable_s *static_vtable; /// A collection of blocks the connection has handed us that represent the /// transport (->) to connection API. struct tb_transport_connection_blocks_s con_table; /// Transport-specific data. Must maintain for out-of-tree transports. void *transport_priv; /// In-line transport-specific data. Used by in-tree transports to avoid an /// additional allocation. tb_transport_static_context_s inline_priv; } _tb_transport_s, *_tb_transport_t __TB_WARN_UNUSED_RESULT; #ifdef __RTKIT__ // rdar://117555447 Remove this redefintion once RTKit has moved over to using // accessors instead of direct access to the transport structure (or casting // the public structure to the private structure) struct tb_transport_s { /// A vtable of methods that the owning connection will call into. This represents the API surface /// from the connection to the (->) transport. struct tb_transport_vtable_s vtable; const struct tb_transport_vtable_s *static_vtable; /// A collection of blocks the connection has handed us that represent the transport (->) to connection /// API. struct tb_transport_connection_blocks_s con_table; /// Transport-specific data. Must maintain for out-of-tree transports. void *transport_priv; /// In-line transport-specific data. Used by in-tree transports to avoid an additional allocation. tb_transport_static_context_s inline_priv; }; #endif // See comment in cL4_transport_internal.h for why this is a `>=` check. _Static_assert(sizeof(struct tb_transport_s) >= sizeof(struct _tb_transport_s), ""); typedef uint8_t * __single tb_transport_message_payload_t; typedef void * __single tb_transport_context_t; // Make the field of this type usable for data structures #define TB_TRANSPORT_EXTRA_DATA_SIZE 48 struct tb_transport_message_buffer_opaque_data_s { _Alignas(8) uint8_t opaque[TB_TRANSPORT_EXTRA_DATA_SIZE]; }; struct tb_transport_message_buffer_s { /// A pointer to the start of the message payload buffer itself. tb_transport_message_payload_t __sized_by(size) payload; /// Whether the payload buffer is allocated and managed on the outside. bool wrapping; /// An offset to the position of the next readable/writable byte in the /// message payload buffer, including any reserved space. size_t position; /// The total size of the message buffer, including reserved or unwritten /// content. size_t size; /// The amount of space at the beginning of the buffer reserved for /// transport-specific data. size_t reserved; /// Whether this buffer is owned by the Connection layer or the transport. /// There are cases where the Connection layer may need to manually create /// a transport buffer, for example when sending a message that's larger /// than the transport can send in a single IPC payload. This flag will /// only be set by the Connection layer. bool connection_owned; bool destructed; /// Flags associated with the buffer that are to be interpreted by the /// transport. tb_transport_flags_t flags; /// A pointer to a transport-specific context. _Nullable tb_transport_context_t context; /// A bit of caller-provided memory for transport-specific data struct tb_transport_message_buffer_opaque_data_s data; } __TB_WARN_UNUSED_RESULT; TB_EXPORT void tb_transport_destruct(tb_transport_t transport); /// Initialize an empty transport message buffer. This will initialize all fields to 0 and pointers to NULL. /// /// @param buffer /// The buffer to initialize. TB_EXPORT void tb_transport_initialize_message_buffer( struct tb_transport_message_buffer_s *buffer); /// Reset a transport message buffer. This will initialize all connection-owned fields to 0 and pointers to NULL. /// /// @param buffer /// The buffer to initialize. TB_EXPORT void tb_transport_reset_message_buffer(struct tb_transport_message_buffer_s *buffer); /// Get the private data stored in the provided transport. /// /// @param tpt /// The transport to retrieve the private data for. /// /// @return A pointer to the transport-private data, NULL if not set. TB_EXPORT void * tb_transport_get_transport_private(tb_transport_t tpt); TB_EXPORT void * tb_transport_get_context(tb_transport_t tpt); /// Perform a deep copy of a transport message buffer. This will NOT copy the /// context or data pointers. These must be copied over manually as they are /// transport owned. /// /// @param dst /// The message buffer into which to copy the contents from `src`. /// /// @param src /// The message buffer from which to copy contents into `dst`. TB_EXPORT void tb_transport_message_buffer_deep_copy(tb_transport_message_buffer_t dst, tb_transport_message_buffer_t src); __TB_END_DECLS TB_ASSUME_NONNULL_END #endif // __TIGHTBEAM_TRANSPORT_PRIVATE_H