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