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 <map>
20 #include <queue>
21 #include <vector>
22
23 #include "common/bind.h"
24 #include "l2cap/internal/ilink.h"
25 #include "os/alarm.h"
26 #include "packet/fragmenting_inserter.h"
27 #include "packet/raw_builder.h"
28
29 namespace bluetooth {
30 namespace l2cap {
31 namespace internal {
ErtmController(ILink * link,Cid cid,Cid remote_cid,UpperQueueDownEnd * channel_queue_end,os::Handler * handler,Scheduler * scheduler)32 ErtmController::ErtmController(ILink* link, Cid cid, Cid remote_cid, UpperQueueDownEnd* channel_queue_end,
33 os::Handler* handler, Scheduler* scheduler)
34 : link_(link), cid_(cid), remote_cid_(remote_cid), enqueue_buffer_(channel_queue_end), handler_(handler),
35 scheduler_(scheduler), pimpl_(std::make_unique<impl>(this, handler)) {}
36
~ErtmController()37 ErtmController::~ErtmController() {
38 enqueue_buffer_.Clear();
39 }
40
41 struct ErtmController::impl {
implbluetooth::l2cap::internal::ErtmController::impl42 impl(ErtmController* controller, os::Handler* handler)
43 : controller_(controller), handler_(handler), retrans_timer_(handler), monitor_timer_(handler) {}
44
45 ErtmController* controller_;
46 os::Handler* handler_;
47
48 // We don't support extended window
49 static constexpr uint8_t kMaxTxWin = 64;
50
51 // We don't support sending SREJ
52 static constexpr bool kSendSrej = false;
53
54 // States (@see 8.6.5.2): Transmitter state and receiver state
55
56 enum class TxState {
57 XMIT,
58 WAIT_F,
59 };
60 TxState tx_state_ = TxState::XMIT;
61
62 enum class RxState {
63 RECV,
64 REJ_SENT,
65 SREJ_SENT,
66 };
67 RxState rx_state_ = RxState::RECV;
68
69 // Variables and Timers (@see 8.6.5.3)
70
71 uint8_t tx_seq_ = 0;
72 uint8_t next_tx_seq_ = 0;
73 uint8_t expected_ack_seq_ = 0;
74 uint8_t req_seq_ = 0;
75 uint8_t expected_tx_seq_ = 0;
76 uint8_t buffer_seq_ = 0;
77
78 bool remote_busy_ = false;
79 bool local_busy_ = false;
80 int unacked_frames_ = 0;
81 // TODO: Instead of having a map, we may consider about a better data structure
82 // Map from TxSeq to (SAR, SDU size for START packet, information payload)
83 std::map<uint8_t, std::tuple<SegmentationAndReassembly, uint16_t, std::shared_ptr<packet::RawBuilder>>> unacked_list_;
84 // Stores (SAR, SDU size for START packet, information payload)
85 std::queue<std::tuple<SegmentationAndReassembly, uint16_t, std::unique_ptr<packet::RawBuilder>>> pending_frames_;
86 int retry_count_ = 0;
87 std::map<uint8_t /* tx_seq, */, int /* count */> retry_i_frames_;
88 bool rnr_sent_ = false;
89 bool rej_actioned_ = false;
90 bool srej_actioned_ = false;
91 uint16_t srej_save_req_seq_ = 0;
92 bool send_rej_ = false;
93 int buffer_seq_srej_ = 0;
94 int frames_sent_ = 0;
95 os::Alarm retrans_timer_;
96 os::Alarm monitor_timer_;
97
98 // Events (@see 8.6.5.4)
99
data_requestbluetooth::l2cap::internal::ErtmController::impl100 void data_request(SegmentationAndReassembly sar, std::unique_ptr<packet::RawBuilder> pdu, uint16_t sdu_size = 0) {
101 // Note: sdu_size only applies to START packet
102 if (tx_state_ == TxState::XMIT && !remote_busy() && rem_window_not_full()) {
103 send_data(sar, sdu_size, std::move(pdu));
104 } else if (tx_state_ == TxState::XMIT && (remote_busy() || rem_window_full())) {
105 pend_data(sar, sdu_size, std::move(pdu));
106 } else if (tx_state_ == TxState::WAIT_F) {
107 pend_data(sar, sdu_size, std::move(pdu));
108 }
109 }
110
local_busy_detectedbluetooth::l2cap::internal::ErtmController::impl111 void local_busy_detected() {
112 local_busy_ = true;
113 }
114
local_busy_clearbluetooth::l2cap::internal::ErtmController::impl115 void local_busy_clear() {
116 if (tx_state_ == TxState::XMIT && rnr_sent()) {
117 local_busy_ = false;
118 rnr_sent_ = false;
119 send_rr(Poll::POLL);
120 retry_count_ = 1;
121 stop_retrans_timer();
122 start_monitor_timer();
123 } else if (tx_state_ == TxState::XMIT) {
124 local_busy_ = false;
125 rnr_sent_ = false;
126 }
127 }
128
recv_req_seq_and_f_bitbluetooth::l2cap::internal::ErtmController::impl129 void recv_req_seq_and_f_bit(uint8_t req_seq, Final f) {
130 if (tx_state_ == TxState::XMIT) {
131 process_req_seq(req_seq);
132 } else if (f == Final::POLL_RESPONSE) {
133 process_req_seq(req_seq);
134 stop_monitor_timer();
135 if (unacked_frames_ > 0) {
136 start_retrans_timer();
137 }
138 tx_state_ = TxState::XMIT;
139 } else {
140 process_req_seq(req_seq);
141 }
142 }
143
recv_f_bitbluetooth::l2cap::internal::ErtmController::impl144 void recv_f_bit(Final f) {
145 if (tx_state_ == TxState::WAIT_F && f == Final::POLL_RESPONSE) {
146 stop_monitor_timer();
147 if (unacked_frames_ > 0) {
148 start_retrans_timer();
149 }
150 tx_state_ = TxState::XMIT;
151 }
152 }
153
retrans_timer_expiresbluetooth::l2cap::internal::ErtmController::impl154 void retrans_timer_expires() {
155 if (tx_state_ == TxState::XMIT) {
156 send_rr_or_rnr(Poll::POLL);
157 // send rr or rnr(p=1)
158 retry_count_ = 1;
159 start_monitor_timer();
160 tx_state_ = TxState::WAIT_F;
161 }
162 }
163
monitor_timer_expiresbluetooth::l2cap::internal::ErtmController::impl164 void monitor_timer_expires() {
165 if (tx_state_ == TxState::WAIT_F && retry_count_less_than_max_transmit()) {
166 retry_count_++;
167 send_rr_or_rnr(Poll::POLL);
168 start_monitor_timer();
169 } else if (tx_state_ == TxState::WAIT_F) {
170 LOG_INFO("Close channel because max transmit reached");
171 CloseChannel();
172 }
173 }
174
recv_i_framebluetooth::l2cap::internal::ErtmController::impl175 void recv_i_frame(Final f, uint8_t tx_seq, uint8_t req_seq, SegmentationAndReassembly sar, uint16_t sdu_size,
176 const packet::PacketView<true>& payload) {
177 if (rx_state_ == RxState::RECV) {
178 if (f == Final::NOT_SET && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f) &&
179 !local_busy()) {
180 increment_expected_tx_seq();
181 pass_to_tx(req_seq, f);
182 data_indication(sar, sdu_size, payload);
183 send_ack(Final::NOT_SET);
184 } else if (f == Final::POLL_RESPONSE && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) &&
185 with_valid_f_bit(f) && !local_busy()) {
186 increment_expected_tx_seq();
187 pass_to_tx(req_seq, f);
188 data_indication(sar, sdu_size, payload);
189 if (!rej_actioned_) {
190 retransmit_i_frames(req_seq);
191 send_pending_i_frames();
192 } else {
193 rej_actioned_ = false;
194 }
195 send_ack(Final::NOT_SET);
196 } else if (with_duplicate_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f) && !local_busy()) {
197 pass_to_tx(req_seq, f);
198 } else if (with_unexpected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f) &&
199 !local_busy()) {
200 if constexpr (kSendSrej) {
201 // We don't support sending SREJ
202 } else {
203 pass_to_tx(req_seq, f);
204 send_rej();
205 rx_state_ = RxState::REJ_SENT;
206 }
207 } else if (with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f) && local_busy()) {
208 pass_to_tx(req_seq, f);
209 store_or_ignore();
210 } else if (with_valid_req_seq(req_seq) && not_with_expected_tx_seq(tx_seq) && with_valid_f_bit(f) &&
211 local_busy()) {
212 pass_to_tx(req_seq, f);
213 } else if ((with_invalid_tx_seq(tx_seq) && controller_->local_tx_window_ > kMaxTxWin / 2) ||
214 with_invalid_req_seq(req_seq)) {
215 CloseChannel();
216 } else if (with_invalid_tx_seq(tx_seq) && controller_->local_tx_window_ <= kMaxTxWin / 2) {
217 // We decided to ignore
218 }
219 } else if (rx_state_ == RxState::REJ_SENT) {
220 if (f == Final::NOT_SET && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
221 increment_expected_tx_seq();
222 pass_to_tx(req_seq, f);
223 data_indication(sar, sdu_size, payload);
224 send_ack(Final::NOT_SET);
225 rx_state_ = RxState::RECV;
226 } else if (f == Final::POLL_RESPONSE && with_expected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) &&
227 with_valid_f_bit(f)) {
228 increment_expected_tx_seq();
229 pass_to_tx(req_seq, f);
230 data_indication(sar, sdu_size, payload);
231 if (!rej_actioned_) {
232 retransmit_i_frames(req_seq);
233 send_pending_i_frames();
234 } else {
235 rej_actioned_ = false;
236 }
237 send_ack(Final::NOT_SET);
238 rx_state_ = RxState::RECV;
239 } else if (with_unexpected_tx_seq(tx_seq) && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
240 pass_to_tx(req_seq, f);
241 }
242 } else if (rx_state_ == RxState::SREJ_SENT) {
243 // SREJ NOT SUPPORTED
244 }
245 }
246
recv_rrbluetooth::l2cap::internal::ErtmController::impl247 void recv_rr(uint8_t req_seq, Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
248 if (rx_state_ == RxState::RECV) {
249 if (p == Poll::NOT_SET && f == Final::NOT_SET && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
250 pass_to_tx(req_seq, f);
251 if (remote_busy() && unacked_frames_ > 0) {
252 start_retrans_timer();
253 }
254 remote_busy_ = false;
255 send_pending_i_frames();
256 } else if (f == Final::POLL_RESPONSE && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
257 remote_busy_ = false;
258 pass_to_tx(req_seq, f);
259 if (!rej_actioned_) {
260 retransmit_i_frames(req_seq, p);
261 } else {
262 rej_actioned_ = false;
263 }
264 send_pending_i_frames();
265 } else if (p == Poll::POLL && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
266 pass_to_tx(req_seq, f);
267 send_i_or_rr_or_rnr(Final::POLL_RESPONSE);
268 } else if (with_invalid_req_seq(req_seq)) {
269 CloseChannel();
270 }
271 } else if (rx_state_ == RxState::REJ_SENT) {
272 if (f == Final::POLL_RESPONSE && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
273 remote_busy_ = false;
274 pass_to_tx(req_seq, f);
275 if (!rej_actioned_) {
276 retransmit_i_frames(req_seq, p);
277 } else {
278 rej_actioned_ = false;
279 }
280 send_pending_i_frames();
281 } else if (p == Poll::NOT_SET && f == Final::NOT_SET && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
282 pass_to_tx(req_seq, f);
283 if (remote_busy() and unacked_frames_ > 0) {
284 start_retrans_timer();
285 }
286 remote_busy_ = false;
287 send_ack(Final::NOT_SET);
288 } else if (p == Poll::POLL && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
289 pass_to_tx(req_seq, f);
290 if (remote_busy() and unacked_frames_ > 0) {
291 start_retrans_timer();
292 }
293 remote_busy_ = false;
294 send_rr(Final::POLL_RESPONSE);
295 } else if (with_invalid_req_seq(req_seq)) {
296 CloseChannel();
297 }
298 } else if (rx_state_ == RxState::SREJ_SENT) {
299 // SREJ NOT SUPPORTED
300 }
301 }
302
recv_rejbluetooth::l2cap::internal::ErtmController::impl303 void recv_rej(uint8_t req_seq, Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
304 if (rx_state_ == RxState::RECV) {
305 if (f == Final::NOT_SET && with_valid_req_seq_retrans(req_seq) &&
306 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
307 remote_busy_ = false;
308 pass_to_tx(req_seq, f);
309 retransmit_i_frames(req_seq, p);
310 send_pending_i_frames();
311 if (p_bit_outstanding()) {
312 rej_actioned_ = true;
313 }
314 } else if (f == Final::POLL_RESPONSE && with_valid_req_seq_retrans(req_seq) &&
315 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
316 remote_busy_ = false;
317 pass_to_tx(req_seq, f);
318 if (!rej_actioned_) {
319 retransmit_i_frames(req_seq, p);
320 } else {
321 rej_actioned_ = false;
322 }
323 send_pending_i_frames();
324 } else if (with_valid_req_seq_retrans(req_seq) && !retry_i_frames_less_than_max_transmit(req_seq)) {
325 CloseChannel();
326 } else if (with_invalid_req_seq_retrans(req_seq)) {
327 CloseChannel();
328 }
329 } else if (rx_state_ == RxState::REJ_SENT) {
330 if (f == Final::NOT_SET && with_valid_req_seq_retrans(req_seq) &&
331 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
332 remote_busy_ = false;
333 pass_to_tx(req_seq, f);
334 retransmit_i_frames(req_seq, p);
335 send_pending_i_frames();
336 if (p_bit_outstanding()) {
337 rej_actioned_ = true;
338 }
339 } else if (f == Final::POLL_RESPONSE && with_valid_req_seq_retrans(req_seq) &&
340 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
341 remote_busy_ = false;
342 pass_to_tx(req_seq, f);
343 if (!rej_actioned_) {
344 retransmit_i_frames(req_seq, p);
345 } else {
346 rej_actioned_ = false;
347 }
348 send_pending_i_frames();
349 } else if (with_valid_req_seq_retrans(req_seq) && !retry_i_frames_less_than_max_transmit(req_seq)) {
350 CloseChannel();
351 } else if (with_invalid_req_seq_retrans(req_seq)) {
352 CloseChannel();
353 }
354 } else if (rx_state_ == RxState::SREJ_SENT) {
355 // SREJ NOT SUPPORTED
356 }
357 }
358
recv_rnrbluetooth::l2cap::internal::ErtmController::impl359 void recv_rnr(uint8_t req_seq, Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
360 if (rx_state_ == RxState::RECV) {
361 if (p == Poll::NOT_SET && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
362 remote_busy_ = true;
363 pass_to_tx(req_seq, f);
364 stop_retrans_timer();
365 } else if (p == Poll::POLL && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
366 remote_busy_ = true;
367 pass_to_tx(req_seq, f);
368 stop_retrans_timer();
369 send_rr_or_rnr(Poll::NOT_SET, Final::POLL_RESPONSE);
370 } else if (with_invalid_req_seq_retrans(req_seq)) {
371 CloseChannel();
372 }
373 } else if (rx_state_ == RxState::REJ_SENT) {
374 if (p == Poll::NOT_SET && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
375 remote_busy_ = true;
376 pass_to_tx(req_seq, f);
377 send_rr(Final::POLL_RESPONSE);
378 } else if (p == Poll::POLL && with_valid_req_seq(req_seq) && with_valid_f_bit(f)) {
379 remote_busy_ = true;
380 pass_to_tx(req_seq, f);
381 send_rr(Final::NOT_SET);
382 } else if (with_invalid_req_seq_retrans(req_seq)) {
383 CloseChannel();
384 }
385 } else if (rx_state_ == RxState::SREJ_SENT) {
386 // SREJ NOT SUPPORTED
387 }
388 }
389
recv_srejbluetooth::l2cap::internal::ErtmController::impl390 void recv_srej(uint8_t req_seq, Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
391 if (rx_state_ == RxState::RECV) {
392 if (p == Poll::NOT_SET && f == Final::NOT_SET && with_valid_req_seq_retrans(req_seq) &&
393 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
394 remote_busy_ = false;
395 pass_to_tx_f_bit(f);
396 retransmit_requested_i_frame(req_seq, p);
397 if (p_bit_outstanding()) {
398 srej_actioned_ = true;
399 srej_save_req_seq_ = req_seq;
400 }
401 } else if (f == Final::POLL_RESPONSE && with_valid_req_seq_retrans(req_seq) &&
402 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
403 remote_busy_ = false;
404 pass_to_tx_f_bit(f);
405 if (srej_actioned_ && srej_save_req_seq_ == req_seq) {
406 srej_actioned_ = false;
407 } else {
408 retransmit_requested_i_frame(req_seq, p);
409 }
410 } else if (p == Poll::POLL && with_valid_req_seq_retrans(req_seq) &&
411 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
412 remote_busy_ = false;
413 pass_to_tx(req_seq, f);
414 retransmit_requested_i_frame(req_seq, p);
415 send_pending_i_frames();
416 if (p_bit_outstanding()) {
417 srej_actioned_ = true;
418 srej_save_req_seq_ = req_seq;
419 }
420 } else if (with_valid_req_seq_retrans(req_seq) && !retry_i_frames_less_than_max_transmit(req_seq)) {
421 CloseChannel();
422 } else if (with_invalid_req_seq_retrans(req_seq)) {
423 CloseChannel();
424 }
425 } else if (rx_state_ == RxState::REJ_SENT) {
426 if (p == Poll::NOT_SET && f == Final::NOT_SET && with_valid_req_seq_retrans(req_seq) &&
427 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
428 remote_busy_ = false;
429 pass_to_tx_f_bit(f);
430 retransmit_requested_i_frame(req_seq, p);
431 if (p_bit_outstanding()) {
432 srej_actioned_ = true;
433 srej_save_req_seq_ = req_seq;
434 }
435 } else if (f == Final::POLL_RESPONSE && with_valid_req_seq_retrans(req_seq) &&
436 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
437 remote_busy_ = false;
438 pass_to_tx_f_bit(f);
439 if (srej_actioned_ && srej_save_req_seq_ == req_seq) {
440 srej_actioned_ = false;
441 } else {
442 retransmit_requested_i_frame(req_seq, p);
443 }
444 } else if (p == Poll::POLL && with_valid_req_seq_retrans(req_seq) &&
445 retry_i_frames_less_than_max_transmit(req_seq) && with_valid_f_bit(f)) {
446 remote_busy_ = false;
447 pass_to_tx(req_seq, f);
448 retransmit_requested_i_frame(req_seq, p);
449 send_pending_i_frames();
450 if (p_bit_outstanding()) {
451 srej_actioned_ = true;
452 srej_save_req_seq_ = req_seq;
453 }
454 } else if (with_valid_req_seq_retrans(req_seq) && !retry_i_frames_less_than_max_transmit(req_seq)) {
455 CloseChannel();
456 } else if (with_invalid_req_seq_retrans(req_seq)) {
457 CloseChannel();
458 }
459 } else if (rx_state_ == RxState::SREJ_SENT) {
460 // SREJ NOT SUPPORTED
461 }
462 }
463
464 // Conditions (@see 8.6.5.5)
remote_busybluetooth::l2cap::internal::ErtmController::impl465 bool remote_busy() {
466 return remote_busy_;
467 }
468
local_busybluetooth::l2cap::internal::ErtmController::impl469 bool local_busy() {
470 return local_busy_;
471 }
472
rem_window_not_fullbluetooth::l2cap::internal::ErtmController::impl473 bool rem_window_not_full() {
474 return unacked_frames_ < controller_->remote_tx_window_;
475 }
476
rem_window_fullbluetooth::l2cap::internal::ErtmController::impl477 bool rem_window_full() {
478 return unacked_frames_ == controller_->remote_tx_window_;
479 }
480
rnr_sentbluetooth::l2cap::internal::ErtmController::impl481 bool rnr_sent() {
482 return rnr_sent_;
483 }
484
retry_i_frames_less_than_max_transmitbluetooth::l2cap::internal::ErtmController::impl485 bool retry_i_frames_less_than_max_transmit(uint8_t req_seq) {
486 return retry_i_frames_[req_seq] < controller_->local_max_transmit_;
487 }
488
retry_count_less_than_max_transmitbluetooth::l2cap::internal::ErtmController::impl489 bool retry_count_less_than_max_transmit() {
490 return retry_count_ < controller_->local_max_transmit_;
491 }
492
493 // Compares two sequence numbers (tx_seq or rx_seq)
sequence_less_thanbluetooth::l2cap::internal::ErtmController::impl494 bool sequence_less_than(uint8_t x, uint8_t y) {
495 // Assuming the maximum overflow of sequence number is the same as local_tx_window_ (10 by default).
496 return x < y || kMaxTxWin - (x - y) < controller_->local_tx_window_;
497 }
498
499 // Compares two sequence numbers (tx_seq or rx_seq)
sequence_less_than_or_equalbluetooth::l2cap::internal::ErtmController::impl500 bool sequence_less_than_or_equal(uint8_t x, uint8_t y) {
501 // Assuming the maximum overflow of sequence number is the same as local_tx_window_ (10 by default).
502 return x <= y || kMaxTxWin - (x - y) <= controller_->local_tx_window_;
503 }
504
with_expected_tx_seqbluetooth::l2cap::internal::ErtmController::impl505 bool with_expected_tx_seq(uint8_t tx_seq) {
506 return tx_seq == expected_tx_seq_;
507 }
508
with_valid_req_seqbluetooth::l2cap::internal::ErtmController::impl509 bool with_valid_req_seq(uint8_t req_seq) {
510 return sequence_less_than_or_equal(expected_ack_seq_, req_seq) &&
511 sequence_less_than_or_equal(req_seq, next_tx_seq_);
512 }
513
with_valid_req_seq_retransbluetooth::l2cap::internal::ErtmController::impl514 bool with_valid_req_seq_retrans(uint8_t req_seq) {
515 return sequence_less_than_or_equal(expected_ack_seq_, req_seq) &&
516 sequence_less_than_or_equal(req_seq, next_tx_seq_);
517 }
518
with_valid_f_bitbluetooth::l2cap::internal::ErtmController::impl519 bool with_valid_f_bit(Final f) {
520 return f == Final::NOT_SET ^ tx_state_ == TxState::WAIT_F;
521 }
522
with_unexpected_tx_seqbluetooth::l2cap::internal::ErtmController::impl523 bool with_unexpected_tx_seq(uint8_t tx_seq) {
524 return sequence_less_than(expected_tx_seq_, tx_seq) &&
525 sequence_less_than_or_equal(tx_seq, expected_tx_seq_ + controller_->local_tx_window_);
526 }
527
with_duplicate_tx_seqbluetooth::l2cap::internal::ErtmController::impl528 bool with_duplicate_tx_seq(uint8_t tx_seq) {
529 return sequence_less_than(tx_seq, expected_tx_seq_) &&
530 sequence_less_than_or_equal(expected_tx_seq_ - controller_->local_tx_window_, tx_seq);
531 }
532
with_invalid_tx_seqbluetooth::l2cap::internal::ErtmController::impl533 bool with_invalid_tx_seq(uint8_t tx_seq) {
534 return sequence_less_than(tx_seq, expected_tx_seq_ - controller_->local_tx_window_) ||
535 sequence_less_than(expected_tx_seq_ + controller_->local_tx_window_, tx_seq);
536 }
537
with_invalid_req_seqbluetooth::l2cap::internal::ErtmController::impl538 bool with_invalid_req_seq(uint8_t req_seq) {
539 return sequence_less_than(req_seq, expected_ack_seq_) || sequence_less_than(next_tx_seq_, req_seq);
540 }
541
with_invalid_req_seq_retransbluetooth::l2cap::internal::ErtmController::impl542 bool with_invalid_req_seq_retrans(uint8_t req_seq) {
543 return sequence_less_than(req_seq, expected_ack_seq_) || sequence_less_than(next_tx_seq_, req_seq);
544 }
545
not_with_expected_tx_seqbluetooth::l2cap::internal::ErtmController::impl546 bool not_with_expected_tx_seq(uint8_t tx_seq) {
547 return !with_invalid_tx_seq(tx_seq) && !with_expected_tx_seq(tx_seq);
548 }
549
with_expected_tx_seq_srejbluetooth::l2cap::internal::ErtmController::impl550 bool with_expected_tx_seq_srej() {
551 // We don't support sending SREJ
552 return false;
553 }
554
send_req_is_truebluetooth::l2cap::internal::ErtmController::impl555 bool send_req_is_true() {
556 // We don't support sending SREJ
557 return false;
558 }
559
srej_list_is_onebluetooth::l2cap::internal::ErtmController::impl560 bool srej_list_is_one() {
561 // We don't support sending SREJ
562 return false;
563 }
564
with_unexpected_tx_seq_srejbluetooth::l2cap::internal::ErtmController::impl565 bool with_unexpected_tx_seq_srej() {
566 // We don't support sending SREJ
567 return false;
568 }
569
with_duplicate_tx_seq_srejbluetooth::l2cap::internal::ErtmController::impl570 bool with_duplicate_tx_seq_srej() {
571 // We don't support sending SREJ
572 return false;
573 }
574
575 // Actions (@see 8.6.5.6)
576
_send_i_framebluetooth::l2cap::internal::ErtmController::impl577 void _send_i_frame(SegmentationAndReassembly sar, std::unique_ptr<CopyablePacketBuilder> segment, uint8_t req_seq,
578 uint8_t tx_seq, uint16_t sdu_size = 0, Final f = Final::NOT_SET) {
579 std::unique_ptr<packet::BasePacketBuilder> builder;
580 if (sar == SegmentationAndReassembly::START) {
581 if (controller_->fcs_enabled_) {
582 builder = EnhancedInformationStartFrameWithFcsBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq,
583 sdu_size, std::move(segment));
584 } else {
585 builder = EnhancedInformationStartFrameBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq, sdu_size,
586 std::move(segment));
587 }
588 } else {
589 if (controller_->fcs_enabled_) {
590 builder = EnhancedInformationFrameWithFcsBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq, sar,
591 std::move(segment));
592 } else {
593 builder = EnhancedInformationFrameBuilder::Create(controller_->remote_cid_, tx_seq, f, req_seq, sar,
594 std::move(segment));
595 }
596 }
597 controller_->send_pdu(std::move(builder));
598 }
599
send_databluetooth::l2cap::internal::ErtmController::impl600 void send_data(SegmentationAndReassembly sar, uint16_t sdu_size, std::unique_ptr<packet::RawBuilder> segment,
601 Final f = Final::NOT_SET) {
602 std::shared_ptr<packet::RawBuilder> shared_segment(segment.release());
603 unacked_list_.emplace(std::piecewise_construct, std::forward_as_tuple(next_tx_seq_),
604 std::forward_as_tuple(sar, sdu_size, shared_segment));
605
606 std::unique_ptr<CopyablePacketBuilder> copyable_packet_builder =
607 std::make_unique<CopyablePacketBuilder>(std::get<2>(unacked_list_.find(next_tx_seq_)->second));
608 _send_i_frame(sar, std::move(copyable_packet_builder), buffer_seq_, next_tx_seq_, sdu_size, f);
609 unacked_frames_++;
610 frames_sent_++;
611 retry_i_frames_[next_tx_seq_] = 1;
612 next_tx_seq_ = (next_tx_seq_ + 1) % kMaxTxWin;
613 start_retrans_timer();
614 }
615
pend_databluetooth::l2cap::internal::ErtmController::impl616 void pend_data(SegmentationAndReassembly sar, uint16_t sdu_size, std::unique_ptr<packet::RawBuilder> data) {
617 pending_frames_.emplace(std::make_tuple(sar, sdu_size, std::move(data)));
618 }
619
process_req_seqbluetooth::l2cap::internal::ErtmController::impl620 void process_req_seq(uint8_t req_seq) {
621 for (int i = expected_ack_seq_; i < req_seq; i++) {
622 unacked_list_.erase(i);
623 retry_i_frames_[i] = 0;
624 }
625 unacked_frames_ -= ((req_seq - expected_ack_seq_) + kMaxTxWin) % kMaxTxWin;
626 expected_ack_seq_ = req_seq;
627 if (unacked_frames_ == 0) {
628 stop_retrans_timer();
629 }
630 }
631
_send_s_framebluetooth::l2cap::internal::ErtmController::impl632 void _send_s_frame(SupervisoryFunction s, uint8_t req_seq, Poll p, Final f) {
633 std::unique_ptr<packet::BasePacketBuilder> builder;
634 if (controller_->fcs_enabled_) {
635 builder = EnhancedSupervisoryFrameWithFcsBuilder::Create(controller_->remote_cid_, s, p, f, req_seq);
636 } else {
637 builder = EnhancedSupervisoryFrameBuilder::Create(controller_->remote_cid_, s, p, f, req_seq);
638 }
639 controller_->send_pdu(std::move(builder));
640 }
641
send_rrbluetooth::l2cap::internal::ErtmController::impl642 void send_rr(Poll p) {
643 _send_s_frame(SupervisoryFunction::RECEIVER_READY, expected_tx_seq_, p, Final::NOT_SET);
644 }
645
send_rrbluetooth::l2cap::internal::ErtmController::impl646 void send_rr(Final f) {
647 _send_s_frame(SupervisoryFunction::RECEIVER_READY, expected_tx_seq_, Poll::NOT_SET, f);
648 }
649
send_rnrbluetooth::l2cap::internal::ErtmController::impl650 void send_rnr(Poll p) {
651 _send_s_frame(SupervisoryFunction::RECEIVER_NOT_READY, expected_tx_seq_, p, Final::NOT_SET);
652 }
653
send_rnrbluetooth::l2cap::internal::ErtmController::impl654 void send_rnr(Final f) {
655 _send_s_frame(SupervisoryFunction::RECEIVER_NOT_READY, expected_tx_seq_, Poll::NOT_SET, f);
656 rnr_sent_ = true;
657 }
658
send_rejbluetooth::l2cap::internal::ErtmController::impl659 void send_rej(Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
660 _send_s_frame(SupervisoryFunction::REJECT, expected_tx_seq_, p, f);
661 }
662
send_rr_or_rnrbluetooth::l2cap::internal::ErtmController::impl663 void send_rr_or_rnr(Poll p = Poll::NOT_SET, Final f = Final::NOT_SET) {
664 if (local_busy()) {
665 _send_s_frame(SupervisoryFunction::RECEIVER_NOT_READY, buffer_seq_, p, f);
666 } else {
667 _send_s_frame(SupervisoryFunction::RECEIVER_READY, buffer_seq_, p, f);
668 }
669 }
670
send_i_or_rr_or_rnrbluetooth::l2cap::internal::ErtmController::impl671 void send_i_or_rr_or_rnr(Final f = Final::POLL_RESPONSE) {
672 auto frames_sent = 0;
673 if (local_busy()) {
674 send_rnr(Final::POLL_RESPONSE);
675 }
676 if (remote_busy() && unacked_frames_ > 0) {
677 start_retrans_timer();
678 }
679 remote_busy_ = false;
680 send_pending_i_frames(f); // TODO: Only first has f = 1, other f = 0. Also increase frames_sent
681 if (!local_busy() && frames_sent == 0) {
682 send_rr(Final::POLL_RESPONSE);
683 }
684 }
685
send_srejbluetooth::l2cap::internal::ErtmController::impl686 void send_srej() {
687 // Sending SREJ is not supported
688 }
689
start_retrans_timerbluetooth::l2cap::internal::ErtmController::impl690 void start_retrans_timer() {
691 retrans_timer_.Schedule(common::BindOnce(&impl::retrans_timer_expires, common::Unretained(this)),
692 std::chrono::milliseconds(controller_->local_retransmit_timeout_ms_));
693 }
694
start_monitor_timerbluetooth::l2cap::internal::ErtmController::impl695 void start_monitor_timer() {
696 monitor_timer_.Schedule(common::BindOnce(&impl::monitor_timer_expires, common::Unretained(this)),
697 std::chrono::milliseconds(controller_->local_monitor_timeout_ms_));
698 }
699
pass_to_txbluetooth::l2cap::internal::ErtmController::impl700 void pass_to_tx(uint8_t req_seq, Final f) {
701 recv_req_seq_and_f_bit(req_seq, f);
702 }
703
pass_to_tx_f_bitbluetooth::l2cap::internal::ErtmController::impl704 void pass_to_tx_f_bit(Final f) {
705 recv_f_bit(f);
706 }
707
data_indicationbluetooth::l2cap::internal::ErtmController::impl708 void data_indication(SegmentationAndReassembly sar, uint16_t sdu_size, const packet::PacketView<true>& segment) {
709 controller_->stage_for_reassembly(sar, sdu_size, segment);
710 buffer_seq_ = (buffer_seq_ + 1) % kMaxTxWin;
711 }
712
increment_expected_tx_seqbluetooth::l2cap::internal::ErtmController::impl713 void increment_expected_tx_seq() {
714 expected_tx_seq_ = (expected_tx_seq_ + 1) % kMaxTxWin;
715 }
716
stop_retrans_timerbluetooth::l2cap::internal::ErtmController::impl717 void stop_retrans_timer() {
718 retrans_timer_.Cancel();
719 }
720
stop_monitor_timerbluetooth::l2cap::internal::ErtmController::impl721 void stop_monitor_timer() {
722 monitor_timer_.Cancel();
723 }
724
send_ackbluetooth::l2cap::internal::ErtmController::impl725 void send_ack(Final f = Final::NOT_SET) {
726 if (local_busy()) {
727 send_rnr(f);
728 } else if (!remote_busy() && !pending_frames_.empty() && rem_window_not_full()) {
729 send_pending_i_frames(f);
730 } else {
731 send_rr(f);
732 }
733 }
734
init_srejbluetooth::l2cap::internal::ErtmController::impl735 void init_srej() {
736 // We don't support sending SREJ
737 }
738
save_i_frame_srejbluetooth::l2cap::internal::ErtmController::impl739 void save_i_frame_srej() {
740 // We don't support sending SREJ
741 }
742
store_or_ignorebluetooth::l2cap::internal::ErtmController::impl743 void store_or_ignore() {
744 // We choose to ignore.
745 }
746
p_bit_outstandingbluetooth::l2cap::internal::ErtmController::impl747 bool p_bit_outstanding() {
748 return tx_state_ == TxState::WAIT_F;
749 }
750
retransmit_i_framesbluetooth::l2cap::internal::ErtmController::impl751 void retransmit_i_frames(uint8_t req_seq, Poll p = Poll::NOT_SET) {
752 uint8_t i = req_seq;
753 Final f = (p == Poll::NOT_SET ? Final::NOT_SET : Final::POLL_RESPONSE);
754 while (unacked_list_.find(i) != unacked_list_.end()) {
755 if (retry_i_frames_[i] == controller_->local_max_transmit_) {
756 CloseChannel();
757 return;
758 }
759 std::unique_ptr<CopyablePacketBuilder> copyable_packet_builder =
760 std::make_unique<CopyablePacketBuilder>(std::get<2>(unacked_list_.find(i)->second));
761 _send_i_frame(std::get<0>(unacked_list_.find(i)->second), std::move(copyable_packet_builder), buffer_seq_, i,
762 std::get<1>(unacked_list_.find(i)->second), f);
763 retry_i_frames_[i]++;
764 frames_sent_++;
765 f = Final::NOT_SET;
766 i++;
767 }
768 if (i != req_seq) {
769 start_retrans_timer();
770 }
771 }
772
retransmit_requested_i_framebluetooth::l2cap::internal::ErtmController::impl773 void retransmit_requested_i_frame(uint8_t req_seq, Poll p) {
774 Final f = p == Poll::POLL ? Final::POLL_RESPONSE : Final::NOT_SET;
775 if (unacked_list_.find(req_seq) == unacked_list_.end()) {
776 LOG_ERROR("Received invalid SREJ");
777 return;
778 }
779 std::unique_ptr<CopyablePacketBuilder> copyable_packet_builder =
780 std::make_unique<CopyablePacketBuilder>(std::get<2>(unacked_list_.find(req_seq)->second));
781 _send_i_frame(std::get<0>(unacked_list_.find(req_seq)->second), std::move(copyable_packet_builder), buffer_seq_,
782 req_seq, std::get<1>(unacked_list_.find(req_seq)->second), f);
783 retry_i_frames_[req_seq]++;
784 start_retrans_timer();
785 }
786
send_pending_i_framesbluetooth::l2cap::internal::ErtmController::impl787 void send_pending_i_frames(Final f = Final::NOT_SET) {
788 if (p_bit_outstanding()) {
789 return;
790 }
791 while (rem_window_not_full() && !pending_frames_.empty()) {
792 auto& frame = pending_frames_.front();
793 send_data(std::get<0>(frame), std::get<1>(frame), std::move(std::get<2>(frame)), f);
794 pending_frames_.pop();
795 f = Final::NOT_SET;
796 }
797 }
798
CloseChannelbluetooth::l2cap::internal::ErtmController::impl799 void CloseChannel() {
800 controller_->close_channel();
801 }
802
pop_srej_listbluetooth::l2cap::internal::ErtmController::impl803 void pop_srej_list() {
804 // We don't support sending SREJ
805 }
806
data_indication_srejbluetooth::l2cap::internal::ErtmController::impl807 void data_indication_srej() {
808 // We don't support sending SREJ
809 }
810 };
811
812 // Segmentation is handled here
OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu)813 void ErtmController::OnSdu(std::unique_ptr<packet::BasePacketBuilder> sdu) {
814 auto sdu_size = sdu->size();
815 std::vector<std::unique_ptr<packet::RawBuilder>> segments;
816 auto size_each_packet = (remote_mps_ - 4 /* basic L2CAP header */ - 2 /* SDU length */ - 2 /* Enhanced control */ -
817 (fcs_enabled_ ? 2 : 0));
818 packet::FragmentingInserter fragmenting_inserter(size_each_packet, std::back_insert_iterator(segments));
819 sdu->Serialize(fragmenting_inserter);
820 fragmenting_inserter.finalize();
821 if (segments.size() == 1) {
822 pimpl_->data_request(SegmentationAndReassembly::UNSEGMENTED, std::move(segments[0]));
823 return;
824 }
825 pimpl_->data_request(SegmentationAndReassembly::START, std::move(segments[0]), sdu_size);
826 for (auto i = 1; i < segments.size() - 1; i++) {
827 pimpl_->data_request(SegmentationAndReassembly::CONTINUATION, std::move(segments[i]));
828 }
829 pimpl_->data_request(SegmentationAndReassembly::END, std::move(segments.back()));
830 }
831
OnPdu(packet::PacketView<true> pdu)832 void ErtmController::OnPdu(packet::PacketView<true> pdu) {
833 if (fcs_enabled_) {
834 on_pdu_fcs(pdu);
835 } else {
836 on_pdu_no_fcs(pdu);
837 }
838 }
839
on_pdu_no_fcs(const packet::PacketView<true> & pdu)840 void ErtmController::on_pdu_no_fcs(const packet::PacketView<true>& pdu) {
841 auto basic_frame_view = BasicFrameView::Create(pdu);
842 if (!basic_frame_view.IsValid()) {
843 return;
844 }
845 auto standard_frame_view = StandardFrameView::Create(basic_frame_view);
846 if (!standard_frame_view.IsValid()) {
847 LOG_WARN("Received invalid frame");
848 return;
849 }
850 auto type = standard_frame_view.GetFrameType();
851 if (type == FrameType::I_FRAME) {
852 auto i_frame_view = EnhancedInformationFrameView::Create(standard_frame_view);
853 if (!i_frame_view.IsValid()) {
854 LOG_WARN("Received invalid frame");
855 return;
856 }
857 Final f = i_frame_view.GetF();
858 uint8_t tx_seq = i_frame_view.GetTxSeq();
859 uint8_t req_seq = i_frame_view.GetReqSeq();
860 auto sar = i_frame_view.GetSar();
861 if (sar == SegmentationAndReassembly::START) {
862 auto i_frame_start_view = EnhancedInformationStartFrameView::Create(i_frame_view);
863 if (!i_frame_start_view.IsValid()) {
864 LOG_WARN("Received invalid I-Frame START");
865 return;
866 }
867 pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, i_frame_start_view.GetL2capSduLength(),
868 i_frame_start_view.GetPayload());
869 } else {
870 pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, 0, i_frame_view.GetPayload());
871 }
872 } else if (type == FrameType::S_FRAME) {
873 auto s_frame_view = EnhancedSupervisoryFrameView::Create(standard_frame_view);
874 if (!s_frame_view.IsValid()) {
875 LOG_WARN("Received invalid frame");
876 return;
877 }
878 auto req_seq = s_frame_view.GetReqSeq();
879 auto f = s_frame_view.GetF();
880 auto p = s_frame_view.GetP();
881 switch (s_frame_view.GetS()) {
882 case SupervisoryFunction::RECEIVER_READY:
883 pimpl_->recv_rr(req_seq, p, f);
884 break;
885 case SupervisoryFunction::RECEIVER_NOT_READY:
886 pimpl_->recv_rnr(req_seq, p, f);
887 break;
888 case SupervisoryFunction::REJECT:
889 pimpl_->recv_rej(req_seq, p, f);
890 break;
891 case SupervisoryFunction::SELECT_REJECT:
892 pimpl_->recv_srej(req_seq, p, f);
893 break;
894 }
895 } else {
896 LOG_WARN("Received invalid frame");
897 }
898 }
899
on_pdu_fcs(const packet::PacketView<true> & pdu)900 void ErtmController::on_pdu_fcs(const packet::PacketView<true>& pdu) {
901 auto basic_frame_view = BasicFrameWithFcsView::Create(pdu);
902 if (!basic_frame_view.IsValid()) {
903 return;
904 }
905 auto standard_frame_view = StandardFrameWithFcsView::Create(basic_frame_view);
906 if (!standard_frame_view.IsValid()) {
907 LOG_WARN("Received invalid frame");
908 return;
909 }
910 auto type = standard_frame_view.GetFrameType();
911 if (type == FrameType::I_FRAME) {
912 auto i_frame_view = EnhancedInformationFrameWithFcsView::Create(standard_frame_view);
913 if (!i_frame_view.IsValid()) {
914 LOG_WARN("Received invalid frame");
915 return;
916 }
917 Final f = i_frame_view.GetF();
918 uint8_t tx_seq = i_frame_view.GetTxSeq();
919 uint8_t req_seq = i_frame_view.GetReqSeq();
920 auto sar = i_frame_view.GetSar();
921 if (sar == SegmentationAndReassembly::START) {
922 auto i_frame_start_view = EnhancedInformationStartFrameWithFcsView::Create(i_frame_view);
923 if (!i_frame_start_view.IsValid()) {
924 LOG_WARN("Received invalid I-Frame START");
925 return;
926 }
927 pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, i_frame_start_view.GetL2capSduLength(),
928 i_frame_start_view.GetPayload());
929 } else {
930 pimpl_->recv_i_frame(f, tx_seq, req_seq, sar, 0, i_frame_view.GetPayload());
931 }
932 } else if (type == FrameType::S_FRAME) {
933 auto s_frame_view = EnhancedSupervisoryFrameWithFcsView::Create(standard_frame_view);
934 if (!s_frame_view.IsValid()) {
935 LOG_WARN("Received invalid frame");
936 return;
937 }
938 auto req_seq = s_frame_view.GetReqSeq();
939 auto f = s_frame_view.GetF();
940 auto p = s_frame_view.GetP();
941 switch (s_frame_view.GetS()) {
942 case SupervisoryFunction::RECEIVER_READY:
943 pimpl_->recv_rr(req_seq, p, f);
944 break;
945 case SupervisoryFunction::RECEIVER_NOT_READY:
946 pimpl_->recv_rnr(req_seq, p, f);
947 break;
948 case SupervisoryFunction::REJECT:
949 pimpl_->recv_rej(req_seq, p, f);
950 break;
951 case SupervisoryFunction::SELECT_REJECT:
952 pimpl_->recv_srej(req_seq, p, f);
953 break;
954 }
955 } else {
956 LOG_WARN("Received invalid frame");
957 }
958 }
959
GetNextPacket()960 std::unique_ptr<packet::BasePacketBuilder> ErtmController::GetNextPacket() {
961 auto next = std::move(pdu_queue_.front());
962 pdu_queue_.pop();
963 return next;
964 }
965
stage_for_reassembly(SegmentationAndReassembly sar,uint16_t sdu_size,const packet::PacketView<kLittleEndian> & payload)966 void ErtmController::stage_for_reassembly(SegmentationAndReassembly sar, uint16_t sdu_size,
967 const packet::PacketView<kLittleEndian>& payload) {
968 // If EnqueueBuffer has more than 1 packets, we claim LocalBusy, until queue is empty
969 constexpr size_t kEnqueueBufferBusyThreshold = 3;
970 switch (sar) {
971 case SegmentationAndReassembly::UNSEGMENTED:
972 if (sar_state_ != SegmentationAndReassembly::END) {
973 LOG_WARN("Received invalid SAR");
974 close_channel();
975 return;
976 }
977 // TODO: Enforce MTU
978 enqueue_buffer_.Enqueue(std::make_unique<packet::PacketView<kLittleEndian>>(payload), handler_);
979 if (enqueue_buffer_.Size() == kEnqueueBufferBusyThreshold) {
980 pimpl_->local_busy_detected();
981 enqueue_buffer_.NotifyOnEmpty(common::BindOnce(&impl::local_busy_clear, common::Unretained(pimpl_.get())));
982 }
983 break;
984 case SegmentationAndReassembly::START:
985 if (sar_state_ != SegmentationAndReassembly::END) {
986 LOG_WARN("Received invalid SAR");
987 close_channel();
988 return;
989 }
990 // TODO: Enforce MTU
991 sar_state_ = SegmentationAndReassembly::START;
992 reassembly_stage_ = payload;
993 remaining_sdu_continuation_packet_size_ = sdu_size - payload.size();
994 break;
995 case SegmentationAndReassembly::CONTINUATION:
996 if (sar_state_ == SegmentationAndReassembly::END) {
997 LOG_WARN("Received invalid SAR");
998 close_channel();
999 return;
1000 }
1001 reassembly_stage_.AppendPacketView(payload);
1002 remaining_sdu_continuation_packet_size_ -= payload.size();
1003 break;
1004 case SegmentationAndReassembly::END:
1005 if (sar_state_ == SegmentationAndReassembly::END) {
1006 LOG_WARN("Received invalid SAR");
1007 close_channel();
1008 return;
1009 }
1010 sar_state_ = SegmentationAndReassembly::END;
1011 remaining_sdu_continuation_packet_size_ -= payload.size();
1012 if (remaining_sdu_continuation_packet_size_ != 0) {
1013 LOG_WARN("Received invalid END I-Frame");
1014 reassembly_stage_ =
1015 PacketViewForReassembly(PacketView<kLittleEndian>(std::make_shared<std::vector<uint8_t>>()));
1016 remaining_sdu_continuation_packet_size_ = 0;
1017 close_channel();
1018 return;
1019 }
1020 reassembly_stage_.AppendPacketView(payload);
1021 enqueue_buffer_.Enqueue(std::make_unique<packet::PacketView<kLittleEndian>>(reassembly_stage_), handler_);
1022 if (enqueue_buffer_.Size() == kEnqueueBufferBusyThreshold) {
1023 pimpl_->local_busy_detected();
1024 enqueue_buffer_.NotifyOnEmpty(common::BindOnce(&impl::local_busy_clear, common::Unretained(pimpl_.get())));
1025 }
1026 break;
1027 }
1028 }
1029
EnableFcs(bool enabled)1030 void ErtmController::EnableFcs(bool enabled) {
1031 fcs_enabled_ = enabled;
1032 }
1033
send_pdu(std::unique_ptr<packet::BasePacketBuilder> pdu)1034 void ErtmController::send_pdu(std::unique_ptr<packet::BasePacketBuilder> pdu) {
1035 pdu_queue_.emplace(std::move(pdu));
1036 scheduler_->OnPacketsReady(cid_, 1);
1037 }
1038
SetRetransmissionAndFlowControlOptions(const RetransmissionAndFlowControlConfigurationOption & option)1039 void ErtmController::SetRetransmissionAndFlowControlOptions(
1040 const RetransmissionAndFlowControlConfigurationOption& option) {
1041 remote_tx_window_ = option.tx_window_size_;
1042 local_max_transmit_ = option.max_transmit_;
1043 local_retransmit_timeout_ms_ = option.retransmission_time_out_;
1044 local_monitor_timeout_ms_ = option.monitor_time_out_;
1045 remote_mps_ = option.maximum_pdu_size_;
1046 }
1047
close_channel()1048 void ErtmController::close_channel() {
1049 link_->SendDisconnectionRequest(cid_, remote_cid_);
1050 }
1051
size() const1052 size_t ErtmController::CopyablePacketBuilder::size() const {
1053 return builder_->size();
1054 }
1055
Serialize(BitInserter & it) const1056 void ErtmController::CopyablePacketBuilder::Serialize(BitInserter& it) const {
1057 builder_->Serialize(it);
1058 }
1059
1060 } // namespace internal
1061 } // namespace l2cap
1062 } // namespace bluetooth
1063