1 /*
2  * Copyright 2022 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 <bluetooth/log.h>
18 #include <fcntl.h>
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 #include <sys/socket.h>
22 
23 #include "hci/controller_interface_mock.h"
24 #include "osi/include/allocator.h"
25 #include "stack/btm/btm_int_types.h"
26 #include "stack/include/bt_psm_types.h"
27 #include "stack/include/l2cap_controller_interface.h"
28 #include "stack/include/l2cap_hci_link_interface.h"
29 #include "stack/include/l2cap_module.h"
30 #include "stack/include/l2cdefs.h"
31 #include "stack/l2cap/l2c_int.h"
32 #include "test/mock/mock_main_shim_entry.h"
33 
34 tBTM_CB btm_cb;
35 extern tL2C_CB l2cb;
36 
37 void l2c_link_send_to_lower_br_edr(tL2C_LCB* p_lcb, BT_HDR* p_buf);
38 void l2c_link_send_to_lower_ble(tL2C_LCB* p_lcb, BT_HDR* p_buf);
39 
40 using testing::Return;
41 
42 namespace {
43 constexpr uint16_t kAclBufferCountClassic = 123;
44 constexpr uint16_t kAclBufferCountBle = 45;
45 constexpr uint16_t kAclBufferSizeBle = 45;
46 
47 }  // namespace
48 
49 class StackL2capTest : public ::testing::Test {
50 protected:
SetUp()51   void SetUp() override {
52     bluetooth::hci::testing::mock_controller_ = &controller_interface_;
53     ON_CALL(controller_interface_, GetNumAclPacketBuffers)
54             .WillByDefault(Return(kAclBufferCountClassic));
55     bluetooth::hci::LeBufferSize le_sizes;
56     le_sizes.total_num_le_packets_ = kAclBufferCountBle;
57     le_sizes.le_data_packet_length_ = kAclBufferSizeBle;
58     ON_CALL(controller_interface_, GetLeBufferSize).WillByDefault(Return(le_sizes));
59     ON_CALL(controller_interface_, SupportsBle).WillByDefault(Return(true));
60     l2c_init();
61   }
62 
TearDown()63   void TearDown() override {
64     l2c_free();
65     bluetooth::hci::testing::mock_controller_ = nullptr;
66   }
67 
68   bluetooth::hci::testing::MockControllerInterface controller_interface_;
69 };
70 
TEST_F(StackL2capTest,l2cble_process_data_length_change_event)71 TEST_F(StackL2capTest, l2cble_process_data_length_change_event) {
72   l2cb.lcb_pool[0].tx_data_len = 0xdead;
73 
74   // ACL unknown and legal inputs
75   l2cble_process_data_length_change_event(0x1234, 0x001b, 0x001b);
76   ASSERT_EQ(0xdead, l2cb.lcb_pool[0].tx_data_len);
77 
78   l2cb.lcb_pool[0].in_use = true;
79   l2cu_set_lcb_handle(l2cb.lcb_pool[0], 0x1234);
80   ASSERT_EQ(0x1234, l2cb.lcb_pool[0].Handle());
81 
82   // ACL known and illegal inputs
83   l2cble_process_data_length_change_event(0x1234, 1, 1);
84   ASSERT_EQ(0xdead, l2cb.lcb_pool[0].tx_data_len);
85 
86   // ACL known and legal inputs
87   l2cble_process_data_length_change_event(0x1234, 0x001b, 0x001b);
88   ASSERT_EQ(0x001b, l2cb.lcb_pool[0].tx_data_len);
89 }
90 
91 class StackL2capChannelTest : public StackL2capTest {
92 protected:
SetUp()93   void SetUp() override { StackL2capTest::SetUp(); }
94 
TearDown()95   void TearDown() override { StackL2capTest::TearDown(); }
96 
97   tL2C_CCB ccb_ = {
98           .in_use = true,
99           .chnl_state = CST_OPEN,  // tL2C_CHNL_STATE
100           .local_conn_cfg =
101                   {
102                           // tL2CAP_LE_CFG_INFO
103                           .result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK,
104                           .mtu = 100,
105                           .mps = 100,
106                           .credits = L2CA_LeCreditDefault(),
107                           .number_of_channels = L2CAP_CREDIT_BASED_MAX_CIDS,
108                   },
109           .peer_conn_cfg =
110                   {
111                           // tL2CAP_LE_CFG_INFO
112                           .result = tL2CAP_CFG_RESULT::L2CAP_CFG_OK,
113                           .mtu = 100,
114                           .mps = 100,
115                           .credits = L2CA_LeCreditDefault(),
116                           .number_of_channels = L2CAP_CREDIT_BASED_MAX_CIDS,
117                   },
118           .is_first_seg = false,
119           .ble_sdu = nullptr,     // BT_HDR*; Buffer for storing unassembled sdu
120           .ble_sdu_length = 0,    /* Length of unassembled sdu length*/
121           .p_next_ccb = nullptr,  // struct t_l2c_ccb* Next CCB in the chain
122           .p_prev_ccb = nullptr,  // struct t_l2c_ccb* Previous CCB in the chain
123           .p_lcb = nullptr,       // struct t_l2c_linkcb* Link this CCB is assigned to
124           .local_cid = 40,
125           .remote_cid = 80,
126           .l2c_ccb_timer = nullptr,  // alarm_t* CCB Timer Entry
127           .p_rcb = nullptr,          // tL2C_RCB* Registration CB for this Channel
128           .config_done = 0,          // Configuration flag word
129           .remote_config_rsp_result =
130                   tL2CAP_CFG_RESULT::L2CAP_CFG_OK,  // The config rsp result from remote
131           .local_id = 12,                           // Transaction ID for local trans
132           .remote_id = 22,                          // Transaction ID for local
133           .flags = 0,
134           .connection_initiator = false,
135           .our_cfg = {},           // tL2CAP_CFG_INFO Our saved configuration options
136           .peer_cfg = {},          // tL2CAP_CFG_INFO Peer's saved configuration options
137           .xmit_hold_q = nullptr,  // fixed_queue_t*  Transmit data hold queue
138           .cong_sent = false,
139           .buff_quota = 0,
140 
141           .ccb_priority = L2CAP_CHNL_PRIORITY_HIGH,  // tL2CAP_CHNL_PRIORITY Channel priority
142           .tx_data_rate = 0,                         // tL2CAP_CHNL_PRIORITY  Channel Tx data rate
143           .rx_data_rate = 0,                         // tL2CAP_CHNL_PRIORITY  Channel Rx data rate
144 
145           .ertm_info =
146                   {
147                           // .tL2CAP_ERTM_INFO
148                           .preferred_mode = 0,
149                   },
150           .fcrb =
151                   {
152                           // tL2C_FCRB
153                           .next_tx_seq = 0,
154                           .last_rx_ack = 0,
155                           .next_seq_expected = 0,
156                           .last_ack_sent = 0,
157                           .num_tries = 0,
158                           .max_held_acks = 0,
159                           .remote_busy = false,
160                           .rej_sent = false,
161                           .srej_sent = false,
162                           .wait_ack = false,
163                           .rej_after_srej = false,
164                           .send_f_rsp = false,
165                           .rx_sdu_len = 0,
166                           .p_rx_sdu = nullptr,  // BT_HDR* Buffer holding the SDU being received
167                           .waiting_for_ack_q = nullptr,  // fixed_queue_t*
168                           .srej_rcv_hold_q = nullptr,    // fixed_queue_t*
169                           .retrans_q = nullptr,          // fixed_queue_t*
170                           .ack_timer = nullptr,          // alarm_t*
171                           .mon_retrans_timer = nullptr,  // alarm_t*
172                   },
173           .tx_mps = 0,
174           .max_rx_mtu = 0,
175           .fcr_cfg_tries = 0,
176           .peer_cfg_already_rejected = false,
177           .out_cfg_fcr_present = false,
178           .is_flushable = false,
179           .fixed_chnl_idle_tout = 0,
180           .tx_data_len = 0,
181           .remote_credit_count = 0,
182           .ecoc = false,
183           .reconfig_started = false,
184           .metrics = {},
185   };
186 };
187 
TEST_F(StackL2capChannelTest,l2c_lcc_proc_pdu__FirstSegment)188 TEST_F(StackL2capChannelTest, l2c_lcc_proc_pdu__FirstSegment) {
189   ccb_.is_first_seg = true;
190 
191   BT_HDR* p_buf = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + 32);
192   p_buf->len = 32;
193 
194   l2c_lcc_proc_pdu(&ccb_, p_buf);
195 }
196 
TEST_F(StackL2capChannelTest,l2c_lcc_proc_pdu__NextSegment)197 TEST_F(StackL2capChannelTest, l2c_lcc_proc_pdu__NextSegment) {
198   BT_HDR* p_buf = (BT_HDR*)osi_calloc(sizeof(BT_HDR) + 32);
199   p_buf->len = 32;
200 
201   l2c_lcc_proc_pdu(&ccb_, p_buf);
202 }
203 
TEST_F(StackL2capChannelTest,l2c_link_init)204 TEST_F(StackL2capChannelTest, l2c_link_init) {
205   l2cb.num_lm_acl_bufs = 0;
206   l2cb.controller_xmit_window = 0;
207   l2c_link_init(kAclBufferCountClassic);
208 
209   ASSERT_EQ(kAclBufferCountClassic, l2cb.num_lm_acl_bufs);
210   ASSERT_EQ(kAclBufferCountClassic, l2cb.controller_xmit_window);
211 }
212 
TEST_F(StackL2capTest,l2cap_result_code_text)213 TEST_F(StackL2capTest, l2cap_result_code_text) {
214   std::vector<std::pair<tL2CAP_CONN, std::string>> results = {
215           std::make_pair(tL2CAP_CONN::L2CAP_CONN_OK, "tL2CAP_CONN::L2CAP_CONN_OK(0x0000)"),
216           std::make_pair(tL2CAP_CONN::L2CAP_CONN_PENDING,
217                          "tL2CAP_CONN::L2CAP_CONN_PENDING(0x0001)"),
218           std::make_pair(tL2CAP_CONN::L2CAP_CONN_NO_PSM, "tL2CAP_CONN::L2CAP_CONN_NO_PSM(0x0002)"),
219           std::make_pair(tL2CAP_CONN::L2CAP_CONN_SECURITY_BLOCK,
220                          "tL2CAP_CONN::L2CAP_CONN_SECURITY_BLOCK(0x0003)"),
221           std::make_pair(tL2CAP_CONN::L2CAP_CONN_NO_RESOURCES,
222                          "tL2CAP_CONN::L2CAP_CONN_NO_RESOURCES(0x0004)"),
223           std::make_pair(tL2CAP_CONN::L2CAP_CONN_TIMEOUT,
224                          "tL2CAP_CONN::L2CAP_CONN_TIMEOUT(0xeeee)"),
225           std::make_pair(tL2CAP_CONN::L2CAP_CONN_OTHER_ERROR,
226                          "tL2CAP_CONN::L2CAP_CONN_OTHER_ERROR(0xf000)"),
227           std::make_pair(tL2CAP_CONN::L2CAP_CONN_ACL_CONNECTION_FAILED,
228 
229                          "tL2CAP_CONN::L2CAP_CONN_ACL_CONNECTION_FAILED(0xf001)"),
230           std::make_pair(tL2CAP_CONN::L2CAP_CONN_CLIENT_SECURITY_CLEARANCE_FAILED,
231                          "tL2CAP_CONN::L2CAP_CONN_CLIENT_SECURITY_CLEARANCE_FAILED(0xf002)"),
232           std::make_pair(tL2CAP_CONN::L2CAP_CONN_NO_LINK,
233                          "tL2CAP_CONN::L2CAP_CONN_NO_LINK(0xf003)"),
234           std::make_pair(tL2CAP_CONN::L2CAP_CONN_CANCEL, "tL2CAP_CONN::L2CAP_CONN_CANCEL(0xf004)"),
235           std::make_pair(tL2CAP_CONN::L2CAP_CONN_INSUFFICIENT_AUTHENTICATION,
236                          "tL2CAP_CONN::L2CAP_CONN_INSUFFICIENT_AUTHENTICATION(0xff05)"),
237           std::make_pair(tL2CAP_CONN::L2CAP_CONN_INSUFFICIENT_AUTHORIZATION,
238                          "tL2CAP_CONN::L2CAP_CONN_INSUFFICIENT_AUTHORIZATION(0xff06)"),
239           std::make_pair(tL2CAP_CONN::L2CAP_CONN_INSUFFICIENT_ENCRYP_KEY_SIZE,
240                          "tL2CAP_CONN::L2CAP_CONN_INSUFFICIENT_ENCRYP_KEY_SIZE(0xff07)"),
241           std::make_pair(tL2CAP_CONN::L2CAP_CONN_INSUFFICIENT_ENCRYP,
242                          "tL2CAP_CONN::L2CAP_CONN_INSUFFICIENT_ENCRYP(0xff08)"),
243           std::make_pair(tL2CAP_CONN::L2CAP_CONN_INVALID_SOURCE_CID,
244                          "tL2CAP_CONN::L2CAP_CONN_INVALID_SOURCE_CID(0xff09)"),
245           std::make_pair(tL2CAP_CONN::L2CAP_CONN_SOURCE_CID_ALREADY_ALLOCATED,
246                          "tL2CAP_CONN::L2CAP_CONN_SOURCE_CID_ALREADY_ALLOCATED(0xff0a)"),
247           std::make_pair(tL2CAP_CONN::L2CAP_CONN_UNACCEPTABLE_PARAMETERS,
248 
249                          "tL2CAP_CONN::L2CAP_CONN_UNACCEPTABLE_PARAMETERS(0xff0b)"),
250           std::make_pair(tL2CAP_CONN::L2CAP_CONN_INVALID_PARAMETERS,
251                          "tL2CAP_CONN::L2CAP_CONN_INVALID_PARAMETERS(0xff0c)"),
252   };
253   for (const auto& result : results) {
254     ASSERT_STREQ(result.second.c_str(), l2cap_result_code_text(result.first).c_str());
255   }
256   std::ostringstream oss;
257   oss << "Unknown tL2CAP_CONN(" << std::hex << "0x" << std::numeric_limits<std::uint16_t>::max()
258       << ")";
259   ASSERT_STREQ(oss.str().c_str(),
260                l2cap_result_code_text(
261                        static_cast<tL2CAP_CONN>(std::numeric_limits<std::uint16_t>::max()))
262                        .c_str());
263 }
264 
TEST_F(StackL2capTest,L2CA_Dumpsys)265 TEST_F(StackL2capTest, L2CA_Dumpsys) {
266   int sv[2];
267   char buf[32];
268   ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sv));
269   ASSERT_EQ(0, fcntl(sv[1], F_SETFL, fcntl(sv[1], F_GETFL, 0) | O_NONBLOCK));
270 
271   L2CA_Dumpsys(sv[0]);
272   while (read(sv[1], buf, sizeof(buf)) != -1) {
273   }
274 }
275 
TEST_F(StackL2capTest,bt_psm_text)276 TEST_F(StackL2capTest, bt_psm_text) {
277   std::map<tBT_PSM, std::string> map = {
278           {BT_PSM_SDP, "BT_PSM_SDP"},
279           {BT_PSM_RFCOMM, "BT_PSM_RFCOMM"},
280           {BT_PSM_TCS, "BT_PSM_TCS"},
281           {BT_PSM_CTP, "BT_PSM_CTP"},
282           {BT_PSM_BNEP, "BT_PSM_BNEP"},
283           {BT_PSM_HIDC, "BT_PSM_HIDC"},
284           {HID_PSM_CONTROL, "HID_PSM_CONTROL"},
285           {BT_PSM_HIDI, "BT_PSM_HIDI"},
286           {HID_PSM_INTERRUPT, "HID_PSM_INTERRUPT"},
287           {BT_PSM_UPNP, "BT_PSM_UPNP"},
288           {BT_PSM_AVCTP, "BT_PSM_AVCTP"},
289           {BT_PSM_AVDTP, "BT_PSM_AVDTP"},
290           {BT_PSM_AVCTP_BROWSE, "BT_PSM_AVCTP_BROWSE"},
291           {BT_PSM_UDI_CP, "BT_PSM_UDI_CP"},
292           {BT_PSM_ATT, "BT_PSM_ATT"},
293           {BT_PSM_EATT, "BT_PSM_EATT"},
294           {BRCM_RESERVED_PSM_START, "BRCM_RESERVED_PSM_START"},
295           {BRCM_RESERVED_PSM_END, "BRCM_RESERVED_PSM_END"},
296   };
297 
298   for (const auto& it : map) {
299     bluetooth::log::info("{} {} ", bt_psm_text(it.first), it.second);
300   }
301 }
302