1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "l2cap/internal/enhanced_retransmission_mode_channel_data_controller.h"
18
19 #include <bluetooth/log.h>
20
21 #include <map>
22 #include <queue>
23 #include <vector>
24
25 #include "common/bind.h"
26 #include "l2cap/internal/ilink.h"
27 #include "os/alarm.h"
28 #include "packet/fragmenting_inserter.h"
29 #include "packet/raw_builder.h"
30
31 namespace bluetooth {
32 namespace l2cap {
33 namespace internal {
ErtmController(ILink * link,Cid cid,Cid remote_cid,UpperQueueDownEnd * channel_queue_end,os::Handler * handler,Scheduler * scheduler)34 ErtmController::ErtmController(ILink* link, Cid cid, Cid remote_cid, UpperQueueDownEnd* channel_queue_end,
35 os::Handler* handler, Scheduler* scheduler)
36 : link_(link), cid_(cid), remote_cid_(remote_cid), enqueue_buffer_(channel_queue_end), handler_(handler),
37 scheduler_(scheduler), pimpl_(std::make_unique<impl>(this, handler)) {}
38
~ErtmController()39 ErtmController::~ErtmController() {
40 enqueue_buffer_.Clear();
41 }
42
43 struct ErtmController::impl {
implbluetooth::l2cap::internal::ErtmController::impl44 impl(ErtmController* controller, os::Handler* handler)
45 : controller_(controller), handler_(handler), retrans_timer_(handler), monitor_timer_(handler) {}
46
47 ErtmController* controller_;
48 os::Handler* handler_;
49
50 // We don't support extended window
51 static constexpr uint8_t kMaxTxWin = 64;
52
53 // We don't support sending SREJ
54 static constexpr bool kSendSrej = false;
55
56 // States (@see 8.6.5.2): Transmitter state and receiver state
57
58 enum class TxState {
59 XMIT,
60 WAIT_F,
61 };
62 TxState tx_state_ = TxState::XMIT;
63
64 enum class RxState {
65 RECV,
66 REJ_SENT,
67 SREJ_SENT,
68 };
69 RxState rx_state_ = RxState::RECV;
70
71 // Variables and Timers (@see 8.6.5.3)
72
73 uint8_t tx_seq_ = 0;
74 uint8_t next_tx_seq_ = 0;
75 uint8_t expected_ack_seq_ = 0;
76 uint8_t req_seq_ = 0;
77 uint8_t expected_tx_seq_ = 0;
78 uint8_t buffer_seq_ = 0;
79
80 bool remote_busy_ = false;
81 bool local_busy_ = false;
82 int unacked_frames_ = 0;
83 // TODO: Instead of having a map, we may consider about a better data structure
84 // Map from TxSeq to (SAR, SDU size for START packet, information payload)
85 std::map<uint8_t, std::tuple<SegmentationAndReassembly, uint16_t, std::shared_ptr<packet::RawBuilder>>> unacked_list_;
86 // Stores (SAR, SDU size for START packet, information payload)
87 std::queue<std::tuple<SegmentationAndReassembly, uint16_t, std::unique_ptr<packet::RawBuilder>>> pending_frames_;
88 int retry_count_ = 0;
89 std::map<uint8_t /* tx_seq, */, int /* count */> retry_i_frames_;
90 bool rnr_sent_ = false;
91 bool rej_actioned_ = false;
92 bool srej_actioned_ = false;
93 uint16_t srej_save_req_seq_ = 0;
94 bool send_rej_ = false;
95 int buffer_seq_srej_ = 0;
96 int frames_sent_ = 0;
97 os::Alarm retrans_timer_;
98 os::Alarm monitor_timer_;
99
100 // Events (@see 8.6.5.4)
101
data_requestbluetooth::l2cap::internal::ErtmController::impl102 void data_request(SegmentationAndReassembly sar, std::unique_ptr<packet::RawBuilder> pdu, uint16_t sdu_size = 0) {
103 // Note: sdu_size only applies to START packet
104 if (tx_state_ == TxState::XMIT && !remote_busy() && rem_window_not_full()) {
105 send_data(sar, sdu_size, std::move(pdu));
106 } else if (tx_state_ == TxState::XMIT && (remote_busy() || rem_window_full())) {
107 pend_data(sar, sdu_size, std::move(pdu));
108 } else if (tx_state_ == TxState::WAIT_F) {
109 pend_data(sar, sdu_size, std::move(pdu));
110 }
111 }
112
local_busy_detectedbluetooth::l2cap::internal::ErtmController::impl113 void local_busy_detected() {
114 local_busy_ = true;
115 }
116
local_busy_clearbluetooth::l2cap::internal::ErtmController::impl117 void local_busy_clear() {
118 if (tx_state_ == TxState::XMIT && rnr_sent()) {
119 local_busy_ = false;
120 rnr_sent_ = false;
121 send_rr(Poll::POLL);
122 retry_count_ = 1;
123 stop_retrans_timer();
124 start_monitor_timer();
125 } else if (tx_state_ == TxState::XMIT) {
126 local_busy_ = false;
127 rnr_sent_ = false;
128 }
129 }
130
recv_req_seq_and_f_bitbluetooth::l2cap::internal::ErtmController::impl131 void recv_req_seq_and_f_bit(uint8_t req_seq, Final f) {
132 if (tx_state_ == TxState::XMIT) {
133 process_req_seq(req_seq);
134 } else if (f == Final::POLL_RESPONSE) {
135 process_req_seq(req_seq);
136 stop_monitor_timer();
137 if (unacked_frames_ > 0) {
138 start_retrans_timer();
139 }
140 tx_state_ = TxState::XMIT;
141 } else {
142 process_req_seq(req_seq);
143 }
144 }
145
recv_f_bitbluetooth::l2cap::internal::ErtmController::impl146 void recv_f_bit(Final f) {
147 if (tx_state_ == TxState::WAIT_F && f == Final::POLL_RESPONSE) {
148 stop_monitor_timer();
149 if (unacked_frames_ > 0) {
150 start_retrans_timer();
151 }
152 tx_state_ = TxState::XMIT;
153 }
154 }
155
retrans_timer_expiresbluetooth::l2cap::internal::ErtmController::impl156 void retrans_timer_expires() {
157 if (tx_state_ == TxState::XMIT) {
158 send_rr_or_rnr(Poll::POLL);
159 // send rr or rnr(p=1)
160 retry_count_ = 1;
161 start_monitor_timer();
162 tx_state_ = TxState::WAIT_F;
163 }
164 }
165
monitor_timer_expiresbluetooth::l2cap::internal::ErtmController::impl166 void monitor_timer_expires() {
167 if (tx_state_ == TxState::WAIT_F && retry_count_less_than_max_transmit()) {
168 retry_count_++;
169 send_rr_or_rnr(Poll::POLL);
170 start_monitor_timer();
171 } else if (tx_state_ == TxState::WAIT_F) {
172 log::info("Close channel because max transmit reached");
173 CloseChannel();
174 }
175 }
176
recv_i_framebluetooth::l2cap::internal::ErtmController::impl177 void recv_i_frame(Final f, uint8_t tx_seq, uint8_t req_seq, SegmentationAndReassembly sar, uint16_t sdu_size,
178 const packet::PacketView<true>& payload) {
179 if (rx_state_ == RxState::RECV) {
180 if (f == Final::NOT_SET && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f) &&
181 !local_busy()) {
182 increment_expected_tx_seq();
183 pass_to_tx(req_seq, f);
184 data_indication(sar, sdu_size, payload);
185 send_ack(Final::NOT_SET);
186 } else if (f == Final::POLL_RESPONSE && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) &&
187 with_valid_f_bit(f) && !local_busy()) {
188 increment_expected_tx_seq();
189 pass_to_tx(req_seq, f);
190 data_indication(sar, sdu_size, payload);
191 if (!rej_actioned_) {
192 retransmit_i_frames(req_seq);
193 send_pending_i_frames();
194 } else {
195 rej_actioned_ = false;
196 }
197 send_ack(Final::NOT_SET);
198 } else if (with_duplicate_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f) && !local_busy()) {
199 pass_to_tx(req_seq, f);
200 } else if (with_unexpected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f) &&
201 !local_busy()) {
202 if constexpr (kSendSrej) {
203 // We don't support sending SREJ
204 } else {
205 pass_to_tx(req_seq, f);
206 send_rej();
207 rx_state_ = RxState::REJ_SENT;
208 }
209 } else if (with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f) && local_busy()) {
210 pass_to_tx(req_seq, f);
211 store_or_ignore();
212 } else if (with_valid_req_seq(req_seq) && not_with_expected_tx_seq(tx_seq) && with_valid_f_bit(f) &&
213 local_busy()) {
214 pass_to_tx(req_seq, f);
215 } else if ((with_invalid_tx_seq(tx_seq) && controller_->local_tx_window_ > kMaxTxWin / 2) ||
216 with_invalid_req_seq(req_seq)) {
217 CloseChannel();
218 } else if (with_invalid_tx_seq(tx_seq) && controller_->local_tx_window_ <= kMaxTxWin / 2) {
219 // We decided to ignore
220 }
221 } else if (rx_state_ == RxState::REJ_SENT) {
222 if (f == Final::NOT_SET && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
223 increment_expected_tx_seq();
224 pass_to_tx(req_seq, f);
225 data_indication(sar, sdu_size, payload);
226 send_ack(Final::NOT_SET);
227 rx_state_ = RxState::RECV;
228 } else if (f == Final::POLL_RESPONSE && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) &&
229 with_valid_f_bit(f)) {
230 increment_expected_tx_seq();
231 pass_to_tx(req_seq, f);
232 data_indication(sar, sdu_size, payload);
233 if (!rej_actioned_) {
234 retransmit_i_frames(req_seq);
235 send_pending_i_frames();
236 } else {
237 rej_actioned_ = false;
238 }
239 send_ack(Final::NOT_SET);
240 rx_state_ = RxState::RECV;
241 } else if (with_unexpected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
242 pass_to_tx(req_seq, f);
243 }
244 } else if (rx_state_ == RxState::SREJ_SENT) {
245 // SREJ NOT SUPPORTED
246 }
247 }
248
recv_rrbluetooth::l2cap::internal::ErtmController::impl249 void recv_rr(uint8_t req_seq, Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
250 if (rx_state_ == RxState::RECV) {
251 if (p == Poll::NOT_SET && f == Final::NOT_SET && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
252 pass_to_tx(req_seq, f);
253 if (remote_busy() && unacked_frames_ > 0) {
254 start_retrans_timer();
255 }
256 remote_busy_ = false;
257 send_pending_i_frames();
258 } else if (f == Final::POLL_RESPONSE && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
259 remote_busy_ = false;
260 pass_to_tx(req_seq, f);
261 if (!rej_actioned_) {
262 retransmit_i_frames(req_seq, p);
263 } else {
264 rej_actioned_ = false;
265 }
266 send_pending_i_frames();
267 } else if (p == Poll::POLL && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
268 pass_to_tx(req_seq, f);
269 send_i_or_rr_or_rnr(Final::POLL_RESPONSE);
270 } else if (with_invalid_req_seq(req_seq)) {
271 CloseChannel();
272 }
273 } else if (rx_state_ == RxState::REJ_SENT) {
274 if (f == Final::POLL_RESPONSE && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
275 remote_busy_ = false;
276 pass_to_tx(req_seq, f);
277 if (!rej_actioned_) {
278 retransmit_i_frames(req_seq, p);
279 } else {
280 rej_actioned_ = false;
281 }
282 send_pending_i_frames();
283 } else if (p == Poll::NOT_SET && f == Final::NOT_SET && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
284 pass_to_tx(req_seq, f);
285 if (remote_busy() && unacked_frames_ > 0) {
286 start_retrans_timer();
287 }
288 remote_busy_ = false;
289 send_ack(Final::NOT_SET);
290 } else if (p == Poll::POLL && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
291 pass_to_tx(req_seq, f);
292 if (remote_busy() && unacked_frames_ > 0) {
293 start_retrans_timer();
294 }
295 remote_busy_ = false;
296 send_rr(Final::POLL_RESPONSE);
297 } else if (with_invalid_req_seq(req_seq)) {
298 CloseChannel();
299 }
300 } else if (rx_state_ == RxState::SREJ_SENT) {
301 // SREJ NOT SUPPORTED
302 }
303 }
304
recv_rejbluetooth::l2cap::internal::ErtmController::impl305 void recv_rej(uint8_t req_seq, Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
306 if (rx_state_ == RxState::RECV) {
307 if (f == Final::NOT_SET && with_valid_req_seq_retrans(req_seq) &&
308 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
309 remote_busy_ = false;
310 pass_to_tx(req_seq, f);
311 retransmit_i_frames(req_seq, p);
312 send_pending_i_frames();
313 if (p_bit_outstanding()) {
314 rej_actioned_ = true;
315 }
316 } else if (f == Final::POLL_RESPONSE && with_valid_req_seq_retrans(req_seq) &&
317 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
318 remote_busy_ = false;
319 pass_to_tx(req_seq, f);
320 if (!rej_actioned_) {
321 retransmit_i_frames(req_seq, p);
322 } else {
323 rej_actioned_ = false;
324 }
325 send_pending_i_frames();
326 } else if (with_valid_req_seq_retrans(req_seq) && !retry_i_frames_less_than_max_transmit(req_seq)) {
327 CloseChannel();
328 } else if (with_invalid_req_seq_retrans(req_seq)) {
329 CloseChannel();
330 }
331 } else if (rx_state_ == RxState::REJ_SENT) {
332 if (f == Final::NOT_SET && with_valid_req_seq_retrans(req_seq) &&
333 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
334 remote_busy_ = false;
335 pass_to_tx(req_seq, f);
336 retransmit_i_frames(req_seq, p);
337 send_pending_i_frames();
338 if (p_bit_outstanding()) {
339 rej_actioned_ = true;
340 }
341 } else if (f == Final::POLL_RESPONSE && with_valid_req_seq_retrans(req_seq) &&
342 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
343 remote_busy_ = false;
344 pass_to_tx(req_seq, f);
345 if (!rej_actioned_) {
346 retransmit_i_frames(req_seq, p);
347 } else {
348 rej_actioned_ = false;
349 }
350 send_pending_i_frames();
351 } else if (with_valid_req_seq_retrans(req_seq) && !retry_i_frames_less_than_max_transmit(req_seq)) {
352 CloseChannel();
353 } else if (with_invalid_req_seq_retrans(req_seq)) {
354 CloseChannel();
355 }
356 } else if (rx_state_ == RxState::SREJ_SENT) {
357 // SREJ NOT SUPPORTED
358 }
359 }
360
recv_rnrbluetooth::l2cap::internal::ErtmController::impl361 void recv_rnr(uint8_t req_seq, Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
362 if (rx_state_ == RxState::RECV) {
363 if (p == Poll::NOT_SET && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
364 remote_busy_ = true;
365 pass_to_tx(req_seq, f);
366 stop_retrans_timer();
367 } else if (p == Poll::POLL && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
368 remote_busy_ = true;
369 pass_to_tx(req_seq, f);
370 stop_retrans_timer();
371 send_rr_or_rnr(Poll::NOT_SET, Final::POLL_RESPONSE);
372 } else if (with_invalid_req_seq_retrans(req_seq)) {
373 CloseChannel();
374 }
375 } else if (rx_state_ == RxState::REJ_SENT) {
376 if (p == Poll::NOT_SET && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
377 remote_busy_ = true;
378 pass_to_tx(req_seq, f);
379 send_rr(Final::POLL_RESPONSE);
380 } else if (p == Poll::POLL && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
381 remote_busy_ = true;
382 pass_to_tx(req_seq, f);
383 send_rr(Final::NOT_SET);
384 } else if (with_invalid_req_seq_retrans(req_seq)) {
385 CloseChannel();
386 }
387 } else if (rx_state_ == RxState::SREJ_SENT) {
388 // SREJ NOT SUPPORTED
389 }
390 }
391
recv_srejbluetooth::l2cap::internal::ErtmController::impl392 void recv_srej(uint8_t req_seq, Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
393 if (rx_state_ == RxState::RECV) {
394 if (p == Poll::NOT_SET && f == Final::NOT_SET && with_valid_req_seq_retrans(req_seq) &&
395 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
396 remote_busy_ = false;
397 pass_to_tx_f_bit(f);
398 retransmit_requested_i_frame(req_seq, p);
399 if (p_bit_outstanding()) {
400 srej_actioned_ = true;
401 srej_save_req_seq_ = req_seq;
402 }
403 } else if (f == Final::POLL_RESPONSE && with_valid_req_seq_retrans(req_seq) &&
404 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
405 remote_busy_ = false;
406 pass_to_tx_f_bit(f);
407 if (srej_actioned_ && srej_save_req_seq_ == req_seq) {
408 srej_actioned_ = false;
409 } else {
410 retransmit_requested_i_frame(req_seq, p);
411 }
412 } else if (p == Poll::POLL && with_valid_req_seq_retrans(req_seq) &&
413 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
414 remote_busy_ = false;
415 pass_to_tx(req_seq, f);
416 retransmit_requested_i_frame(req_seq, p);
417 send_pending_i_frames();
418 if (p_bit_outstanding()) {
419 srej_actioned_ = true;
420 srej_save_req_seq_ = req_seq;
421 }
422 } else if (with_valid_req_seq_retrans(req_seq) && !retry_i_frames_less_than_max_transmit(req_seq)) {
423 CloseChannel();
424 } else if (with_invalid_req_seq_retrans(req_seq)) {
425 CloseChannel();
426 }
427 } else if (rx_state_ == RxState::REJ_SENT) {
428 if (p == Poll::NOT_SET && f == Final::NOT_SET && with_valid_req_seq_retrans(req_seq) &&
429 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
430 remote_busy_ = false;
431 pass_to_tx_f_bit(f);
432 retransmit_requested_i_frame(req_seq, p);
433 if (p_bit_outstanding()) {
434 srej_actioned_ = true;
435 srej_save_req_seq_ = req_seq;
436 }
437 } else if (f == Final::POLL_RESPONSE && with_valid_req_seq_retrans(req_seq) &&
438 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
439 remote_busy_ = false;
440 pass_to_tx_f_bit(f);
441 if (srej_actioned_ && srej_save_req_seq_ == req_seq) {
442 srej_actioned_ = false;
443 } else {
444 retransmit_requested_i_frame(req_seq, p);
445 }
446 } else if (p == Poll::POLL && with_valid_req_seq_retrans(req_seq) &&
447 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
448 remote_busy_ = false;
449 pass_to_tx(req_seq, f);
450 retransmit_requested_i_frame(req_seq, p);
451 send_pending_i_frames();
452 if (p_bit_outstanding()) {
453 srej_actioned_ = true;
454 srej_save_req_seq_ = req_seq;
455 }
456 } else if (with_valid_req_seq_retrans(req_seq) && !retry_i_frames_less_than_max_transmit(req_seq)) {
457 CloseChannel();
458 } else if (with_invalid_req_seq_retrans(req_seq)) {
459 CloseChannel();
460 }
461 } else if (rx_state_ == RxState::SREJ_SENT) {
462 // SREJ NOT SUPPORTED
463 }
464 }
465
466 // Conditions (@see 8.6.5.5)
remote_busybluetooth::l2cap::internal::ErtmController::impl467 bool remote_busy() {
468 return remote_busy_;
469 }
470
local_busybluetooth::l2cap::internal::ErtmController::impl471 bool local_busy() {
472 return local_busy_;
473 }
474
rem_window_not_fullbluetooth::l2cap::internal::ErtmController::impl475 bool rem_window_not_full() {
476 return unacked_frames_ < controller_->remote_tx_window_;
477 }
478
rem_window_fullbluetooth::l2cap::internal::ErtmController::impl479 bool rem_window_full() {
480 return unacked_frames_ == controller_->remote_tx_window_;
481 }
482
rnr_sentbluetooth::l2cap::internal::ErtmController::impl483 bool rnr_sent() {
484 return rnr_sent_;
485 }
486
retry_i_frames_less_than_max_transmitbluetooth::l2cap::internal::ErtmController::impl487 bool retry_i_frames_less_than_max_transmit(uint8_t req_seq) {
488 return retry_i_frames_[req_seq] < controller_->local_max_transmit_;
489 }
490
retry_count_less_than_max_transmitbluetooth::l2cap::internal::ErtmController::impl491 bool retry_count_less_than_max_transmit() {
492 return retry_count_ < controller_->local_max_transmit_;
493 }
494
495 // Compares two sequence numbers (tx_seq or rx_seq)
sequence_less_thanbluetooth::l2cap::internal::ErtmController::impl496 bool sequence_less_than(uint8_t x, uint8_t y) {
497 // Assuming the maximum overflow of sequence number is the same as local_tx_window_ (10 by default).
498 return x < y || kMaxTxWin - (x - y) < controller_->local_tx_window_;
499 }
500
501 // Compares two sequence numbers (tx_seq or rx_seq)
sequence_less_than_or_equalbluetooth::l2cap::internal::ErtmController::impl502 bool sequence_less_than_or_equal(uint8_t x, uint8_t y) {
503 // Assuming the maximum overflow of sequence number is the same as local_tx_window_ (10 by default).
504 return x <= y || kMaxTxWin - (x - y) <= controller_->local_tx_window_;
505 }
506
with_expected_tx_seqbluetooth::l2cap::internal::ErtmController::impl507 bool with_expected_tx_seq(uint8_t tx_seq) {
508 return tx_seq == expected_tx_seq_;
509 }
510
with_valid_req_seqbluetooth::l2cap::internal::ErtmController::impl511 bool with_valid_req_seq(uint8_t req_seq) {
512 return sequence_less_than_or_equal(expected_ack_seq_, req_seq) &&
513 sequence_less_than_or_equal(req_seq, next_tx_seq_);
514 }
515
with_valid_req_seq_retransbluetooth::l2cap::internal::ErtmController::impl516 bool with_valid_req_seq_retrans(uint8_t req_seq) {
517 return sequence_less_than_or_equal(expected_ack_seq_, req_seq) &&
518 sequence_less_than_or_equal(req_seq, next_tx_seq_);
519 }
520
with_valid_f_bitbluetooth::l2cap::internal::ErtmController::impl521 bool with_valid_f_bit(Final f) {
522 return f == Final::NOT_SET ^ tx_state_ == TxState::WAIT_F;
523 }
524
with_unexpected_tx_seqbluetooth::l2cap::internal::ErtmController::impl525 bool with_unexpected_tx_seq(uint8_t tx_seq) {
526 return sequence_less_than(expected_tx_seq_, tx_seq) &&
527 sequence_less_than_or_equal(tx_seq, expected_tx_seq_ + controller_->local_tx_window_);
528 }
529
with_duplicate_tx_seqbluetooth::l2cap::internal::ErtmController::impl530 bool with_duplicate_tx_seq(uint8_t tx_seq) {
531 return sequence_less_than(tx_seq, expected_tx_seq_) &&
532 sequence_less_than_or_equal(expected_tx_seq_ - controller_->local_tx_window_, tx_seq);
533 }
534
with_invalid_tx_seqbluetooth::l2cap::internal::ErtmController::impl535 bool with_invalid_tx_seq(uint8_t tx_seq) {
536 return sequence_less_than(tx_seq, expected_tx_seq_ - controller_->local_tx_window_) ||
537 sequence_less_than(expected_tx_seq_ + controller_->local_tx_window_, tx_seq);
538 }
539
with_invalid_req_seqbluetooth::l2cap::internal::ErtmController::impl540 bool with_invalid_req_seq(uint8_t req_seq) {
541 return sequence_less_than(req_seq, expected_ack_seq_) || sequence_less_than(next_tx_seq_, req_seq);
542 }
543
with_invalid_req_seq_retransbluetooth::l2cap::internal::ErtmController::impl544 bool with_invalid_req_seq_retrans(uint8_t req_seq) {
545 return sequence_less_than(req_seq, expected_ack_seq_) || sequence_less_than(next_tx_seq_, req_seq);
546 }
547
not_with_expected_tx_seqbluetooth::l2cap::internal::ErtmController::impl548 bool not_with_expected_tx_seq(uint8_t tx_seq) {
549 return !with_invalid_tx_seq(tx_seq) && !with_expected_tx_seq(tx_seq);
550 }
551
with_expected_tx_seq_srejbluetooth::l2cap::internal::ErtmController::impl552 bool with_expected_tx_seq_srej() {
553 // We don't support sending SREJ
554 return false;
555 }
556
send_req_is_truebluetooth::l2cap::internal::ErtmController::impl557 bool send_req_is_true() {
558 // We don't support sending SREJ
559 return false;
560 }
561
srej_list_is_onebluetooth::l2cap::internal::ErtmController::impl562 bool srej_list_is_one() {
563 // We don't support sending SREJ
564 return false;
565 }
566
with_unexpected_tx_seq_srejbluetooth::l2cap::internal::ErtmController::impl567 bool with_unexpected_tx_seq_srej() {
568 // We don't support sending SREJ
569 return false;
570 }
571
with_duplicate_tx_seq_srejbluetooth::l2cap::internal::ErtmController::impl572 bool with_duplicate_tx_seq_srej() {
573 // We don't support sending SREJ
574 return false;
575 }
576
577 // Actions (@see 8.6.5.6)
578
_send_i_framebluetooth::l2cap::internal::ErtmController::impl579 void _send_i_frame(SegmentationAndReassembly sar, std::unique_ptr<CopyablePacketBuilder> segment, uint8_t req_seq,
580 uint8_t tx_seq, uint16_t sdu_size = 0, Final f = Final::NOT_SET) {
581 std::unique_ptr<packet::BasePacketBuilder> builder;
582 if (sar == SegmentationAndReassembly::START) {
583 if (controller_->fcs_enabled_) {
584 builder = EnhancedInformationStartFrameWithFcsBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq,
585 sdu_size, std::move(segment));
586 } else {
587 builder = EnhancedInformationStartFrameBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq, sdu_size,
588 std::move(segment));
589 }
590 } else {
591 if (controller_->fcs_enabled_) {
592 builder = EnhancedInformationFrameWithFcsBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq, sar,
593 std::move(segment));
594 } else {
595 builder = EnhancedInformationFrameBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq, sar,
596 std::move(segment));
597 }
598 }
599 controller_->send_pdu(std::move(builder));
600 }
601
send_databluetooth::l2cap::internal::ErtmController::impl602 void send_data(SegmentationAndReassembly sar, uint16_t sdu_size, std::unique_ptr<packet::RawBuilder> segment,
603 Final f = Final::NOT_SET) {
604 std::shared_ptr<packet::RawBuilder> shared_segment(segment.release());
605 unacked_list_.emplace(std::piecewise_construct, std::forward_as_tuple(next_tx_seq_),
606 std::forward_as_tuple(sar, sdu_size, shared_segment));
607
608 std::unique_ptr<CopyablePacketBuilder> copyable_packet_builder =
609 std::make_unique<CopyablePacketBuilder>(std::get<2>(unacked_list_.find(next_tx_seq_)->second));
610 _send_i_frame(sar, std::move(copyable_packet_builder), buffer_seq_, next_tx_seq_, sdu_size, f);
611 unacked_frames_++;
612 frames_sent_++;
613 retry_i_frames_[next_tx_seq_] = 1;
614 next_tx_seq_ = (next_tx_seq_ + 1) % kMaxTxWin;
615 start_retrans_timer();
616 }
617
pend_databluetooth::l2cap::internal::ErtmController::impl618 void pend_data(SegmentationAndReassembly sar, uint16_t sdu_size, std::unique_ptr<packet::RawBuilder> data) {
619 pending_frames_.emplace(std::make_tuple(sar, sdu_size, std::move(data)));
620 }
621
process_req_seqbluetooth::l2cap::internal::ErtmController::impl622 void process_req_seq(uint8_t req_seq) {
623 for (int i = expected_ack_seq_; i < req_seq; i++) {
624 unacked_list_.erase(i);
625 retry_i_frames_[i] = 0;
626 }
627 unacked_frames_ -= ((req_seq - expected_ack_seq_) + kMaxTxWin) % kMaxTxWin;
628 expected_ack_seq_ = req_seq;
629 if (unacked_frames_ == 0) {
630 stop_retrans_timer();
631 }
632 }
633
_send_s_framebluetooth::l2cap::internal::ErtmController::impl634 void _send_s_frame(SupervisoryFunction s, uint8_t req_seq, Poll p, Final f) {
635 std::unique_ptr<packet::BasePacketBuilder> builder;
636 if (controller_->fcs_enabled_) {
637 builder = EnhancedSupervisoryFrameWithFcsBuilder::Create(controller_->remote_cid_, s, p, f, req_seq);
638 } else {
639 builder = EnhancedSupervisoryFrameBuilder::Create(controller_->remote_cid_, s, p, f, req_seq);
640 }
641 controller_->send_pdu(std::move(builder));
642 }
643
send_rrbluetooth::l2cap::internal::ErtmController::impl644 void send_rr(Poll p) {
645 _send_s_frame(SupervisoryFunction::RECEIVER_READY, expected_tx_seq_, p, Final::NOT_SET);
646 }
647
send_rrbluetooth::l2cap::internal::ErtmController::impl648 void send_rr(Final f) {
649 _send_s_frame(SupervisoryFunction::RECEIVER_READY, expected_tx_seq_, Poll::NOT_SET, f);
650 }
651
send_rnrbluetooth::l2cap::internal::ErtmController::impl652 void send_rnr(Poll p) {
653 _send_s_frame(SupervisoryFunction::RECEIVER_NOT_READY, expected_tx_seq_, p, Final::NOT_SET);
654 }
655
send_rnrbluetooth::l2cap::internal::ErtmController::impl656 void send_rnr(Final f) {
657 _send_s_frame(SupervisoryFunction::RECEIVER_NOT_READY, expected_tx_seq_, Poll::NOT_SET, f);
658 rnr_sent_ = true;
659 }
660
send_rejbluetooth::l2cap::internal::ErtmController::impl661 void send_rej(Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
662 _send_s_frame(SupervisoryFunction::REJECT, expected_tx_seq_, p, f);
663 }
664
send_rr_or_rnrbluetooth::l2cap::internal::ErtmController::impl665 void send_rr_or_rnr(Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
666 if (local_busy()) {
667 _send_s_frame(SupervisoryFunction::RECEIVER_NOT_READY, buffer_seq_, p, f);
668 } else {
669 _send_s_frame(SupervisoryFunction::RECEIVER_READY, buffer_seq_, p, f);
670 }
671 }
672
send_i_or_rr_or_rnrbluetooth::l2cap::internal::ErtmController::impl673 void send_i_or_rr_or_rnr(Final f = Final::POLL_RESPONSE) {
674 auto frames_sent = 0;
675 if (local_busy()) {
676 send_rnr(Final::POLL_RESPONSE);
677 }
678 if (remote_busy() && unacked_frames_ > 0) {
679 start_retrans_timer();
680 }
681 remote_busy_ = false;
682 send_pending_i_frames(f); // TODO: Only first has f = 1, other f = 0. Also increase frames_sent
683 if (!local_busy() && frames_sent == 0) {
684 send_rr(Final::POLL_RESPONSE);
685 }
686 }
687
send_srejbluetooth::l2cap::internal::ErtmController::impl688 void send_srej() {
689 // Sending SREJ is not supported
690 }
691
start_retrans_timerbluetooth::l2cap::internal::ErtmController::impl692 void start_retrans_timer() {
693 retrans_timer_.Schedule(common::BindOnce(&impl::retrans_timer_expires, common::Unretained(this)),
694 std::chrono::milliseconds(controller_->local_retransmit_timeout_ms_));
695 }
696
start_monitor_timerbluetooth::l2cap::internal::ErtmController::impl697 void start_monitor_timer() {
698 monitor_timer_.Schedule(common::BindOnce(&impl::monitor_timer_expires, common::Unretained(this)),
699 std::chrono::milliseconds(controller_->local_monitor_timeout_ms_));
700 }
701
pass_to_txbluetooth::l2cap::internal::ErtmController::impl702 void pass_to_tx(uint8_t req_seq, Final f) {
703 recv_req_seq_and_f_bit(req_seq, f);
704 }
705
pass_to_tx_f_bitbluetooth::l2cap::internal::ErtmController::impl706 void pass_to_tx_f_bit(Final f) {
707 recv_f_bit(f);
708 }
709
data_indicationbluetooth::l2cap::internal::ErtmController::impl710 void data_indication(SegmentationAndReassembly sar, uint16_t sdu_size, const packet::PacketView<true>& segment) {
711 controller_->stage_for_reassembly(sar, sdu_size, segment);
712 buffer_seq_ = (buffer_seq_ + 1) % kMaxTxWin;
713 }
714
increment_expected_tx_seqbluetooth::l2cap::internal::ErtmController::impl715 void increment_expected_tx_seq() {
716 expected_tx_seq_ = (expected_tx_seq_ + 1) % kMaxTxWin;
717 }
718
stop_retrans_timerbluetooth::l2cap::internal::ErtmController::impl719 void stop_retrans_timer() {
720 retrans_timer_.Cancel();
721 }
722
stop_monitor_timerbluetooth::l2cap::internal::ErtmController::impl723 void stop_monitor_timer() {
724 monitor_timer_.Cancel();
725 }
726
send_ackbluetooth::l2cap::internal::ErtmController::impl727 void send_ack(Final f = Final::NOT_SET) {
728 if (local_busy()) {
729 send_rnr(f);
730 } else if (!remote_busy() && !pending_frames_.empty() && rem_window_not_full()) {
731 send_pending_i_frames(f);
732 } else {
733 send_rr(f);
734 }
735 }
736
init_srejbluetooth::l2cap::internal::ErtmController::impl737 void init_srej() {
738 // We don't support sending SREJ
739 }
740
save_i_frame_srejbluetooth::l2cap::internal::ErtmController::impl741 void save_i_frame_srej() {
742 // We don't support sending SREJ
743 }
744
store_or_ignorebluetooth::l2cap::internal::ErtmController::impl745 void store_or_ignore() {
746 // We choose to ignore.
747 }
748
p_bit_outstandingbluetooth::l2cap::internal::ErtmController::impl749 bool p_bit_outstanding() {
750 return tx_state_ == TxState::WAIT_F;
751 }
752
retransmit_i_framesbluetooth::l2cap::internal::ErtmController::impl753 void retransmit_i_frames(uint8_t req_seq, Poll p = Poll::NOT_SET) {
754 uint8_t i = req_seq;
755 Final f = (p == Poll::NOT_SET ? Final::NOT_SET : Final::POLL_RESPONSE);
756 while (unacked_list_.find(i) != unacked_list_.end()) {
757 if (retry_i_frames_[i] == controller_->local_max_transmit_) {
758 CloseChannel();
759 return;
760 }
761 std::unique_ptr<CopyablePacketBuilder> copyable_packet_builder =
762 std::make_unique<CopyablePacketBuilder>(std::get<2>(unacked_list_.find(i)->second));
763 _send_i_frame(std::get<0>(unacked_list_.find(i)->second), std::move(copyable_packet_builder), buffer_seq_, i,
764 std::get<1>(unacked_list_.find(i)->second), f);
765 retry_i_frames_[i]++;
766 frames_sent_++;
767 f = Final::NOT_SET;
768 i++;
769 }
770 if (i != req_seq) {
771 start_retrans_timer();
772 }
773 }
774
retransmit_requested_i_framebluetooth::l2cap::internal::ErtmController::impl775 void retransmit_requested_i_frame(uint8_t req_seq, Poll p) {
776 Final f = p == Poll::POLL ? Final::POLL_RESPONSE : Final::NOT_SET;
777 if (unacked_list_.find(req_seq) == unacked_list_.end()) {
778 log::error("Received invalid SREJ");
779 return;
780 }
781 std::unique_ptr<CopyablePacketBuilder> copyable_packet_builder =
782 std::make_unique<CopyablePacketBuilder>(std::get<2>(unacked_list_.find(req_seq)->second));
783 _send_i_frame(std::get<0>(unacked_list_.find(req_seq)->second), std::move(copyable_packet_builder), buffer_seq_,
784 req_seq, std::get<1>(unacked_list_.find(req_seq)->second), f);
785 retry_i_frames_[req_seq]++;
786 start_retrans_timer();
787 }
788
send_pending_i_framesbluetooth::l2cap::internal::ErtmController::impl789 void send_pending_i_frames(Final f = Final::NOT_SET) {
790 if (p_bit_outstanding()) {
791 return;
792 }
793 while (rem_window_not_full() && !pending_frames_.empty()) {
794 auto& frame = pending_frames_.front();
795 send_data(std::get<0>(frame), std::get<1>(frame), std::move(std::get<2>(frame)), f);
796 pending_frames_.pop();
797 f = Final::NOT_SET;
798 }
799 }
800
CloseChannelbluetooth::l2cap::internal::ErtmController::impl801 void CloseChannel() {
802 controller_->close_channel();
803 }
804
pop_srej_listbluetooth::l2cap::internal::ErtmController::impl805 void pop_srej_list() {
806 // We don't support sending SREJ
807 }
808
data_indication_srejbluetooth::l2cap::internal::ErtmController::impl809 void data_indication_srej() {
810 // We don't support sending SREJ
811 }
812 };
813
814 // Segmentation is handled here
OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu)815 void ErtmController::OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu) {
816 auto sdu_size = sdu->size();
817 std::vector<std::unique_ptr<packet::RawBuilder>> segments;
818 auto size_each_packet = (remote_mps_ - 4 /* basic L2CAP header */ - 2 /* SDU length */ - 2 /* Enhanced control */ -
819 (fcs_enabled_ ? 2 : 0));
820 packet::FragmentingInserter fragmenting_inserter(size_each_packet, std::back_insert_iterator(segments));
821 sdu->Serialize(fragmenting_inserter);
822 fragmenting_inserter.finalize();
823 if (segments.size() == 1) {
824 pimpl_->data_request(SegmentationAndReassembly::UNSEGMENTED, std::move(segments[0]));
825 return;
826 }
827 pimpl_->data_request(SegmentationAndReassembly::START, std::move(segments[0]), sdu_size);
828 for (size_t i = 1; i < segments.size() - 1; i++) {
829 pimpl_->data_request(SegmentationAndReassembly::CONTINUATION, std::move(segments[i]));
830 }
831 pimpl_->data_request(SegmentationAndReassembly::END, std::move(segments.back()));
832 }
833
OnPdu(packet::PacketView<true> pdu)834 void ErtmController::OnPdu(packet::PacketView<true> pdu) {
835 if (fcs_enabled_) {
836 on_pdu_fcs(pdu);
837 } else {
838 on_pdu_no_fcs(pdu);
839 }
840 }
841
on_pdu_no_fcs(const packet::PacketView<true> & pdu)842 void ErtmController::on_pdu_no_fcs(const packet::PacketView<true>& pdu) {
843 auto basic_frame_view = BasicFrameView::Create(pdu);
844 if (!basic_frame_view.IsValid()) {
845 return;
846 }
847 auto standard_frame_view = StandardFrameView::Create(basic_frame_view);
848 if (!standard_frame_view.IsValid()) {
849 log::warn("Received invalid frame");
850 return;
851 }
852 auto type = standard_frame_view.GetFrameType();
853 if (type == FrameType::I_FRAME) {
854 auto i_frame_view = EnhancedInformationFrameView::Create(standard_frame_view);
855 if (!i_frame_view.IsValid()) {
856 log::warn("Received invalid frame");
857 return;
858 }
859 Final f = i_frame_view.GetF();
860 uint8_t tx_seq = i_frame_view.GetTxSeq();
861 uint8_t req_seq = i_frame_view.GetReqSeq();
862 auto sar = i_frame_view.GetSar();
863 if (sar == SegmentationAndReassembly::START) {
864 auto i_frame_start_view = EnhancedInformationStartFrameView::Create(i_frame_view);
865 if (!i_frame_start_view.IsValid()) {
866 log::warn("Received invalid I-Frame START");
867 return;
868 }
869 pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, i_frame_start_view.GetL2capSduLength(),
870 i_frame_start_view.GetPayload());
871 } else {
872 pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, 0, i_frame_view.GetPayload());
873 }
874 } else if (type == FrameType::S_FRAME) {
875 auto s_frame_view = EnhancedSupervisoryFrameView::Create(standard_frame_view);
876 if (!s_frame_view.IsValid()) {
877 log::warn("Received invalid frame");
878 return;
879 }
880 auto req_seq = s_frame_view.GetReqSeq();
881 auto f = s_frame_view.GetF();
882 auto p = s_frame_view.GetP();
883 switch (s_frame_view.GetS()) {
884 case SupervisoryFunction::RECEIVER_READY:
885 pimpl_->recv_rr(req_seq, p, f);
886 break;
887 case SupervisoryFunction::RECEIVER_NOT_READY:
888 pimpl_->recv_rnr(req_seq, p, f);
889 break;
890 case SupervisoryFunction::REJECT:
891 pimpl_->recv_rej(req_seq, p, f);
892 break;
893 case SupervisoryFunction::SELECT_REJECT:
894 pimpl_->recv_srej(req_seq, p, f);
895 break;
896 }
897 } else {
898 log::warn("Received invalid frame");
899 }
900 }
901
on_pdu_fcs(const packet::PacketView<true> & pdu)902 void ErtmController::on_pdu_fcs(const packet::PacketView<true>& pdu) {
903 auto basic_frame_view = BasicFrameWithFcsView::Create(pdu);
904 if (!basic_frame_view.IsValid()) {
905 return;
906 }
907 auto standard_frame_view = StandardFrameWithFcsView::Create(basic_frame_view);
908 if (!standard_frame_view.IsValid()) {
909 log::warn("Received invalid frame");
910 return;
911 }
912 auto type = standard_frame_view.GetFrameType();
913 if (type == FrameType::I_FRAME) {
914 auto i_frame_view = EnhancedInformationFrameWithFcsView::Create(standard_frame_view);
915 if (!i_frame_view.IsValid()) {
916 log::warn("Received invalid frame");
917 return;
918 }
919 Final f = i_frame_view.GetF();
920 uint8_t tx_seq = i_frame_view.GetTxSeq();
921 uint8_t req_seq = i_frame_view.GetReqSeq();
922 auto sar = i_frame_view.GetSar();
923 if (sar == SegmentationAndReassembly::START) {
924 auto i_frame_start_view = EnhancedInformationStartFrameWithFcsView::Create(i_frame_view);
925 if (!i_frame_start_view.IsValid()) {
926 log::warn("Received invalid I-Frame START");
927 return;
928 }
929 pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, i_frame_start_view.GetL2capSduLength(),
930 i_frame_start_view.GetPayload());
931 } else {
932 pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, 0, i_frame_view.GetPayload());
933 }
934 } else if (type == FrameType::S_FRAME) {
935 auto s_frame_view = EnhancedSupervisoryFrameWithFcsView::Create(standard_frame_view);
936 if (!s_frame_view.IsValid()) {
937 log::warn("Received invalid frame");
938 return;
939 }
940 auto req_seq = s_frame_view.GetReqSeq();
941 auto f = s_frame_view.GetF();
942 auto p = s_frame_view.GetP();
943 switch (s_frame_view.GetS()) {
944 case SupervisoryFunction::RECEIVER_READY:
945 pimpl_->recv_rr(req_seq, p, f);
946 break;
947 case SupervisoryFunction::RECEIVER_NOT_READY:
948 pimpl_->recv_rnr(req_seq, p, f);
949 break;
950 case SupervisoryFunction::REJECT:
951 pimpl_->recv_rej(req_seq, p, f);
952 break;
953 case SupervisoryFunction::SELECT_REJECT:
954 pimpl_->recv_srej(req_seq, p, f);
955 break;
956 }
957 } else {
958 log::warn("Received invalid frame");
959 }
960 }
961
GetNextPacket()962 std::unique_ptr<packet::BasePacketBuilder> ErtmController::GetNextPacket() {
963 auto next = std::move(pdu_queue_.front());
964 pdu_queue_.pop();
965 return next;
966 }
967
stage_for_reassembly(SegmentationAndReassembly sar,uint16_t sdu_size,const packet::PacketView<kLittleEndian> & payload)968 void ErtmController::stage_for_reassembly(SegmentationAndReassembly sar, uint16_t sdu_size,
969 const packet::PacketView<kLittleEndian>& payload) {
970 // If EnqueueBuffer has more than 1 packets, we claim LocalBusy, until queue is empty
971 constexpr size_t kEnqueueBufferBusyThreshold = 3;
972 switch (sar) {
973 case SegmentationAndReassembly::UNSEGMENTED:
974 if (sar_state_ != SegmentationAndReassembly::END) {
975 log::warn("Received invalid SAR");
976 close_channel();
977 return;
978 }
979 // TODO: Enforce MTU
980 enqueue_buffer_.Enqueue(std::make_unique<packet::PacketView<kLittleEndian>>(payload), handler_);
981 if (enqueue_buffer_.Size() == kEnqueueBufferBusyThreshold) {
982 pimpl_->local_busy_detected();
983 enqueue_buffer_.NotifyOnEmpty(common::BindOnce(&impl::local_busy_clear, common::Unretained(pimpl_.get())));
984 }
985 break;
986 case SegmentationAndReassembly::START:
987 if (sar_state_ != SegmentationAndReassembly::END) {
988 log::warn("Received invalid SAR");
989 close_channel();
990 return;
991 }
992 // TODO: Enforce MTU
993 sar_state_ = SegmentationAndReassembly::START;
994 reassembly_stage_ = payload;
995 remaining_sdu_continuation_packet_size_ = sdu_size - payload.size();
996 break;
997 case SegmentationAndReassembly::CONTINUATION:
998 if (sar_state_ == SegmentationAndReassembly::END) {
999 log::warn("Received invalid SAR");
1000 close_channel();
1001 return;
1002 }
1003 reassembly_stage_.AppendPacketView(payload);
1004 remaining_sdu_continuation_packet_size_ -= payload.size();
1005 break;
1006 case SegmentationAndReassembly::END:
1007 if (sar_state_ == SegmentationAndReassembly::END) {
1008 log::warn("Received invalid SAR");
1009 close_channel();
1010 return;
1011 }
1012 sar_state_ = SegmentationAndReassembly::END;
1013 remaining_sdu_continuation_packet_size_ -= payload.size();
1014 if (remaining_sdu_continuation_packet_size_ != 0) {
1015 log::warn("Received invalid END I-Frame");
1016 reassembly_stage_ =
1017 PacketViewForReassembly(PacketView<kLittleEndian>(std::make_shared<std::vector<uint8_t>>()));
1018 remaining_sdu_continuation_packet_size_ = 0;
1019 close_channel();
1020 return;
1021 }
1022 reassembly_stage_.AppendPacketView(payload);
1023 enqueue_buffer_.Enqueue(std::make_unique<packet::PacketView<kLittleEndian>>(reassembly_stage_), handler_);
1024 if (enqueue_buffer_.Size() == kEnqueueBufferBusyThreshold) {
1025 pimpl_->local_busy_detected();
1026 enqueue_buffer_.NotifyOnEmpty(common::BindOnce(&impl::local_busy_clear, common::Unretained(pimpl_.get())));
1027 }
1028 break;
1029 }
1030 }
1031
EnableFcs(bool enabled)1032 void ErtmController::EnableFcs(bool enabled) {
1033 fcs_enabled_ = enabled;
1034 }
1035
send_pdu(std::unique_ptr<packet::BasePacketBuilder> pdu)1036 void ErtmController::send_pdu(std::unique_ptr<packet::BasePacketBuilder> pdu) {
1037 pdu_queue_.emplace(std::move(pdu));
1038 scheduler_->OnPacketsReady(cid_, 1);
1039 }
1040
SetRetransmissionAndFlowControlOptions(const RetransmissionAndFlowControlConfigurationOption & option)1041 void ErtmController::SetRetransmissionAndFlowControlOptions(
1042 const RetransmissionAndFlowControlConfigurationOption& option) {
1043 remote_tx_window_ = option.tx_window_size_;
1044 local_max_transmit_ = option.max_transmit_;
1045 local_retransmit_timeout_ms_ = option.retransmission_time_out_;
1046 local_monitor_timeout_ms_ = option.monitor_time_out_;
1047 remote_mps_ = option.maximum_pdu_size_;
1048 }
1049
close_channel()1050 void ErtmController::close_channel() {
1051 link_->SendDisconnectionRequest(cid_, remote_cid_);
1052 }
1053
size() const1054 size_t ErtmController::CopyablePacketBuilder::size() const {
1055 return builder_->size();
1056 }
1057
Serialize(BitInserter & it) const1058 void ErtmController::CopyablePacketBuilder::Serialize(BitInserter& it) const {
1059 builder_->Serialize(it);
1060 }
1061
1062 } // namespace internal
1063 } // namespace l2cap
1064 } // namespace bluetooth
1065