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