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