• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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