Skip to main content

ibverbs_rs/channel/
builder.rs

1use crate::channel::Channel;
2use crate::channel::cached_completion_queue::CachedCompletionQueue;
3use crate::ibverbs::access_config::AccessFlags;
4use crate::ibverbs::error::IbvResult;
5use crate::ibverbs::protection_domain::ProtectionDomain;
6use crate::ibverbs::queue_pair::builder::{PreparedQueuePair, QueuePairEndpoint};
7use crate::ibverbs::queue_pair::config::*;
8use bon::bon;
9use std::cell::RefCell;
10use std::rc::Rc;
11
12#[bon]
13impl Channel {
14    #[builder(state_mod(vis = "pub"))]
15    pub fn builder(
16        pd: &ProtectionDomain,
17        #[builder(default =
18            AccessFlags::new()
19                .with_local_write()
20                .with_remote_read()
21                .with_remote_write()
22        )]
23        access: AccessFlags,
24        #[builder(default = 32)] min_cq_entries: u32,
25        #[builder(default = 16)] max_send_wr: u32,
26        #[builder(default = 16)] max_recv_wr: u32,
27        #[builder(default = 16)] max_send_sge: u32,
28        #[builder(default = 16)] max_recv_sge: u32,
29        #[builder(default)] max_rnr_retries: MaxRnrRetries,
30        #[builder(default)] max_ack_retries: MaxAckRetries,
31        #[builder(default)] min_rnr_timer: MinRnrTimer,
32        #[builder(default)] ack_timeout: AckTimeout,
33        #[builder(default)] mtu: MaximumTransferUnit,
34        #[builder(default)] send_psn: PacketSequenceNumber,
35        #[builder(default)] recv_psn: PacketSequenceNumber,
36    ) -> IbvResult<PreparedChannel> {
37        let cq = pd.context().create_cq(min_cq_entries)?;
38        let qp = pd
39            .create_qp()
40            .send_cq(&cq)
41            .recv_cq(&cq)
42            .access(access)
43            .max_send_wr(max_send_wr)
44            .max_recv_wr(max_recv_wr)
45            .max_send_sge(max_send_sge)
46            .max_recv_sge(max_recv_sge)
47            .max_rnr_retries(max_rnr_retries)
48            .max_ack_retries(max_ack_retries)
49            .min_rnr_timer(min_rnr_timer)
50            .ack_timeout(ack_timeout)
51            .mtu(mtu)
52            .send_psn(send_psn)
53            .recv_psn(recv_psn)
54            .build()?;
55
56        Ok(PreparedChannel {
57            cq: CachedCompletionQueue::wrap_cq(cq),
58            pd: pd.clone(),
59            qp,
60        })
61    }
62}
63
64/// A [`Channel`] that has been configured but not yet connected to a remote peer.
65///
66/// Created by [`Channel::builder`]. Call [`endpoint`](Self::endpoint) to obtain the
67/// local connection information, exchange it with the remote side, then call
68/// [`handshake`](Self::handshake) with the remote's endpoint to finish the connection.
69pub struct PreparedChannel {
70    cq: CachedCompletionQueue,
71    pd: ProtectionDomain,
72    qp: PreparedQueuePair,
73}
74
75impl PreparedChannel {
76    /// Returns the local endpoint information needed by the remote peer to complete the handshake.
77    pub fn endpoint(&self) -> QueuePairEndpoint {
78        self.qp.endpoint()
79    }
80
81    /// Connects to the remote peer and returns a ready-to-use [`Channel`].
82    pub fn handshake(self, endpoint: QueuePairEndpoint) -> IbvResult<Channel> {
83        let qp = self.qp.handshake(endpoint)?;
84        Ok(Channel {
85            qp,
86            cq: Rc::new(RefCell::new(self.cq)),
87            pd: self.pd,
88            next_wr_id: 0,
89        })
90    }
91}