1 /******************************************************************************
3 * Copyright 2018 The Android Open Source Project
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 ******************************************************************************/
19 #include <base/logging.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
26 #include "osi/include/osi.h"
30 #include "hci/include/btsnoop.h"
33 #include "mock_btm_layer.h"
34 #include "mock_l2cap_layer.h"
35 #include "stack_rfcomm_test_utils.h"
36 #include "stack_test_packet_utils.h"
38 static void capture(const BT_HDR*, bool) { /* do nothing */
40 static void whitelist_l2c_channel(uint16_t, uint16_t,
41 uint16_t) { /* do nothing */
43 static void whitelist_rfc_dlci(uint16_t, uint8_t) { /* do nothing */
45 static void add_rfc_l2c_channel(uint16_t, uint16_t, uint16_t) { /* do nothing */
47 static void clear_l2cap_whitelist(uint16_t, uint16_t,
48 uint16_t) { /* do nothing */
50 static const btsnoop_t fake_snoop = {capture, whitelist_l2c_channel,
51 whitelist_rfc_dlci, add_rfc_l2c_channel,
52 clear_l2cap_whitelist};
53 const btsnoop_t* btsnoop_get_interface() { return &fake_snoop; }
55 std::string DumpByteBufferToString(uint8_t* p_data, size_t len) {
56 std::stringstream str;
57 str.setf(std::ios_base::hex, std::ios::basefield);
58 str.setf(std::ios_base::uppercase);
60 for (size_t i = 0; i < len; ++i) {
61 str << std::setw(2) << static_cast<uint16_t>(p_data[i]);
67 uint16_t L2CA_Register(unsigned short, tL2CAP_APPL_INFO*, bool) { return 0; }
69 std::string DumpBtHdrToString(BT_HDR* p_hdr) {
70 uint8_t* p_hdr_data = p_hdr->data + p_hdr->offset;
71 return DumpByteBufferToString(p_hdr_data, p_hdr->len);
74 void PrintTo(BT_HDR* value, ::std::ostream* os) {
75 *os << DumpBtHdrToString(value);
78 void PrintTo(tL2CAP_CFG_INFO* value, ::std::ostream* os) {
79 *os << DumpByteBufferToString((uint8_t*)value, sizeof(tL2CAP_CFG_INFO));
86 using testing::Return;
88 using testing::StrictMock;
89 using testing::SaveArg;
90 using testing::SaveArgPointee;
91 using testing::Pointee;
93 using testing::NotNull;
95 using bluetooth::CreateL2capDataPacket;
96 using bluetooth::CreateAclPacket;
97 using bluetooth::AllocateWrappedIncomingL2capAclPacket;
98 using bluetooth::AllocateWrappedOutgoingL2capAclPacket;
100 using bluetooth::rfcomm::GetDlci;
101 using bluetooth::rfcomm::GetAddressField;
102 using bluetooth::rfcomm::GetControlField;
103 using bluetooth::rfcomm::CreateMccPnFrame;
104 using bluetooth::rfcomm::CreateMccMscFrame;
105 using bluetooth::rfcomm::CreateMultiplexerControlFrame;
106 using bluetooth::rfcomm::CreateRfcommPacket;
107 using bluetooth::rfcomm::CreateQuickDataPacket;
108 using bluetooth::rfcomm::CreateQuickPnPacket;
109 using bluetooth::rfcomm::CreateQuickSabmPacket;
110 using bluetooth::rfcomm::CreateQuickUaPacket;
111 using bluetooth::rfcomm::CreateQuickMscPacket;
113 MATCHER_P(PointerMemoryEqual, ptr,
114 DumpByteBufferToString((uint8_t*)ptr, sizeof(*ptr))) {
115 return memcmp(arg, ptr, sizeof(*ptr)) == 0;
118 MATCHER_P(BtHdrEqual, expected, DumpBtHdrToString(expected)) {
119 auto arg_hdr = static_cast<BT_HDR*>(arg);
120 uint8_t* arg_data = arg_hdr->data + arg_hdr->offset;
121 auto expected_hdr = static_cast<BT_HDR*>(expected);
122 uint8_t* expected_data = expected_hdr->data + expected_hdr->offset;
123 return memcmp(arg_data, expected_data, expected_hdr->len) == 0;
126 bluetooth::rfcomm::MockRfcommCallback* rfcomm_callback = nullptr;
128 void port_mgmt_cback_0(uint32_t code, uint16_t port_handle) {
129 rfcomm_callback->PortManagementCallback(code, port_handle, 0);
132 void port_mgmt_cback_1(uint32_t code, uint16_t port_handle) {
133 rfcomm_callback->PortManagementCallback(code, port_handle, 1);
136 void port_event_cback_0(uint32_t code, uint16_t port_handle) {
137 rfcomm_callback->PortEventCallback(code, port_handle, 0);
140 void port_event_cback_1(uint32_t code, uint16_t port_handle) {
141 rfcomm_callback->PortEventCallback(code, port_handle, 1);
144 RawAddress GetTestAddress(int index) {
145 CHECK_LT(index, UINT8_MAX);
146 RawAddress result = {
147 {0xAA, 0x00, 0x11, 0x22, 0x33, static_cast<uint8_t>(index)}};
151 class StackRfcommTest : public Test {
153 void StartServerPort(uint16_t uuid, uint8_t scn, uint16_t mtu,
154 tPORT_CALLBACK* management_callback,
155 tPORT_CALLBACK* event_callback,
156 uint16_t* server_handle) {
158 ASSERT_EQ(RFCOMM_CreateConnection(uuid, scn, true, mtu, RawAddress::kAny,
159 server_handle, management_callback),
161 ASSERT_EQ(PORT_SetEventMask(*server_handle, PORT_EV_RXCHAR), PORT_SUCCESS);
162 ASSERT_EQ(PORT_SetEventCallback(*server_handle, event_callback),
166 void ConnectServerL2cap(const RawAddress& peer_addr, uint16_t acl_handle,
169 // Remote device connect to this channel, we shall accept
170 static const uint8_t cmd_id = 0x07;
171 EXPECT_CALL(l2cap_interface_,
172 ConnectResponse(peer_addr, cmd_id, lcid, L2CAP_CONN_OK, 0));
173 tL2CAP_CFG_INFO cfg_req = {.mtu_present = true, .mtu = L2CAP_MTU_SIZE};
174 EXPECT_CALL(l2cap_interface_,
175 ConfigRequest(lcid, PointerMemoryEqual(&cfg_req)))
176 .WillOnce(Return(true));
177 l2cap_appl_info_.pL2CA_ConnectInd_Cb(peer_addr, lcid, BT_PSM_RFCOMM,
181 // MTU configuration is done
182 cfg_req.mtu_present = false;
183 l2cap_appl_info_.pL2CA_ConfigCfm_Cb(lcid, &cfg_req);
186 // Remote device also ask to configure MTU size
187 EXPECT_CALL(l2cap_interface_,
188 ConfigResponse(lcid, PointerMemoryEqual(&cfg_req)))
189 .WillOnce(Return(true));
190 l2cap_appl_info_.pL2CA_ConfigInd_Cb(lcid, &cfg_req);
193 // Remote device connect to server channel 0
194 BT_HDR* sabm_channel_0 = AllocateWrappedIncomingL2capAclPacket(
195 CreateQuickSabmPacket(RFCOMM_MX_DLCI, lcid, acl_handle));
196 BT_HDR* ua_channel_0 = AllocateWrappedOutgoingL2capAclPacket(
197 CreateQuickUaPacket(RFCOMM_MX_DLCI, lcid, acl_handle));
198 EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(ua_channel_0)))
199 .WillOnce(Return(L2CAP_DW_SUCCESS));
200 // Packet should be freed by RFCOMM
201 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, sabm_channel_0);
202 osi_free(ua_channel_0);
205 void ConnectServerPort(const RawAddress& peer_addr, uint16_t port_handle,
206 uint8_t scn, uint16_t mtu, uint16_t acl_handle,
207 uint16_t lcid, int port_callback_index) {
209 // Negotiate parameters on scn
210 BT_HDR* uih_pn_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket(
211 CreateQuickPnPacket(true, GetDlci(false, scn), true, mtu,
212 RFCOMM_PN_CONV_LAYER_CBFC_I >> 4, 0, RFCOMM_K_MAX,
214 BT_HDR* uih_pn_rsp_to_peer = AllocateWrappedOutgoingL2capAclPacket(
215 CreateQuickPnPacket(false, GetDlci(false, scn), false, mtu,
216 RFCOMM_PN_CONV_LAYER_CBFC_R >> 4, 0, RFCOMM_K_MAX,
218 EXPECT_CALL(l2cap_interface_,
219 DataWrite(lcid, BtHdrEqual(uih_pn_rsp_to_peer)))
220 .WillOnce(Return(L2CAP_DW_SUCCESS));
221 // uih_pn_cmd_from_peer should be freed by this method
222 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_pn_cmd_from_peer);
223 osi_free(uih_pn_rsp_to_peer);
226 // Remote device connect to scn
227 tBTM_SEC_CALLBACK* security_callback = nullptr;
228 void* p_port = nullptr;
229 BT_HDR* sabm_channel_dlci = AllocateWrappedIncomingL2capAclPacket(
230 CreateQuickSabmPacket(GetDlci(false, scn), lcid, acl_handle));
231 EXPECT_CALL(btm_security_internal_interface_,
232 MultiplexingProtocolAccessRequest(peer_addr, BT_PSM_RFCOMM,
233 false, BTM_SEC_PROTO_RFCOMM,
234 scn, NotNull(), NotNull()))
235 .WillOnce(DoAll(SaveArg<5>(&security_callback), SaveArg<6>(&p_port),
236 Return(BTM_SUCCESS)));
237 // sabm_channel_dlci should be freed by this method
238 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, sabm_channel_dlci);
241 // Confirm security check should trigger port as connected
244 PortManagementCallback(PORT_SUCCESS, port_handle, port_callback_index));
245 BT_HDR* ua_channel_dlci = AllocateWrappedOutgoingL2capAclPacket(
246 CreateQuickUaPacket(GetDlci(false, scn), lcid, acl_handle));
247 EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(ua_channel_dlci)))
248 .WillOnce(Return(L2CAP_DW_SUCCESS));
249 ASSERT_TRUE(security_callback);
250 security_callback(&peer_addr, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS);
251 osi_free(ua_channel_dlci);
254 // Remote also need to configure its modem signal before we can send data
255 BT_HDR* uih_msc_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket(
256 CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, true,
257 false, true, true, false, true));
258 BT_HDR* uih_msc_response_to_peer = AllocateWrappedOutgoingL2capAclPacket(
259 CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle,
260 false, false, true, true, false, true));
261 // We also have to do modem configuration ourself
262 EXPECT_CALL(l2cap_interface_,
263 DataWrite(lcid, BtHdrEqual(uih_msc_response_to_peer)))
264 .WillOnce(Return(L2CAP_DW_SUCCESS));
265 BT_HDR* uih_msc_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket(
266 CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle, true,
267 false, true, true, false, true));
268 EXPECT_CALL(l2cap_interface_,
269 DataWrite(lcid, BtHdrEqual(uih_msc_cmd_to_peer)))
270 .WillOnce(Return(L2CAP_DW_SUCCESS));
271 // uih_msc_cmd_from_peer should be freed by this method
272 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_cmd_from_peer);
273 osi_free(uih_msc_response_to_peer);
276 // modem configuration is done
277 BT_HDR* uih_msc_response_from_peer = AllocateWrappedIncomingL2capAclPacket(
278 CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, false,
279 false, true, true, false, true));
280 // uih_msc_response_from_peer should be freed by this method
281 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_response_from_peer);
284 void StartClientPort(const RawAddress& peer_bd_addr, uint16_t uuid,
285 uint8_t scn, uint16_t mtu,
286 tPORT_CALLBACK* management_callback,
287 tPORT_CALLBACK* event_callback, uint16_t lcid,
288 uint16_t acl_handle, uint16_t* client_handle,
289 bool is_first_connection) {
291 BT_HDR* uih_pn_channel_3 =
292 AllocateWrappedOutgoingL2capAclPacket(CreateQuickPnPacket(
293 true, GetDlci(false, scn), true, mtu, RFCOMM_PN_CONV_LAYER_TYPE_1,
294 RFCOMM_PN_PRIORITY_0, RFCOMM_K, lcid, acl_handle));
295 if (is_first_connection) {
296 EXPECT_CALL(l2cap_interface_, ConnectRequest(BT_PSM_RFCOMM, peer_bd_addr))
297 .WillOnce(Return(lcid));
299 EXPECT_CALL(l2cap_interface_,
300 DataWrite(lcid, BtHdrEqual(uih_pn_channel_3)))
301 .WillOnce(Return(L2CAP_DW_SUCCESS));
303 ASSERT_EQ(RFCOMM_CreateConnection(uuid, scn, false, mtu, peer_bd_addr,
304 client_handle, management_callback),
306 ASSERT_EQ(PORT_SetEventMask(*client_handle, PORT_EV_RXCHAR), PORT_SUCCESS);
307 ASSERT_EQ(PORT_SetEventCallback(*client_handle, event_callback),
309 osi_free(uih_pn_channel_3);
312 void TestConnectClientPortL2cap(uint16_t acl_handle, uint16_t lcid) {
314 // Send configuration request when L2CAP connect is succsseful
315 tL2CAP_CFG_INFO cfg_req = {.mtu_present = true, .mtu = L2CAP_MTU_SIZE};
316 EXPECT_CALL(l2cap_interface_,
317 ConfigRequest(lcid, PointerMemoryEqual(&cfg_req)))
318 .WillOnce(Return(true));
319 l2cap_appl_info_.pL2CA_ConnectCfm_Cb(lcid, L2CAP_CONN_OK);
322 // Remote device confirms our configuration request
323 cfg_req.mtu_present = false;
324 l2cap_appl_info_.pL2CA_ConfigCfm_Cb(lcid, &cfg_req);
327 // Remote device also asks to configure MTU
328 // Once configuration is done, we connect to multiplexer control channel 0
329 EXPECT_CALL(l2cap_interface_,
330 ConfigResponse(lcid, PointerMemoryEqual(&cfg_req)))
331 .WillOnce(Return(true));
332 // multiplexer control channel's DLCI is always 0
333 BT_HDR* sabm_channel_0 = AllocateWrappedOutgoingL2capAclPacket(
334 CreateQuickSabmPacket(RFCOMM_MX_DLCI, lcid, acl_handle));
335 EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(sabm_channel_0)))
336 .WillOnce(Return(L2CAP_DW_SUCCESS));
337 l2cap_appl_info_.pL2CA_ConfigInd_Cb(lcid, &cfg_req);
338 osi_free(sabm_channel_0);
341 void ConnectClientPort(const RawAddress& peer_addr, uint16_t port_handle,
342 uint8_t scn, uint16_t mtu, uint16_t acl_handle,
343 uint16_t lcid, int port_callback_index,
344 bool is_first_connection) {
346 if (is_first_connection) {
347 VLOG(1) << "Step 1.5";
348 // Once remote accept multiplexer control channel 0
349 // We change to desired channel on non-initiating device (remote device)
350 BT_HDR* ua_channel_0 = AllocateWrappedIncomingL2capAclPacket(
351 CreateQuickUaPacket(RFCOMM_MX_DLCI, lcid, acl_handle));
352 BT_HDR* uih_pn_channel_3 =
353 AllocateWrappedOutgoingL2capAclPacket(CreateQuickPnPacket(
354 true, GetDlci(false, scn), true, mtu,
355 RFCOMM_PN_CONV_LAYER_CBFC_I >> 4, RFCOMM_PN_PRIORITY_0,
356 RFCOMM_K_MAX, lcid, acl_handle));
357 EXPECT_CALL(l2cap_interface_,
358 DataWrite(lcid, BtHdrEqual(uih_pn_channel_3)))
359 .WillOnce(Return(L2CAP_DW_SUCCESS));
360 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, ua_channel_0);
361 osi_free(uih_pn_channel_3);
365 // Once remote accept service channel change, we start security procedure
366 BT_HDR* uih_pn_channel_3_accept =
367 AllocateWrappedIncomingL2capAclPacket(CreateQuickPnPacket(
368 false, GetDlci(false, scn), false, mtu,
369 RFCOMM_PN_CONV_LAYER_CBFC_I >> 4, RFCOMM_PN_PRIORITY_0,
370 RFCOMM_K_MAX, lcid, acl_handle));
371 tBTM_SEC_CALLBACK* security_callback = nullptr;
372 void* p_port = nullptr;
373 EXPECT_CALL(btm_security_internal_interface_,
374 MultiplexingProtocolAccessRequest(peer_addr, BT_PSM_RFCOMM,
375 true, BTM_SEC_PROTO_RFCOMM,
376 scn, NotNull(), NotNull()))
377 .WillOnce(DoAll(SaveArg<5>(&security_callback), SaveArg<6>(&p_port),
378 Return(BTM_SUCCESS)));
379 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_pn_channel_3_accept);
382 // Once security procedure is done, we officially connect to target scn
383 BT_HDR* sabm_channel_3 = AllocateWrappedOutgoingL2capAclPacket(
384 CreateQuickSabmPacket(GetDlci(false, scn), lcid, acl_handle));
385 EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(sabm_channel_3)))
386 .WillOnce(Return(L2CAP_DW_SUCCESS));
387 ASSERT_TRUE(security_callback);
388 security_callback(&peer_addr, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS);
389 osi_free(sabm_channel_3);
392 // When target scn is accepted by remote, we need to configure modem signal
393 // state beofre using the port
396 PortManagementCallback(PORT_SUCCESS, port_handle, port_callback_index));
397 BT_HDR* uih_msc_cmd = AllocateWrappedOutgoingL2capAclPacket(
398 CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, true,
399 false, true, true, false, true));
400 EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_msc_cmd)))
401 .WillOnce(Return(L2CAP_DW_SUCCESS));
402 BT_HDR* ua_channel_3 = AllocateWrappedIncomingL2capAclPacket(
403 CreateQuickUaPacket(GetDlci(false, scn), lcid, acl_handle));
404 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, ua_channel_3);
405 osi_free(uih_msc_cmd);
408 // modem configuration is done
409 BT_HDR* uih_msc_response = AllocateWrappedIncomingL2capAclPacket(
410 CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle,
411 false, false, true, true, false, true));
412 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_response);
415 // Remote also need to configure its modem signal before we can send data
416 BT_HDR* uih_msc_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket(
417 CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle, true,
418 false, true, true, false, true));
419 BT_HDR* uih_msc_response_to_peer = AllocateWrappedOutgoingL2capAclPacket(
420 CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, false,
421 false, true, true, false, true));
422 EXPECT_CALL(l2cap_interface_,
423 DataWrite(lcid, BtHdrEqual(uih_msc_response_to_peer)))
424 .WillOnce(Return(L2CAP_DW_SUCCESS));
425 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_cmd_from_peer);
426 osi_free(uih_msc_response_to_peer);
429 void SendAndVerifyOutgoingTransmission(uint16_t port_handle,
430 bool is_initiator, uint8_t scn,
431 bool cr, const std::string& message,
432 int credits, uint16_t acl_handle,
435 BT_HDR* data_packet = AllocateWrappedOutgoingL2capAclPacket(
436 CreateQuickDataPacket(GetDlci(is_initiator, scn), cr, lcid, acl_handle,
438 uint16_t transmitted_length = 0;
439 EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(data_packet)))
440 .WillOnce(Return(L2CAP_DW_SUCCESS));
441 ASSERT_EQ(PORT_WriteData(port_handle, message.data(), message.size(),
442 &transmitted_length),
444 ASSERT_EQ(transmitted_length, message.size());
447 void ReceiveAndVerifyIncomingTransmission(uint16_t port_handle,
448 bool is_initiator, uint8_t scn,
449 bool cr, const std::string& message,
450 int credits, uint16_t acl_handle,
452 int port_callback_index) {
454 BT_HDR* data_packet = AllocateWrappedIncomingL2capAclPacket(
455 CreateQuickDataPacket(GetDlci(is_initiator, scn), cr, lcid, acl_handle,
457 EXPECT_CALL(rfcomm_callback_,
458 PortEventCallback(_, port_handle, port_callback_index));
459 l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, data_packet);
462 char buffer[L2CAP_MTU_SIZE] = {};
464 int status = PORT_ReadData(port_handle, buffer, L2CAP_MTU_SIZE, &length);
465 ASSERT_EQ(status, PORT_SUCCESS);
466 ASSERT_THAT(buffer, StrEq(message));
470 void SetUp() override {
472 bluetooth::manager::SetMockSecurityInternalInterface(
473 &btm_security_internal_interface_);
474 bluetooth::l2cap::SetMockInterface(&l2cap_interface_);
475 rfcomm_callback = &rfcomm_callback_;
476 EXPECT_CALL(l2cap_interface_, Register(BT_PSM_RFCOMM, _))
478 DoAll(SaveArgPointee<1>(&l2cap_appl_info_), Return(BT_PSM_RFCOMM)));
480 rfc_cb.trace_level = BT_TRACE_LEVEL_DEBUG;
483 void TearDown() override {
484 rfcomm_callback = nullptr;
485 bluetooth::l2cap::SetMockInterface(nullptr);
486 bluetooth::manager::SetMockSecurityInternalInterface(nullptr);
487 testing::Test::TearDown();
489 StrictMock<bluetooth::manager::MockBtmSecurityInternalInterface>
490 btm_security_internal_interface_;
491 StrictMock<bluetooth::l2cap::MockL2capInterface> l2cap_interface_;
492 StrictMock<bluetooth::rfcomm::MockRfcommCallback> rfcomm_callback_;
493 tL2CAP_APPL_INFO l2cap_appl_info_;
496 TEST_F(StackRfcommTest, SingleServerConnectionHelloWorld) {
497 // Prepare a server channel at kTestChannelNumber0
498 static const uint16_t acl_handle = 0x0009;
499 static const uint16_t lcid = 0x0054;
500 static const uint16_t test_uuid = 0x1112;
501 static const uint8_t test_scn = 8;
502 static const uint16_t test_mtu = 1600;
503 static const RawAddress test_address = GetTestAddress(0);
504 uint16_t server_handle = 0;
505 ASSERT_NO_FATAL_FAILURE(StartServerPort(test_uuid, test_scn, test_mtu,
506 port_mgmt_cback_0, port_event_cback_0,
508 ASSERT_NO_FATAL_FAILURE(ConnectServerL2cap(test_address, acl_handle, lcid));
509 ASSERT_NO_FATAL_FAILURE(ConnectServerPort(
510 test_address, server_handle, test_scn, test_mtu, acl_handle, lcid, 0));
511 ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
512 server_handle, false, test_scn, true, "Hello World!\r", 50, acl_handle,
514 ASSERT_NO_FATAL_FAILURE(
515 SendAndVerifyOutgoingTransmission(server_handle, false, test_scn, false,
516 "\r!dlroW olleH", 4, acl_handle, lcid));
519 TEST_F(StackRfcommTest, MultiServerPortSameDeviceHelloWorld) {
520 // Prepare a server channel at kTestChannelNumber0
521 static const uint16_t acl_handle = 0x0009;
522 static const uint16_t lcid = 0x0054;
523 static const uint16_t test_mtu = 1600;
524 static const RawAddress test_address = GetTestAddress(0);
527 uint16_t server_handle_0 = 0;
528 static const uint8_t test_scn_0 = 8;
529 static const uint16_t test_uuid_0 = 0x1112;
530 ASSERT_NO_FATAL_FAILURE(StartServerPort(test_uuid_0, test_scn_0, test_mtu,
531 port_mgmt_cback_0, port_event_cback_0,
533 ASSERT_NO_FATAL_FAILURE(ConnectServerL2cap(test_address, acl_handle, lcid));
534 ASSERT_NO_FATAL_FAILURE(ConnectServerPort(test_address, server_handle_0,
535 test_scn_0, test_mtu, acl_handle,
539 uint16_t server_handle_1 = 0;
540 static const uint8_t test_scn_1 = 10;
541 static const uint16_t test_uuid_1 = 0x111F;
542 ASSERT_NE(test_scn_1, test_scn_0);
543 ASSERT_NE(test_uuid_1, test_uuid_0);
544 ASSERT_NO_FATAL_FAILURE(StartServerPort(test_uuid_1, test_scn_1, test_mtu,
545 port_mgmt_cback_1, port_event_cback_1,
547 // No L2CAP setup for 2nd device
548 ASSERT_NO_FATAL_FAILURE(ConnectServerPort(test_address, server_handle_1,
549 test_scn_1, test_mtu, acl_handle,
553 ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
554 server_handle_0, false, test_scn_0, true, "Hello World0!\r", 50,
555 acl_handle, lcid, 0));
556 ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
557 server_handle_0, false, test_scn_0, false, "\r!0dlroW olleH", 4,
560 ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
561 server_handle_1, false, test_scn_1, true, "Hello World1!\r", 50,
562 acl_handle, lcid, 1));
563 ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
564 server_handle_1, false, test_scn_1, false, "\r!1dlroW olleH", 4,
568 TEST_F(StackRfcommTest, SameServerPortMultiDeviceHelloWorld) {
569 // Prepare a server channel at kTestChannelNumber0
570 static const uint16_t test_mtu = 1600;
571 static const uint8_t test_scn = 3;
572 static const uint16_t test_uuid = 0x1112;
575 static const RawAddress test_address_0 = GetTestAddress(0);
576 static const uint16_t acl_handle_0 = 0x0009;
577 static const uint16_t lcid_0 = 0x0054;
578 uint16_t server_handle_0 = 0;
579 ASSERT_NO_FATAL_FAILURE(StartServerPort(test_uuid, test_scn, test_mtu,
580 port_mgmt_cback_0, port_event_cback_0,
582 ASSERT_NO_FATAL_FAILURE(
583 ConnectServerL2cap(test_address_0, acl_handle_0, lcid_0));
584 ASSERT_NO_FATAL_FAILURE(ConnectServerPort(test_address_0, server_handle_0,
585 test_scn, test_mtu, acl_handle_0,
589 static const RawAddress test_address_1 = GetTestAddress(1);
590 static const uint16_t acl_handle_1 = 0x0012;
591 static const uint16_t lcid_1 = 0x0045;
592 uint16_t server_handle_1 = 0;
593 ASSERT_NO_FATAL_FAILURE(StartServerPort(test_uuid, test_scn, test_mtu,
594 port_mgmt_cback_1, port_event_cback_1,
596 ASSERT_NO_FATAL_FAILURE(
597 ConnectServerL2cap(test_address_1, acl_handle_1, lcid_1));
598 ASSERT_NO_FATAL_FAILURE(ConnectServerPort(test_address_1, server_handle_1,
599 test_scn, test_mtu, acl_handle_1,
603 ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
604 server_handle_0, false, test_scn, true, "Hello World0!\r", 50,
605 acl_handle_0, lcid_0, 0));
606 ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
607 server_handle_0, false, test_scn, false, "\r!0dlroW olleH", 4,
608 acl_handle_0, lcid_0));
610 ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
611 server_handle_1, false, test_scn, true, "Hello World1!\r", 50,
612 acl_handle_1, lcid_1, 1));
613 ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
614 server_handle_1, false, test_scn, false, "\r!1dlroW olleH", 4,
615 acl_handle_1, lcid_1));
618 TEST_F(StackRfcommTest, SingleClientConnectionHelloWorld) {
619 static const uint16_t acl_handle = 0x0009;
620 static const uint16_t lcid = 0x0054;
621 static const uint16_t test_uuid = 0x1112;
622 static const uint8_t test_scn = 8;
623 static const uint16_t test_mtu = 1600;
624 static const RawAddress test_address = GetTestAddress(0);
625 uint16_t client_handle = 0;
626 ASSERT_NO_FATAL_FAILURE(StartClientPort(
627 test_address, test_uuid, test_scn, test_mtu, port_mgmt_cback_0,
628 port_event_cback_0, lcid, acl_handle, &client_handle, true));
629 ASSERT_NO_FATAL_FAILURE(TestConnectClientPortL2cap(acl_handle, lcid));
630 ASSERT_NO_FATAL_FAILURE(ConnectClientPort(test_address, client_handle,
631 test_scn, test_mtu, acl_handle,
633 ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
634 client_handle, false, test_scn, true, "\r!dlroW olleH", -1, acl_handle,
636 ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
637 client_handle, false, test_scn, false, "Hello World!\r", -1, acl_handle,
641 TEST_F(StackRfcommTest, MultiClientPortSameDeviceHelloWorld) {
642 static const uint16_t acl_handle = 0x0009;
643 static const uint16_t lcid = 0x0054;
644 static const uint16_t test_mtu = 1600;
645 static const RawAddress test_address = GetTestAddress(0);
648 static const uint16_t test_uuid_0 = 0x1112;
649 static const uint8_t test_scn_0 = 8;
650 uint16_t client_handle_0 = 0;
651 ASSERT_NO_FATAL_FAILURE(StartClientPort(
652 test_address, test_uuid_0, test_scn_0, test_mtu, port_mgmt_cback_0,
653 port_event_cback_0, lcid, acl_handle, &client_handle_0, true));
654 ASSERT_NO_FATAL_FAILURE(TestConnectClientPortL2cap(acl_handle, lcid));
655 ASSERT_NO_FATAL_FAILURE(ConnectClientPort(test_address, client_handle_0,
656 test_scn_0, test_mtu, acl_handle,
660 static const uint16_t test_uuid_1 = 0x111F;
661 static const uint8_t test_scn_1 = 10;
662 uint16_t client_handle_1 = 0;
663 ASSERT_NO_FATAL_FAILURE(StartClientPort(
664 test_address, test_uuid_1, test_scn_1, test_mtu, port_mgmt_cback_1,
665 port_event_cback_1, lcid, acl_handle, &client_handle_1, false));
666 ASSERT_NO_FATAL_FAILURE(ConnectClientPort(test_address, client_handle_1,
667 test_scn_1, test_mtu, acl_handle,
671 ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
672 client_handle_0, false, test_scn_0, true, "\r!dlroW olleH", -1,
674 ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
675 client_handle_0, false, test_scn_0, false, "Hello World!\r", -1,
676 acl_handle, lcid, 0));
679 ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
680 client_handle_1, false, test_scn_1, true, "\r!dlroW olleH", -1,
682 ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
683 client_handle_1, false, test_scn_1, false, "Hello World!\r", -1,
684 acl_handle, lcid, 1));
687 TEST_F(StackRfcommTest, SameClientPortMultiDeviceHelloWorld) {
688 static const uint16_t test_uuid = 0x1112;
689 static const uint8_t test_scn = 8;
690 static const uint16_t test_mtu = 1600;
693 static const RawAddress test_address_0 = GetTestAddress(0);
694 static const uint16_t acl_handle_0 = 0x0009;
695 static const uint16_t lcid_0 = 0x0054;
696 uint16_t client_handle_0 = 0;
697 ASSERT_NO_FATAL_FAILURE(StartClientPort(
698 test_address_0, test_uuid, test_scn, test_mtu, port_mgmt_cback_0,
699 port_event_cback_0, lcid_0, acl_handle_0, &client_handle_0, true));
700 ASSERT_NO_FATAL_FAILURE(TestConnectClientPortL2cap(acl_handle_0, lcid_0));
701 ASSERT_NO_FATAL_FAILURE(ConnectClientPort(test_address_0, client_handle_0,
702 test_scn, test_mtu, acl_handle_0,
706 static const RawAddress test_address_1 = GetTestAddress(1);
707 static const uint16_t acl_handle_1 = 0x0012;
708 static const uint16_t lcid_1 = 0x0045;
709 uint16_t client_handle_1 = 0;
710 ASSERT_NO_FATAL_FAILURE(StartClientPort(
711 test_address_1, test_uuid, test_scn, test_mtu, port_mgmt_cback_1,
712 port_event_cback_1, lcid_1, acl_handle_1, &client_handle_1, true));
713 ASSERT_NO_FATAL_FAILURE(TestConnectClientPortL2cap(acl_handle_1, lcid_1));
714 ASSERT_NO_FATAL_FAILURE(ConnectClientPort(test_address_1, client_handle_1,
715 test_scn, test_mtu, acl_handle_1,
719 ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
720 client_handle_0, false, test_scn, true, "\r!dlroW olleH", -1,
721 acl_handle_0, lcid_0));
722 ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
723 client_handle_0, false, test_scn, false, "Hello World!\r", -1,
724 acl_handle_0, lcid_0, 0));
727 ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
728 client_handle_1, false, test_scn, true, "\r!dlroW olleH", -1,
729 acl_handle_1, lcid_1));
730 ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
731 client_handle_1, false, test_scn, false, "Hello World!\r", -1,
732 acl_handle_1, lcid_1, 1));
735 TEST_F(StackRfcommTest, TestConnectionCollision) {
736 static const uint16_t acl_handle = 0x0008;
737 static const uint16_t old_lcid = 0x004a;
738 static const uint16_t new_lcid = 0x005c;
739 static const uint16_t test_uuid = 0x1112;
740 static const uint8_t test_server_scn = 3;
741 static const uint8_t test_peer_scn = 10;
742 // Must be smaller than L2CAP_MTU_SIZE by at least 4 bytes
743 static const uint16_t test_mtu = 1000;
744 static const RawAddress test_address = GetTestAddress(0);
745 uint16_t server_handle = 0;
747 // Prepare a server port
748 int status = RFCOMM_CreateConnection(test_uuid, test_server_scn, true,
749 test_mtu, RawAddress::kAny,
750 &server_handle, port_mgmt_cback_0);
751 ASSERT_EQ(status, PORT_SUCCESS);
752 status = PORT_SetEventMask(server_handle, PORT_EV_RXCHAR);
753 ASSERT_EQ(status, PORT_SUCCESS);
754 status = PORT_SetEventCallback(server_handle, port_event_cback_0);
755 ASSERT_EQ(status, PORT_SUCCESS);
758 // Try to connect to a client port
759 uint16_t client_handle_1 = 0;
760 EXPECT_CALL(l2cap_interface_, ConnectRequest(BT_PSM_RFCOMM, test_address))
762 .WillOnce(Return(old_lcid));
763 status = RFCOMM_CreateConnection(test_uuid, test_peer_scn, false, test_mtu,
764 test_address, &client_handle_1,
766 ASSERT_EQ(status, PORT_SUCCESS);
767 status = PORT_SetEventMask(client_handle_1, PORT_EV_RXCHAR);
768 ASSERT_EQ(status, PORT_SUCCESS);
769 status = PORT_SetEventCallback(client_handle_1, port_event_cback_1);
770 ASSERT_EQ(status, PORT_SUCCESS);
773 // While our connection is pending, remote device tries to connect to
774 // new_lcid, with L2CAP command id: pending_cmd_id
775 static const uint8_t pending_cmd_id = 0x05;
776 // RFCOMM starts timer for collision:
777 l2cap_appl_info_.pL2CA_ConnectInd_Cb(test_address, new_lcid, BT_PSM_RFCOMM,
781 // Remote reject our connection request saying PSM not allowed
782 // This should trigger RFCOMM to accept remote L2CAP connection at new_lcid
783 EXPECT_CALL(l2cap_interface_, ConnectResponse(test_address, pending_cmd_id,
784 new_lcid, L2CAP_CONN_OK, 0))
785 .WillOnce(Return(true));
786 // Followed by configure request for MTU size
787 tL2CAP_CFG_INFO our_cfg_req = {.mtu_present = true, .mtu = L2CAP_MTU_SIZE};
788 EXPECT_CALL(l2cap_interface_,
789 ConfigRequest(new_lcid, PointerMemoryEqual(&our_cfg_req)))
790 .WillOnce(Return(true));
791 l2cap_appl_info_.pL2CA_ConnectCfm_Cb(old_lcid, L2CAP_CONN_NO_PSM);
794 // Remote device also ask to configure MTU size as well
795 tL2CAP_CFG_INFO peer_cfg_req = {.mtu_present = true, .mtu = test_mtu};
796 // We responded by saying OK
797 tL2CAP_CFG_INFO our_cfg_rsp = {.result = L2CAP_CFG_OK,
798 .mtu = peer_cfg_req.mtu};
799 EXPECT_CALL(l2cap_interface_,
800 ConfigResponse(new_lcid, PointerMemoryEqual(&our_cfg_rsp)))
801 .WillOnce(Return(true));
802 l2cap_appl_info_.pL2CA_ConfigInd_Cb(new_lcid, &peer_cfg_req);
805 // Remote device accepted our MTU size
806 tL2CAP_CFG_INFO peer_cfg_rsp = {.mtu_present = true, .mtu = L2CAP_MTU_SIZE};
807 l2cap_appl_info_.pL2CA_ConfigCfm_Cb(new_lcid, &peer_cfg_rsp);
809 // L2CAP collision and connection setup done
812 // Remote device connect multiplexer channel
813 BT_HDR* sabm_channel_0 = AllocateWrappedIncomingL2capAclPacket(
814 CreateQuickSabmPacket(RFCOMM_MX_DLCI, new_lcid, acl_handle));
816 BT_HDR* ua_channel_0 = AllocateWrappedOutgoingL2capAclPacket(
817 CreateQuickUaPacket(RFCOMM_MX_DLCI, new_lcid, acl_handle));
818 EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(ua_channel_0)))
819 .WillOnce(Return(L2CAP_DW_SUCCESS));
820 // And immediately try to configure test_peer_scn
821 BT_HDR* uih_pn_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket(
822 CreateQuickPnPacket(false, GetDlci(true, test_peer_scn), true, test_mtu,
823 RFCOMM_PN_CONV_LAYER_CBFC_I >> 4, 0, RFCOMM_K_MAX,
824 new_lcid, acl_handle));
825 EXPECT_CALL(l2cap_interface_,
826 DataWrite(new_lcid, BtHdrEqual(uih_pn_cmd_to_peer)))
827 .WillOnce(Return(L2CAP_DW_SUCCESS));
828 // Packet should be freed by this method
829 l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, sabm_channel_0);
830 osi_free(ua_channel_0);
831 osi_free(uih_pn_cmd_to_peer);
834 // Peer tries to configure test_server_scn
835 BT_HDR* uih_pn_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket(
836 CreateQuickPnPacket(true, GetDlci(false, test_server_scn), true, test_mtu,
837 RFCOMM_PN_CONV_LAYER_CBFC_I >> 4, 0, RFCOMM_K_MAX,
838 new_lcid, acl_handle));
839 // We, as acceptor, must accept
840 BT_HDR* uih_pn_rsp_to_peer = AllocateWrappedOutgoingL2capAclPacket(
841 CreateQuickPnPacket(false, GetDlci(false, test_server_scn), false,
842 test_mtu, RFCOMM_PN_CONV_LAYER_CBFC_R >> 4, 0,
843 RFCOMM_K_MAX, new_lcid, acl_handle));
844 EXPECT_CALL(l2cap_interface_,
845 DataWrite(new_lcid, BtHdrEqual(uih_pn_rsp_to_peer)))
847 .WillOnce(Return(L2CAP_DW_SUCCESS));
848 l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_pn_cmd_from_peer);
849 osi_free(uih_pn_rsp_to_peer);
852 // Remote never replies our configuration request for test_peer_scn
853 // But instead connect to test_server_scn directly
854 BT_HDR* sabm_server_scn =
855 AllocateWrappedIncomingL2capAclPacket(CreateQuickSabmPacket(
856 GetDlci(false, test_server_scn), new_lcid, acl_handle));
857 // We must do security check first
858 tBTM_SEC_CALLBACK* security_callback = nullptr;
859 void* p_port = nullptr;
860 EXPECT_CALL(btm_security_internal_interface_,
861 MultiplexingProtocolAccessRequest(
862 test_address, BT_PSM_RFCOMM, false, BTM_SEC_PROTO_RFCOMM,
863 test_server_scn, NotNull(), NotNull()))
864 .WillOnce(DoAll(SaveArg<5>(&security_callback), SaveArg<6>(&p_port),
865 Return(BTM_SUCCESS)));
866 l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, sabm_server_scn);
868 VLOG(1) << "Step 10";
869 // After security check, we accept the connection
870 ASSERT_TRUE(security_callback);
871 BT_HDR* ua_server_scn =
872 AllocateWrappedOutgoingL2capAclPacket(CreateQuickUaPacket(
873 GetDlci(false, test_server_scn), new_lcid, acl_handle));
874 EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(ua_server_scn)))
875 .WillOnce(Return(L2CAP_DW_SUCCESS));
876 // Callback should come from server port instead, client port will timeout
878 EXPECT_CALL(rfcomm_callback_,
879 PortManagementCallback(PORT_SUCCESS, server_handle, 0));
880 security_callback(&test_address, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS);
881 osi_free(ua_server_scn);
883 VLOG(1) << "Step 11";
884 // MPX_CTRL Modem Status Command (MSC)
885 BT_HDR* uih_msc_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket(
886 CreateQuickMscPacket(true, GetDlci(false, test_server_scn), new_lcid,
887 acl_handle, true, false, true, true, false, true));
888 BT_HDR* uih_msc_rsp_to_peer = AllocateWrappedOutgoingL2capAclPacket(
889 CreateQuickMscPacket(false, GetDlci(false, test_server_scn), new_lcid,
890 acl_handle, false, false, true, true, false, true));
891 // MPX_CTRL Modem Status Response (MSC)
892 EXPECT_CALL(l2cap_interface_,
893 DataWrite(new_lcid, BtHdrEqual(uih_msc_rsp_to_peer)))
894 .WillOnce(Return(L2CAP_DW_SUCCESS));
895 BT_HDR* uih_msc_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket(
896 CreateQuickMscPacket(false, GetDlci(false, test_server_scn), new_lcid,
897 acl_handle, true, false, true, true, false, true));
898 EXPECT_CALL(l2cap_interface_,
899 DataWrite(new_lcid, BtHdrEqual(uih_msc_cmd_to_peer)))
900 .WillOnce(Return(L2CAP_DW_SUCCESS));
901 l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_msc_cmd_from_peer);
902 osi_free(uih_msc_rsp_to_peer);
903 osi_free(uih_msc_cmd_to_peer);
905 VLOG(1) << "Step 12";
906 BT_HDR* uih_msc_rsp_from_peer = AllocateWrappedIncomingL2capAclPacket(
907 CreateQuickMscPacket(true, GetDlci(false, test_server_scn), new_lcid,
908 acl_handle, false, false, true, true, false, true));
909 l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_msc_rsp_from_peer);