1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_bluetooth_sapphire/internal/host/l2cap/enhanced_retransmission_mode_engines.h"
16
17 namespace bt::l2cap::internal {
18
19 // This factory function ensures that their states are properly linked and
20 // allows for unit tests of their linked behaviors without adding dependencies
21 // between the classes nor tie their lifetimes together. If tying their
22 // lifetimes together is desired, one should perhaps hold reference counts on
23 // the other to preserve the independence.
24 std::pair<std::unique_ptr<EnhancedRetransmissionModeRxEngine>,
25 std::unique_ptr<EnhancedRetransmissionModeTxEngine>>
MakeLinkedEnhancedRetransmissionModeEngines(ChannelId channel_id,uint16_t max_tx_sdu_size,uint8_t max_transmissions,uint8_t n_frames_in_tx_window,TxEngine::TxChannel & channel,EnhancedRetransmissionModeTxEngine::ConnectionFailureCallback connection_failure_callback,pw::async::Dispatcher & dispatcher)26 MakeLinkedEnhancedRetransmissionModeEngines(
27 ChannelId channel_id,
28 uint16_t max_tx_sdu_size,
29 uint8_t max_transmissions,
30 uint8_t n_frames_in_tx_window,
31 TxEngine::TxChannel& channel,
32 EnhancedRetransmissionModeTxEngine::ConnectionFailureCallback
33 connection_failure_callback,
34 pw::async::Dispatcher& dispatcher) {
35 auto rx_engine = std::make_unique<EnhancedRetransmissionModeRxEngine>(
36 fit::bind_member(&channel, &TxEngine::TxChannel::SendFrame),
37 connection_failure_callback.share());
38 auto tx_engine = std::make_unique<EnhancedRetransmissionModeTxEngine>(
39 channel_id,
40 max_tx_sdu_size,
41 max_transmissions,
42 n_frames_in_tx_window,
43 channel,
44 std::move(connection_failure_callback),
45 dispatcher);
46
47 // The direction swap here is because our acknowledgment sequence is based on
48 // the peer's transmit sequence and vice versa.
49 rx_engine->set_receive_seq_num_callback(
50 fit::bind_member<&EnhancedRetransmissionModeTxEngine::UpdateAckSeq>(
51 tx_engine.get()));
52 rx_engine->set_ack_seq_num_callback(
53 fit::bind_member<&EnhancedRetransmissionModeTxEngine::UpdateReqSeq>(
54 tx_engine.get()));
55 rx_engine->set_remote_busy_set_callback(
56 fit::bind_member<&EnhancedRetransmissionModeTxEngine::SetRemoteBusy>(
57 tx_engine.get()));
58 rx_engine->set_remote_busy_cleared_callback(
59 fit::bind_member<&EnhancedRetransmissionModeTxEngine::ClearRemoteBusy>(
60 tx_engine.get()));
61 rx_engine->set_single_retransmit_set_callback(
62 fit::bind_member<
63 &EnhancedRetransmissionModeTxEngine::SetSingleRetransmit>(
64 tx_engine.get()));
65 rx_engine->set_range_retransmit_set_callback(
66 fit::bind_member<&EnhancedRetransmissionModeTxEngine::SetRangeRetransmit>(
67 tx_engine.get()));
68 return {std::move(rx_engine), std::move(tx_engine)};
69 }
70
71 } // namespace bt::l2cap::internal
72