From 912b46ed41e4dcb442e686f1b1b6536eb0ab70a3 Mon Sep 17 00:00:00 2001 From: jbesraa Date: Wed, 6 Nov 2024 09:47:30 +0200 Subject: [PATCH 1/4] Use shorter relative path .. and fix some styling inconsistency --- .../v2/subprotocols/common-messages/Cargo.toml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/protocols/v2/subprotocols/common-messages/Cargo.toml b/protocols/v2/subprotocols/common-messages/Cargo.toml index e2343d0de3..3837023314 100644 --- a/protocols/v2/subprotocols/common-messages/Cargo.toml +++ b/protocols/v2/subprotocols/common-messages/Cargo.toml @@ -14,12 +14,12 @@ keywords = ["stratum", "mining", "bitcoin", "protocol"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -serde = { version = "1.0.89", default-features = false, optional= true } -binary_sv2 = {version = "^1.0.0", path = "../../../../protocols/v2/binary-sv2/binary-sv2" } -const_sv2 = {version = "^2.0.0", path = "../../../../protocols/v2/const-sv2"} -quickcheck = { version = "1.0.3", optional=true } -quickcheck_macros = { version = "1", optional=true } -serde_repr = {version= "0.1.10", optional=true} +serde = { version = "1.0.89", default-features = false, optional = true } +binary_sv2 = { version = "^1.0.0", path = "../../binary-sv2/binary-sv2" } +const_sv2 = { version = "^2.0.0", path = "../../const-sv2" } +quickcheck = { version = "1.0.3", optional = true } +quickcheck_macros = { version = "1", optional = true } +serde_repr = { version= "0.1.10", optional = true } [features] no_std = [] @@ -27,4 +27,4 @@ with_serde = ["binary_sv2/with_serde", "serde", "serde_repr"] prop_test = ["quickcheck"] [package.metadata.docs.rs] -all-features = true \ No newline at end of file +all-features = true From b5b52c10f0b95e22d88a12568bcb1ac4a35a1494 Mon Sep 17 00:00:00 2001 From: jbesraa Date: Tue, 5 Nov 2024 17:31:33 +0200 Subject: [PATCH 2/4] Rewrite docs in `common_messages_sv2` .. As part of the effort to improve Stratum V2 protocols docs, this commit aims to improves and make the documentation more comprehensive and accessible for contributors and end users alike. --- .../src/channel_endpoint_changed.rs | 16 +- .../subprotocols/common-messages/src/lib.rs | 20 ++- .../common-messages/src/setup_connection.rs | 146 ++++++++++++------ 3 files changed, 126 insertions(+), 56 deletions(-) diff --git a/protocols/v2/subprotocols/common-messages/src/channel_endpoint_changed.rs b/protocols/v2/subprotocols/common-messages/src/channel_endpoint_changed.rs index dd28091c95..795a6c4491 100644 --- a/protocols/v2/subprotocols/common-messages/src/channel_endpoint_changed.rs +++ b/protocols/v2/subprotocols/common-messages/src/channel_endpoint_changed.rs @@ -6,16 +6,18 @@ use binary_sv2::{Deserialize, Serialize}; #[cfg(not(feature = "with_serde"))] use core::convert::TryInto; -/// ## ChannelEndpointChanged (Server -> Client) -/// When a channel’s upstream or downstream endpoint changes and that channel had previously -/// sent messages with [channel_msg] bitset of unknown extension_type, the intermediate proxy -/// MUST send a [`ChannelEndpointChanged`] message. Upon receipt thereof, any extension state -/// (including version negotiation and the presence of support for a given extension) MUST be -/// reset and version/presence negotiation must begin again. +/// Message used by an upstream role for announcing a mining channel endpoint change. +/// +/// This message should be sent when a mining channel’s upstream or downstream endpoint changes and +/// that channel had previously exchanged message(s) with `channel_msg` bitset of unknown +/// `extension_type`. +/// +/// When a downstream receives such a message, any extension state (including version and extension +/// support) must be reset and renegotiated. #[repr(C)] #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq)] pub struct ChannelEndpointChanged { - /// The channel which has changed endpoint. + /// Unique identifier of the channel that has changed its endpoint. pub channel_id: u32, } #[cfg(feature = "with_serde")] diff --git a/protocols/v2/subprotocols/common-messages/src/lib.rs b/protocols/v2/subprotocols/common-messages/src/lib.rs index cc0df87a2b..eb897ee214 100644 --- a/protocols/v2/subprotocols/common-messages/src/lib.rs +++ b/protocols/v2/subprotocols/common-messages/src/lib.rs @@ -1,7 +1,19 @@ +//! # Stratum V2 Common Messages Crate. +//! +//! This crate defines a set of shared messages used across all Stratum V2 subprotocols. +//! +//! ## Build Options +//! This crate can be built with the following features: +//! - `std`: Enables support for standard library features. +//! - `serde`: Enables support for serialization and deserialization using Serde. +//! - `quickcheck`: Enables support for property-based testing using QuickCheck. +//! +//! *Note that `serde` feature flag is only used for the Message Generator, and deprecated for any +//! other kind of usage. It will likely be fully deprecated in the future.* +//! +//! For further information about the messages, please refer to [Stratum V2 +//! documentation - Common Messages](https://stratumprotocol.org/specification/03-Protocol-Overview/#36-common-protocol-messages). #![cfg_attr(feature = "no_std", no_std)] - -//! Common messages for [stratum v2][Sv2] -//! The following protocol messages are common across all of the sv2 (sub)protocols. extern crate alloc; mod channel_endpoint_changed; mod setup_connection; @@ -23,10 +35,12 @@ pub use setup_connection::{CSetupConnection, CSetupConnectionError}; #[cfg(not(feature = "with_serde"))] #[no_mangle] +/// A C-compatible function that exports the [`ChannelEndpointChanged`] struct. pub extern "C" fn _c_export_channel_endpoint_changed(_a: ChannelEndpointChanged) {} #[cfg(not(feature = "with_serde"))] #[no_mangle] +/// A C-compatible function that exports the `SetupConnection` struct. pub extern "C" fn _c_export_setup_conn_succ(_a: SetupConnectionSuccess) {} #[cfg(feature = "prop_test")] diff --git a/protocols/v2/subprotocols/common-messages/src/setup_connection.rs b/protocols/v2/subprotocols/common-messages/src/setup_connection.rs index 7bf3308325..828add4fac 100644 --- a/protocols/v2/subprotocols/common-messages/src/setup_connection.rs +++ b/protocols/v2/subprotocols/common-messages/src/setup_connection.rs @@ -16,46 +16,61 @@ use core::convert::TryInto; #[cfg(feature = "with_serde")] use serde_repr::*; -/// ## SetupConnection (Client -> Server) -/// Initiates the connection. This MUST be the first message sent by the client on the newly -/// opened connection. Server MUST respond with either a [`SetupConnectionSuccess`] or -/// [`SetupConnectionError`] message. Clients that are not configured to provide telemetry data to -/// the upstream node SHOULD set device_id to 0-length strings. However, they MUST always set -/// vendor to a string describing the manufacturer/developer and firmware version and SHOULD -/// always set hardware_version to a string describing, at least, the particular hardware/software -/// package in use. +/// Used by downstream to initiate a Stratum V2 connection with an upstream role. +/// +/// This is usually the first message sent by a downstream role on a newly opened connection, +/// after completing the handshake process. +/// +/// Downstreams that do not wish to provide telemetry data to the upstream role **should** set +/// [`SetupConnection::device_id`] to an empty string. However, they **must** set +/// [`SetupConnection::vendor`] to a string describing the manufacturer/developer and firmware +/// version and **should** set [`SetupConnection::hardware_version`] to a string describing, at +/// least, the particular hardware/software package in use. +/// +/// A valid response to this message from the upstream role can either be [`SetupConnectionSuccess`] +/// or [`SetupConnectionError`] message. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub struct SetupConnection<'decoder> { - /// [`Protocol`] + /// Protocol to be used for the connection. pub protocol: Protocol, - /// The minimum protocol version the client supports (currently must be 2). + /// The minimum protocol version supported. + /// + /// Currently must be set to 2. pub min_version: u16, - /// The maximum protocol version the client supports (currently must be 2). + /// The maximum protocol version supported. + /// + /// Currently must be set to 2. pub max_version: u16, - /// Flags indicating optional protocol features the client supports. Each - /// protocol from [`SetupConnection.protocol`] field has its own values/flags. + /// Flags indicating optional protocol features supported by the downstream. + /// + /// Each [`SetupConnection::protocol`] value has it's own flags. pub flags: u32, - /// ASCII text indicating the hostname or IP address. + /// ASCII representation of the connection hostname or IP address. #[cfg_attr(feature = "with_serde", serde(borrow))] pub endpoint_host: Str0255<'decoder>, - /// Connecting port value + /// Connection port value. pub endpoint_port: u16, - //-- DEVICE INFORMATION --// + /// Device vendor name. #[cfg_attr(feature = "with_serde", serde(borrow))] pub vendor: Str0255<'decoder>, + /// Device hardware version. #[cfg_attr(feature = "with_serde", serde(borrow))] pub hardware_version: Str0255<'decoder>, + /// Device firmware version. #[cfg_attr(feature = "with_serde", serde(borrow))] pub firmware: Str0255<'decoder>, + /// Device identifier. #[cfg_attr(feature = "with_serde", serde(borrow))] pub device_id: Str0255<'decoder>, } impl<'decoder> SetupConnection<'decoder> { + /// Set the flag to indicate that the downstream requires a standard job pub fn set_requires_standard_job(&mut self) { self.flags |= 0b_0000_0000_0000_0000_0000_0000_0000_0001; } + /// Set the flag to indicate that the downstream requires an asynchronous job negotiation pub fn set_async_job_nogotiation(&mut self) { self.flags |= 0b_0000_0000_0000_0000_0000_0000_0000_0001; } @@ -128,7 +143,10 @@ impl<'decoder> SetupConnection<'decoder> { } } - /// Check if passed versions support self versions if yes return the biggest version available + /// Check whether received versions are supported. + /// + /// If the versions are not supported, return `None` otherwise return the biggest version + /// available pub fn get_version(&self, min_version: u16, max_version: u16) -> Option { if self.min_version > max_version || min_version > self.max_version { None @@ -137,22 +155,28 @@ impl<'decoder> SetupConnection<'decoder> { } } + /// Checks whether passed flags indicate that the downstream requires standard job. pub fn requires_standard_job(&self) -> bool { has_requires_std_job(self.flags) } } +/// Helper function to check if `REQUIRES_STANDARD_JOBS` bit flag present. pub fn has_requires_std_job(flags: u32) -> bool { let flags = flags.reverse_bits(); let flag = flags >> 31; flag != 0 } + +/// Helper function to check if `REQUIRES_VERSION_ROLLING` bit flag present. pub fn has_version_rolling(flags: u32) -> bool { let flags = flags.reverse_bits(); let flags = flags << 1; let flag = flags >> 31; flag != 0 } + +/// Helper function to check if `REQUIRES_WORK_SELECTION` bit flag present. pub fn has_work_selection(flags: u32) -> bool { let flags = flags.reverse_bits(); let flags = flags << 2; @@ -160,19 +184,36 @@ pub fn has_work_selection(flags: u32) -> bool { flag != 0 } +/// C representation of [`SetupConnection`] #[repr(C)] #[cfg(not(feature = "with_serde"))] #[derive(Debug, Clone)] pub struct CSetupConnection { + /// Protocol to be used for the connection. pub protocol: Protocol, + /// The minimum protocol version supported. + /// + /// Currently must be set to 2. pub min_version: u16, + /// The maximum protocol version supported. + /// + /// Currently must be set to 2. pub max_version: u16, + /// Flags indicating optional protocol features supported by the downstream. + /// + /// Each [`SetupConnection::protocol`] value has it's own flags. pub flags: u32, + /// ASCII representation of the connection hostname or IP address. pub endpoint_host: CVec, + /// Connection port value. pub endpoint_port: u16, + /// Device vendor name. pub vendor: CVec, + /// Device hardware version. pub hardware_version: CVec, + /// Device firmware version. pub firmware: CVec, + /// Device identifier. pub device_id: CVec, } @@ -180,6 +221,7 @@ pub struct CSetupConnection { impl<'a> CSetupConnection { #[cfg(not(feature = "with_serde"))] #[allow(clippy::wrong_self_convention)] + /// Convert C representation to Rust representation pub fn to_rust_rep_mut(&'a mut self) -> Result, Error> { let endpoint_host: Str0255 = self.endpoint_host.as_mut_slice().try_into()?; let vendor: Str0255 = self.vendor.as_mut_slice().try_into()?; @@ -237,42 +279,51 @@ impl<'a> From> for CSetupConnection { } } -/// ## SetupConnection.Success (Server -> Client) -/// Response to [`SetupConnection`] message if the server accepts the connection. The client is -/// required to verify the set of feature flags that the server supports and act accordingly. +/// Message used by an upstream role to accept a connection setup request from a downstream role. +/// +/// This message is sent in response to a [`SetupConnection`] message. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Copy)] #[repr(C)] pub struct SetupConnectionSuccess { - /// Selected version proposed by the connecting node that the upstream - /// node supports. This version will be used on the connection for the rest - /// of its life. + /// Selected version based on the [`SetupConnection::min_version`] and + /// [`SetupConnection::max_version`] sent by the downstream role. + /// + /// This version will be used on the connection for the rest of its life. pub used_version: u16, - /// Flags indicating optional protocol features the server supports. Each - /// protocol from [`Protocol`] field has its own values/flags. + /// Flags indicating optional protocol features supported by the upstream. + /// + /// The downstream is required to verify this set of flags and act accordingly. + /// + /// Each [`SetupConnection::protocol`] field has its own values/flags. pub flags: u32, } -/// ## SetupConnection.Error (Server -> Client) -/// When protocol version negotiation fails (or there is another reason why the upstream node -/// cannot setup the connection) the server sends this message with a particular error code prior -/// to closing the connection. -/// In order to allow a client to determine the set of available features for a given server (e.g. -/// for proxies which dynamically switch between different pools and need to be aware of supported -/// options), clients SHOULD send a SetupConnection message with all flags set and examine the -/// (potentially) resulting [`SetupConnectionError`] message’s flags field. The Server MUST provide -/// the full set of flags which it does not support in each [`SetupConnectionError`] message and -/// MUST consistently support the same set of flags across all servers on the same hostname and -/// port number. If flags is 0, the error is a result of some condition aside from unsupported -/// flags. +/// Message used by an upstream role to reject a connection setup request from a downstream role. +/// +/// This message is sent in response to a [`SetupConnection`] message. +/// +/// The connection setup process could fail because of protocol version negotiation. In order to +/// allow a downstream to determine the set of available features for a given upstream (e.g. for +/// proxies which dynamically switch between different pools and need to be aware of supported +/// options), downstream should send a [`SetupConnection`] message with all flags set and examine +/// the (potentially) resulting [`SetupConnectionError`] message’s flags field. +/// +/// The upstream must provide the full set of flags which it does not support in each +/// [`SetupConnectionError`] message and must consistently support the same set of flags across all +/// servers on the same hostname and port number. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub struct SetupConnectionError<'decoder> { - /// Flags indicating features causing an error. + /// Unsupported feature flags. + /// + /// In case `error_code` is `unsupported-feature-flags`, this field is used to indicate which + /// flag is causing an error, otherwise it will be set to 0. pub flags: u32, - /// Human-readable error code(s). See Error Codes section, [link]. - /// ### Possible error codes: - /// * ‘unsupported-feature-flags’ - /// * ‘unsupported-protocol’ - /// * ‘protocol-version-mismatch’ + /// Reason for setup connection error. + /// + /// Possible error codes: + /// - unsupported-feature-flags + /// - unsupported-protocol + /// - protocol-version-mismatch #[cfg_attr(feature = "with_serde", serde(borrow))] pub error_code: Str0255<'decoder>, } @@ -280,6 +331,7 @@ pub struct SetupConnectionError<'decoder> { #[repr(C)] #[cfg(not(feature = "with_serde"))] #[derive(Debug, Clone)] +/// C representation of [`SetupConnectionError`] pub struct CSetupConnectionError { flags: u32, error_code: CVec, @@ -289,6 +341,7 @@ pub struct CSetupConnectionError { impl<'a> CSetupConnectionError { #[cfg(not(feature = "with_serde"))] #[allow(clippy::wrong_self_convention)] + /// Convert C representation to Rust representation pub fn to_rust_rep_mut(&'a mut self) -> Result, Error> { let error_code: Str0255 = self.error_code.as_mut_slice().try_into()?; @@ -322,16 +375,17 @@ impl<'a> From> for CSetupConnectionError { } } -/// MiningProtocol = [`SV2_MINING_PROTOCOL_DISCRIMINANT`], -/// JobDeclarationProtocol = [`SV2_JOB_DECLARATION_PROTOCOL_DISCRIMINANT`], -/// TemplateDistributionProtocol = [`SV2_TEMPLATE_DISTR_PROTOCOL_DISCRIMINANT`], +/// This enum has a list of the different Stratum V2 subprotocols. #[cfg_attr(feature = "with_serde", derive(Serialize_repr, Deserialize_repr))] #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(u8)] #[allow(clippy::enum_variant_names)] pub enum Protocol { + /// Mining protocol. MiningProtocol = SV2_MINING_PROTOCOL_DISCRIMINANT, + /// Job declaration protocol. JobDeclarationProtocol = SV2_JOB_DECLARATION_PROTOCOL_DISCRIMINANT, + /// Template distribution protocol. TemplateDistributionProtocol = SV2_TEMPLATE_DISTR_PROTOCOL_DISCRIMINANT, } From f0891d1528703743ffa6069464bde3da1ad2b886 Mon Sep 17 00:00:00 2001 From: esraa Date: Tue, 29 Oct 2024 13:31:48 +0200 Subject: [PATCH 3/4] Add README.md .. Use the template README used across the different Stratum V2 protocol crates to `common_messages_sv2` crate. --- .../v2/subprotocols/common-messages/README.md | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 protocols/v2/subprotocols/common-messages/README.md diff --git a/protocols/v2/subprotocols/common-messages/README.md b/protocols/v2/subprotocols/common-messages/README.md new file mode 100644 index 0000000000..721feec8bb --- /dev/null +++ b/protocols/v2/subprotocols/common-messages/README.md @@ -0,0 +1,30 @@ +# common_messages_sv2 + +[![crates.io](https://img.shields.io/crates/v/common_messages_sv2.svg)](https://crates.io/crates/common_messages_sv2) +[![docs.rs](https://docs.rs/common_messages_sv2/badge.svg)](https://docs.rs/common_messages_sv2) +[![rustc+](https://img.shields.io/badge/rustc-1.75.0%2B-lightgrey.svg)](https://blog.rust-lang.org/2023/12/28/Rust-1.75.0.html) +[![license](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](https://github.com/stratum-mining/stratum/blob/main/LICENSE.md) +[![codecov](https://codecov.io/gh/stratum-mining/stratum/branch/main/graph/badge.svg)](https://app.codecov.io/gh/stratum-mining/stratum/tree/main/protocols%2Fv2%2Fcommon_messages_sv2) + +`common_messages_sv2` is a Rust crate that implements a set of messages shared across all Stratum V2 subprotocols. + +For further information, please refer to [Stratum V2 documentation - Common Messages](https://stratumprotocol.org/specification/03-Protocol-Overview/#36-common-protocol-messages). + +## Build Options + +This crate can be built with the following features: + + - `std`: Enables support for standard library features. + - `serde`: Enables support for serialization and deserialization using Serde. + - `quickcheck`: Enables support for property-based testing using QuickCheck. + + *Note that `serde` feature flag is only used for the Message Generator, and deprecated for any + other kind of usage. It will likely be fully deprecated in the future.* + +## Usage + +To include this crate in your project, run: + +```bash +$ cargo add common_messages_sv2 +``` From aadf42dfac092d70b2bb6141cd92035ec5a0c693 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Wed, 4 Dec 2024 14:23:26 +0530 Subject: [PATCH 4/4] modify sv2.h to make it consistent with comments changes --- protocols/v2/sv2-ffi/sv2.h | 63 +++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/protocols/v2/sv2-ffi/sv2.h b/protocols/v2/sv2-ffi/sv2.h index ba7b7803c0..19561eb4ef 100644 --- a/protocols/v2/sv2-ffi/sv2.h +++ b/protocols/v2/sv2-ffi/sv2.h @@ -286,52 +286,77 @@ void _c_export_cvec2(CVec2 _a); #include #include -/// MiningProtocol = [`SV2_MINING_PROTOCOL_DISCRIMINANT`], -/// JobDeclarationProtocol = [`SV2_JOB_DECLARATION_PROTOCOL_DISCRIMINANT`], -/// TemplateDistributionProtocol = [`SV2_TEMPLATE_DISTR_PROTOCOL_DISCRIMINANT`], +/// This enum has a list of the different Stratum V2 subprotocols. enum class Protocol : uint8_t { + /// Mining protocol. MiningProtocol = SV2_MINING_PROTOCOL_DISCRIMINANT, + /// Job declaration protocol. JobDeclarationProtocol = SV2_JOB_DECLARATION_PROTOCOL_DISCRIMINANT, + /// Template distribution protocol. TemplateDistributionProtocol = SV2_TEMPLATE_DISTR_PROTOCOL_DISCRIMINANT, }; -/// ## ChannelEndpointChanged (Server -> Client) -/// When a channel’s upstream or downstream endpoint changes and that channel had previously -/// sent messages with [channel_msg] bitset of unknown extension_type, the intermediate proxy -/// MUST send a [`ChannelEndpointChanged`] message. Upon receipt thereof, any extension state -/// (including version negotiation and the presence of support for a given extension) MUST be -/// reset and version/presence negotiation must begin again. +/// Message used by an upstream role for announcing a mining channel endpoint change. +/// +/// This message should be sent when a mining channel’s upstream or downstream endpoint changes and +/// that channel had previously exchanged message(s) with `channel_msg` bitset of unknown +/// `extension_type`. +/// +/// When a downstream receives such a message, any extension state (including version and extension +/// support) must be reset and renegotiated. struct ChannelEndpointChanged { - /// The channel which has changed endpoint. + /// Unique identifier of the channel that has changed its endpoint. uint32_t channel_id; }; -/// ## SetupConnection.Success (Server -> Client) -/// Response to [`SetupConnection`] message if the server accepts the connection. The client is -/// required to verify the set of feature flags that the server supports and act accordingly. +/// Message used by an upstream role to accept a connection setup request from a downstream role. +/// +/// This message is sent in response to a [`SetupConnection`] message. struct SetupConnectionSuccess { - /// Selected version proposed by the connecting node that the upstream - /// node supports. This version will be used on the connection for the rest - /// of its life. + /// Selected version based on the [`SetupConnection::min_version`] and + /// [`SetupConnection::max_version`] sent by the downstream role. + /// + /// This version will be used on the connection for the rest of its life. uint16_t used_version; - /// Flags indicating optional protocol features the server supports. Each - /// protocol from [`Protocol`] field has its own values/flags. + /// Flags indicating optional protocol features supported by the upstream. + /// + /// The downstream is required to verify this set of flags and act accordingly. + /// + /// Each [`SetupConnection::protocol`] field has its own values/flags. uint32_t flags; }; +/// C representation of [`SetupConnection`] struct CSetupConnection { + /// Protocol to be used for the connection. Protocol protocol; + /// The minimum protocol version supported. + /// + /// Currently must be set to 2. uint16_t min_version; + /// The maximum protocol version supported. + /// + /// Currently must be set to 2. uint16_t max_version; + /// Flags indicating optional protocol features supported by the downstream. + /// + /// Each [`SetupConnection::protocol`] value has it's own flags. uint32_t flags; + /// ASCII representation of the connection hostname or IP address. CVec endpoint_host; + /// Connection port value. uint16_t endpoint_port; + /// Device vendor name. CVec vendor; + /// Device hardware version. CVec hardware_version; + /// Device firmware version. CVec firmware; + /// Device identifier. CVec device_id; }; +/// C representation of [`SetupConnectionError`] struct CSetupConnectionError { uint32_t flags; CVec error_code; @@ -339,8 +364,10 @@ struct CSetupConnectionError { extern "C" { +/// A C-compatible function that exports the [`ChannelEndpointChanged`] struct. void _c_export_channel_endpoint_changed(ChannelEndpointChanged _a); +/// A C-compatible function that exports the `SetupConnection` struct. void _c_export_setup_conn_succ(SetupConnectionSuccess _a); void free_setup_connection(CSetupConnection s);