1272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He/******************************************************************************
2272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *
3272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *  Copyright 2018 The Android Open Source Project
4272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *
5272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *  Licensed under the Apache License, Version 2.0 (the "License");
6272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *  you may not use this file except in compliance with the License.
7272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *  You may obtain a copy of the License at:
8272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *
9272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *  http://www.apache.org/licenses/LICENSE-2.0
10272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *
11272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *  Unless required by applicable law or agreed to in writing, software
12272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *  distributed under the License is distributed on an "AS IS" BASIS,
13272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *  See the License for the specific language governing permissions and
15272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *  limitations under the License.
16272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He *
17272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He ******************************************************************************/
18272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
19272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include <base/logging.h>
20272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include <gmock/gmock.h>
21272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include <gtest/gtest.h>
22272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
23272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "bt_types.h"
24272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "btm_api.h"
25272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "l2c_api.h"
26272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "osi/include/osi.h"
27272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "port_api.h"
28272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
29272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "btm_int.h"
30272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "rfc_int.h"
31272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
32272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "mock_btm_layer.h"
33272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "mock_l2cap_layer.h"
34272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "stack_rfcomm_test_utils.h"
35272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He#include "stack_test_packet_utils.h"
36272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
37272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Hestd::string DumpByteBufferToString(uint8_t* p_data, size_t len) {
38272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  std::stringstream str;
39272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  str.setf(std::ios_base::hex, std::ios::basefield);
40272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  str.setf(std::ios_base::uppercase);
41272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  str.fill('0');
42272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  for (size_t i = 0; i < len; ++i) {
43272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    str << std::setw(2) << static_cast<uint16_t>(p_data[i]);
44272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    str << " ";
45272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
46272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  return str.str();
47272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
48272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
49272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Hestd::string DumpBtHdrToString(BT_HDR* p_hdr) {
50272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint8_t* p_hdr_data = p_hdr->data + p_hdr->offset;
51272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  return DumpByteBufferToString(p_hdr_data, p_hdr->len);
52272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
53272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
54272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Hevoid PrintTo(BT_HDR* value, ::std::ostream* os) {
55272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  *os << DumpBtHdrToString(value);
56272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
57272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
58272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Hevoid PrintTo(tL2CAP_CFG_INFO* value, ::std::ostream* os) {
59272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  *os << DumpByteBufferToString((uint8_t*)value, sizeof(tL2CAP_CFG_INFO));
60272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
61272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
62272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Henamespace {
63272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
64272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing testing::_;
65272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing testing::DoAll;
66272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing testing::Return;
67272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing testing::Test;
68272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing testing::StrictMock;
69272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing testing::SaveArg;
70272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing testing::SaveArgPointee;
71272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing testing::Pointee;
72272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing testing::StrEq;
73272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing testing::NotNull;
74272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
75272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::CreateL2capDataPacket;
76272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::CreateAclPacket;
77272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::AllocateWrappedIncomingL2capAclPacket;
78272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::AllocateWrappedOutgoingL2capAclPacket;
79272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
80272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::GetDlci;
81272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::GetAddressField;
82272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::GetControlField;
83272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::CreateMccPnFrame;
84272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::CreateMccMscFrame;
85272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::CreateMultiplexerControlFrame;
86272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::CreateRfcommPacket;
87272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::CreateQuickDataPacket;
88272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::CreateQuickPnPacket;
89272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::CreateQuickSabmPacket;
90272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::CreateQuickUaPacket;
91272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heusing bluetooth::rfcomm::CreateQuickMscPacket;
92272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
93272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack HeMATCHER_P(PointerMemoryEqual, ptr,
94272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He          DumpByteBufferToString((uint8_t*)ptr, sizeof(*ptr))) {
95272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  return memcmp(arg, ptr, sizeof(*ptr)) == 0;
96272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
97272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
98272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack HeMATCHER_P(BtHdrEqual, expected, DumpBtHdrToString(expected)) {
99272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  auto arg_hdr = static_cast<BT_HDR*>(arg);
100272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint8_t* arg_data = arg_hdr->data + arg_hdr->offset;
101272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  auto expected_hdr = static_cast<BT_HDR*>(expected);
102272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint8_t* expected_data = expected_hdr->data + expected_hdr->offset;
103272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  return memcmp(arg_data, expected_data, expected_hdr->len) == 0;
104272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
105272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
106272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Hebluetooth::rfcomm::MockRfcommCallback* rfcomm_callback = nullptr;
107272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
108272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Hevoid port_mgmt_cback_0(uint32_t code, uint16_t port_handle) {
109272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  rfcomm_callback->PortManagementCallback(code, port_handle, 0);
110272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
111272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
112272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Hevoid port_mgmt_cback_1(uint32_t code, uint16_t port_handle) {
113272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  rfcomm_callback->PortManagementCallback(code, port_handle, 1);
114272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
115272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
116272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Hevoid port_event_cback_0(uint32_t code, uint16_t port_handle) {
117272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  rfcomm_callback->PortEventCallback(code, port_handle, 0);
118272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
119272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
120272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Hevoid port_event_cback_1(uint32_t code, uint16_t port_handle) {
121272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  rfcomm_callback->PortEventCallback(code, port_handle, 1);
122272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
123272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
124272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack HeRawAddress GetTestAddress(int index) {
125272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  CHECK_LT(index, UINT8_MAX);
126272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  RawAddress result = {
127272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      {0xAA, 0x00, 0x11, 0x22, 0x33, static_cast<uint8_t>(index)}};
128272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  return result;
129272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
130272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
131272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack Heclass StackRfcommTest : public Test {
132272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He public:
133272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  void StartServerPort(uint16_t uuid, uint8_t scn, uint16_t mtu,
134272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                       tPORT_CALLBACK* management_callback,
135272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                       tPORT_CALLBACK* event_callback,
136272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                       uint16_t* server_handle) {
137272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 1";
138272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_EQ(RFCOMM_CreateConnection(uuid, scn, true, mtu, RawAddress::kAny,
139272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                      server_handle, management_callback),
140272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He              PORT_SUCCESS);
141272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_EQ(PORT_SetEventMask(*server_handle, PORT_EV_RXCHAR), PORT_SUCCESS);
142272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_EQ(PORT_SetEventCallback(*server_handle, event_callback),
143272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He              PORT_SUCCESS);
144272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
145272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
146272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  void ConnectServerL2cap(const RawAddress& peer_addr, uint16_t acl_handle,
147272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                          uint16_t lcid) {
148272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 1";
149272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Remote device connect to this channel, we shall accept
150272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    static const uint8_t cmd_id = 0x07;
151272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_,
152272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                ConnectResponse(peer_addr, cmd_id, lcid, L2CAP_CONN_OK, 0));
153272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    tL2CAP_CFG_INFO cfg_req = {.mtu_present = true, .mtu = L2CAP_MTU_SIZE};
154272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_,
155272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                ConfigRequest(lcid, PointerMemoryEqual(&cfg_req)))
156272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(true));
157272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_ConnectInd_Cb(peer_addr, lcid, BT_PSM_RFCOMM,
158272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                         cmd_id);
159272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
160272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 2";
161272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // MTU configuration is done
162272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    cfg_req.mtu_present = false;
163272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_ConfigCfm_Cb(lcid, &cfg_req);
164272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
165272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 3";
166272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Remote device also ask to configure MTU size
167272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_,
168272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                ConfigResponse(lcid, PointerMemoryEqual(&cfg_req)))
169272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(true));
170272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_ConfigInd_Cb(lcid, &cfg_req);
171272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
172272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 4";
173272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Remote device connect to server channel 0
174272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* sabm_channel_0 = AllocateWrappedIncomingL2capAclPacket(
175272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickSabmPacket(RFCOMM_MX_DLCI, lcid, acl_handle));
176272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* ua_channel_0 = AllocateWrappedOutgoingL2capAclPacket(
177272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickUaPacket(RFCOMM_MX_DLCI, lcid, acl_handle));
178272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(ua_channel_0)))
179272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(L2CAP_DW_SUCCESS));
180272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Packet should be freed by RFCOMM
181272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, sabm_channel_0);
182272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    osi_free(ua_channel_0);
183272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
184272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
185272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  void ConnectServerPort(const RawAddress& peer_addr, uint16_t port_handle,
186272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                         uint8_t scn, uint16_t mtu, uint16_t acl_handle,
187272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                         uint16_t lcid, int port_callback_index) {
188272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 1";
189272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Negotiate parameters on scn
190272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_pn_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket(
191272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickPnPacket(true, GetDlci(false, scn), true, mtu,
192272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                            RFCOMM_PN_CONV_LAYER_CBFC_I >> 4, 0, RFCOMM_K_MAX,
193272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                            lcid, acl_handle));
194272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_pn_rsp_to_peer = AllocateWrappedOutgoingL2capAclPacket(
195272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickPnPacket(false, GetDlci(false, scn), false, mtu,
196272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                            RFCOMM_PN_CONV_LAYER_CBFC_R >> 4, 0, RFCOMM_K_MAX,
197272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                            lcid, acl_handle));
198272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_,
199272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                DataWrite(lcid, BtHdrEqual(uih_pn_rsp_to_peer)))
200272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(L2CAP_DW_SUCCESS));
201272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // uih_pn_cmd_from_peer should be freed by this method
202272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_pn_cmd_from_peer);
203272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    osi_free(uih_pn_rsp_to_peer);
204272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
205272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 2";
206272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Remote device connect to scn
207272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    tBTM_SEC_CALLBACK* security_callback = nullptr;
208272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    void* p_port = nullptr;
209272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* sabm_channel_dlci = AllocateWrappedIncomingL2capAclPacket(
210272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickSabmPacket(GetDlci(false, scn), lcid, acl_handle));
211272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(btm_security_internal_interface_,
212272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                MultiplexingProtocolAccessRequest(peer_addr, BT_PSM_RFCOMM,
213272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                                  false, BTM_SEC_PROTO_RFCOMM,
214272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                                  scn, NotNull(), NotNull()))
215272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(DoAll(SaveArg<5>(&security_callback), SaveArg<6>(&p_port),
216272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                        Return(BTM_SUCCESS)));
217272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // sabm_channel_dlci should be freed by this method
218272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, sabm_channel_dlci);
219272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
220272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 3";
221272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Confirm security check should trigger port as connected
222272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(
223272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        rfcomm_callback_,
224272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        PortManagementCallback(PORT_SUCCESS, port_handle, port_callback_index));
225272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* ua_channel_dlci = AllocateWrappedOutgoingL2capAclPacket(
226272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickUaPacket(GetDlci(false, scn), lcid, acl_handle));
227272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(ua_channel_dlci)))
228272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(L2CAP_DW_SUCCESS));
229272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_TRUE(security_callback);
230272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    security_callback(&peer_addr, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS);
231272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    osi_free(ua_channel_dlci);
232272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
233272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 4";
234272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Remote also need to configure its modem signal before we can send data
235272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_msc_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket(
236272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, true,
237272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                             false, true, true, false, true));
238272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_msc_response_to_peer = AllocateWrappedOutgoingL2capAclPacket(
239272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle,
240272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                             false, false, true, true, false, true));
241272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // We also have to do modem configuration ourself
242272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_,
243272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                DataWrite(lcid, BtHdrEqual(uih_msc_response_to_peer)))
244272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(L2CAP_DW_SUCCESS));
245272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_msc_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket(
246272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle, true,
247272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                             false, true, true, false, true));
248272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_,
249272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                DataWrite(lcid, BtHdrEqual(uih_msc_cmd_to_peer)))
250272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(L2CAP_DW_SUCCESS));
251272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // uih_msc_cmd_from_peer should be freed by this method
252272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_cmd_from_peer);
253272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    osi_free(uih_msc_response_to_peer);
254272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
255272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 5";
256272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // modem configuration is done
257272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_msc_response_from_peer = AllocateWrappedIncomingL2capAclPacket(
258272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, false,
259272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                             false, true, true, false, true));
260272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // uih_msc_response_from_peer should be freed by this method
261272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_response_from_peer);
262272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
263272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
264272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  void StartClientPort(const RawAddress& peer_bd_addr, uint16_t uuid,
265272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                       uint8_t scn, uint16_t mtu,
266272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                       tPORT_CALLBACK* management_callback,
267272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                       tPORT_CALLBACK* event_callback, uint16_t lcid,
268272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                       uint16_t acl_handle, uint16_t* client_handle,
269272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                       bool is_first_connection) {
270272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 1";
271272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_pn_channel_3 =
272272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        AllocateWrappedOutgoingL2capAclPacket(CreateQuickPnPacket(
273272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He            true, GetDlci(false, scn), true, mtu, RFCOMM_PN_CONV_LAYER_TYPE_1,
274272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He            RFCOMM_PN_PRIORITY_0, RFCOMM_K, lcid, acl_handle));
275272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    if (is_first_connection) {
276272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      EXPECT_CALL(l2cap_interface_, ConnectRequest(BT_PSM_RFCOMM, peer_bd_addr))
277272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He          .WillOnce(Return(lcid));
278272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    } else {
279272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      EXPECT_CALL(l2cap_interface_,
280272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                  DataWrite(lcid, BtHdrEqual(uih_pn_channel_3)))
281272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He          .WillOnce(Return(L2CAP_DW_SUCCESS));
282272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    }
283272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_EQ(RFCOMM_CreateConnection(uuid, scn, false, mtu, peer_bd_addr,
284272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                      client_handle, management_callback),
285272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He              PORT_SUCCESS);
286272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_EQ(PORT_SetEventMask(*client_handle, PORT_EV_RXCHAR), PORT_SUCCESS);
287272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_EQ(PORT_SetEventCallback(*client_handle, event_callback),
288272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He              PORT_SUCCESS);
289272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    osi_free(uih_pn_channel_3);
290272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
291272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
292272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  void TestConnectClientPortL2cap(uint16_t acl_handle, uint16_t lcid) {
293272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 1";
294272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Send configuration request when L2CAP connect is succsseful
295272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    tL2CAP_CFG_INFO cfg_req = {.mtu_present = true, .mtu = L2CAP_MTU_SIZE};
296272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_,
297272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                ConfigRequest(lcid, PointerMemoryEqual(&cfg_req)))
298272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(true));
299272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_ConnectCfm_Cb(lcid, L2CAP_CONN_OK);
300272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
301272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 2";
302272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Remote device confirms our configuration request
303272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    cfg_req.mtu_present = false;
304272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_ConfigCfm_Cb(lcid, &cfg_req);
305272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
306272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 3";
307272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Remote device also asks to configure MTU
308272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Once configuration is done, we connect to multiplexer control channel 0
309272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_,
310272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                ConfigResponse(lcid, PointerMemoryEqual(&cfg_req)))
311272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(true));
312272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // multiplexer control channel's DLCI is always 0
313272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* sabm_channel_0 = AllocateWrappedOutgoingL2capAclPacket(
314272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickSabmPacket(RFCOMM_MX_DLCI, lcid, acl_handle));
315272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(sabm_channel_0)))
316272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(L2CAP_DW_SUCCESS));
317272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_ConfigInd_Cb(lcid, &cfg_req);
318272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    osi_free(sabm_channel_0);
319272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
320272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
321272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  void ConnectClientPort(const RawAddress& peer_addr, uint16_t port_handle,
322272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                         uint8_t scn, uint16_t mtu, uint16_t acl_handle,
323272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                         uint16_t lcid, int port_callback_index,
324272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                         bool is_first_connection) {
325272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 1";
326272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    if (is_first_connection) {
327272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      VLOG(1) << "Step 1.5";
328272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      // Once remote accept multiplexer control channel 0
329272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      // We change to desired channel on non-initiating device (remote device)
330272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      BT_HDR* ua_channel_0 = AllocateWrappedIncomingL2capAclPacket(
331272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He          CreateQuickUaPacket(RFCOMM_MX_DLCI, lcid, acl_handle));
332272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      BT_HDR* uih_pn_channel_3 =
333272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He          AllocateWrappedOutgoingL2capAclPacket(CreateQuickPnPacket(
334272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He              true, GetDlci(false, scn), true, mtu,
335272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He              RFCOMM_PN_CONV_LAYER_CBFC_I >> 4, RFCOMM_PN_PRIORITY_0,
336272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He              RFCOMM_K_MAX, lcid, acl_handle));
337272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      EXPECT_CALL(l2cap_interface_,
338272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                  DataWrite(lcid, BtHdrEqual(uih_pn_channel_3)))
339272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He          .WillOnce(Return(L2CAP_DW_SUCCESS));
340272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, ua_channel_0);
341272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      osi_free(uih_pn_channel_3);
342272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    }
343272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
344272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 2";
345272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Once remote accept service channel change, we start security procedure
346272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_pn_channel_3_accept =
347272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        AllocateWrappedIncomingL2capAclPacket(CreateQuickPnPacket(
348272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He            false, GetDlci(false, scn), false, mtu,
349272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He            RFCOMM_PN_CONV_LAYER_CBFC_I >> 4, RFCOMM_PN_PRIORITY_0,
350272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He            RFCOMM_K_MAX, lcid, acl_handle));
351272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    tBTM_SEC_CALLBACK* security_callback = nullptr;
352272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    void* p_port = nullptr;
353272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(btm_security_internal_interface_,
354272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                MultiplexingProtocolAccessRequest(peer_addr, BT_PSM_RFCOMM,
355272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                                  true, BTM_SEC_PROTO_RFCOMM,
356272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                                  scn, NotNull(), NotNull()))
357272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(DoAll(SaveArg<5>(&security_callback), SaveArg<6>(&p_port),
358272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                        Return(BTM_SUCCESS)));
359272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_pn_channel_3_accept);
360272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
361272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 3";
362272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Once security procedure is done, we officially connect to target scn
363272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* sabm_channel_3 = AllocateWrappedOutgoingL2capAclPacket(
364272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickSabmPacket(GetDlci(false, scn), lcid, acl_handle));
365272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(sabm_channel_3)))
366272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(L2CAP_DW_SUCCESS));
367272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_TRUE(security_callback);
368272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    security_callback(&peer_addr, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS);
369272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    osi_free(sabm_channel_3);
370272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
371272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 4";
372272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // When target scn is accepted by remote, we need to configure modem signal
373272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // state beofre using the port
374272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(
375272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        rfcomm_callback_,
376272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        PortManagementCallback(PORT_SUCCESS, port_handle, port_callback_index));
377272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_msc_cmd = AllocateWrappedOutgoingL2capAclPacket(
378272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, true,
379272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                             false, true, true, false, true));
380272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(uih_msc_cmd)))
381272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(L2CAP_DW_SUCCESS));
382272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* ua_channel_3 = AllocateWrappedIncomingL2capAclPacket(
383272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickUaPacket(GetDlci(false, scn), lcid, acl_handle));
384272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, ua_channel_3);
385272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    osi_free(uih_msc_cmd);
386272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
387272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 5";
388272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // modem configuration is done
389272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_msc_response = AllocateWrappedIncomingL2capAclPacket(
390272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle,
391272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                             false, false, true, true, false, true));
392272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_response);
393272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
394272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 6";
395272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    // Remote also need to configure its modem signal before we can send data
396272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_msc_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket(
397272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickMscPacket(false, GetDlci(false, scn), lcid, acl_handle, true,
398272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                             false, true, true, false, true));
399272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* uih_msc_response_to_peer = AllocateWrappedOutgoingL2capAclPacket(
400272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickMscPacket(true, GetDlci(false, scn), lcid, acl_handle, false,
401272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                             false, true, true, false, true));
402272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_,
403272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                DataWrite(lcid, BtHdrEqual(uih_msc_response_to_peer)))
404272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(L2CAP_DW_SUCCESS));
405272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, uih_msc_cmd_from_peer);
406272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    osi_free(uih_msc_response_to_peer);
407272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
408272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
409272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  void SendAndVerifyOutgoingTransmission(uint16_t port_handle,
410272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                         bool is_initiator, uint8_t scn,
411272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                         bool cr, const std::string& message,
412272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                         int credits, uint16_t acl_handle,
413272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                         uint16_t lcid) {
414272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 1";
415272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* data_packet = AllocateWrappedOutgoingL2capAclPacket(
416272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickDataPacket(GetDlci(is_initiator, scn), cr, lcid, acl_handle,
417272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                              credits, message));
418272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    uint16_t transmitted_length = 0;
419272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_, DataWrite(lcid, BtHdrEqual(data_packet)))
420272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(Return(L2CAP_DW_SUCCESS));
421272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_EQ(PORT_WriteData(port_handle, message.data(), message.size(),
422272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                             &transmitted_length),
423272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He              PORT_SUCCESS);
424272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_EQ(transmitted_length, message.size());
425272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
426272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
427272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  void ReceiveAndVerifyIncomingTransmission(uint16_t port_handle,
428272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            bool is_initiator, uint8_t scn,
429272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            bool cr, const std::string& message,
430272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            int credits, uint16_t acl_handle,
431272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            uint16_t lcid,
432272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            int port_callback_index) {
433272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 1";
434272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    BT_HDR* data_packet = AllocateWrappedIncomingL2capAclPacket(
435272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        CreateQuickDataPacket(GetDlci(is_initiator, scn), cr, lcid, acl_handle,
436272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                              credits, message));
437272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(rfcomm_callback_,
438272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                PortEventCallback(_, port_handle, port_callback_index));
439272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    l2cap_appl_info_.pL2CA_DataInd_Cb(lcid, data_packet);
440272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
441272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    VLOG(1) << "Step 2";
442272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    char buffer[L2CAP_MTU_SIZE] = {};
443272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    uint16_t length = 0;
444272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    int status = PORT_ReadData(port_handle, buffer, L2CAP_MTU_SIZE, &length);
445272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_EQ(status, PORT_SUCCESS);
446272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    ASSERT_THAT(buffer, StrEq(message));
447272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
448272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
449272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He protected:
450272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  void SetUp() override {
451272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    Test::SetUp();
452272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    bluetooth::manager::SetMockSecurityInternalInterface(
453272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        &btm_security_internal_interface_);
454272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    bluetooth::l2cap::SetMockInterface(&l2cap_interface_);
455272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    rfcomm_callback = &rfcomm_callback_;
456272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    EXPECT_CALL(l2cap_interface_, Register(BT_PSM_RFCOMM, _))
457272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He        .WillOnce(
458272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He            DoAll(SaveArgPointee<1>(&l2cap_appl_info_), Return(BT_PSM_RFCOMM)));
459272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    RFCOMM_Init();
460272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    rfc_cb.trace_level = BT_TRACE_LEVEL_DEBUG;
461272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
462272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
463272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  void TearDown() override {
464272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    rfcomm_callback = nullptr;
465272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    bluetooth::l2cap::SetMockInterface(nullptr);
466272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    bluetooth::manager::SetMockSecurityInternalInterface(nullptr);
467272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He    testing::Test::TearDown();
468272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  }
469272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  StrictMock<bluetooth::manager::MockBtmSecurityInternalInterface>
470272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      btm_security_internal_interface_;
471272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  StrictMock<bluetooth::l2cap::MockL2capInterface> l2cap_interface_;
472272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  StrictMock<bluetooth::rfcomm::MockRfcommCallback> rfcomm_callback_;
473272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  tL2CAP_APPL_INFO l2cap_appl_info_;
474272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He};
475272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
476272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack HeTEST_F(StackRfcommTest, SingleServerConnectionHelloWorld) {
477272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Prepare a server channel at kTestChannelNumber0
478272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t acl_handle = 0x0009;
479272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t lcid = 0x0054;
480272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_uuid = 0x1112;
481272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint8_t test_scn = 8;
482272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_mtu = 1600;
483272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const RawAddress test_address = GetTestAddress(0);
484272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint16_t server_handle = 0;
485272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(StartServerPort(test_uuid, test_scn, test_mtu,
486272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                          port_mgmt_cback_0, port_event_cback_0,
487272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                          &server_handle));
488272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectServerL2cap(test_address, acl_handle, lcid));
489272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectServerPort(
490272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      test_address, server_handle, test_scn, test_mtu, acl_handle, lcid, 0));
491272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
492272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      server_handle, false, test_scn, true, "Hello World!\r", 50, acl_handle,
493272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      lcid, 0));
494272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(
495272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      SendAndVerifyOutgoingTransmission(server_handle, false, test_scn, false,
496272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                        "\r!dlroW olleH", 4, acl_handle, lcid));
497272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
498272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
499272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack HeTEST_F(StackRfcommTest, MultiServerPortSameDeviceHelloWorld) {
500272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Prepare a server channel at kTestChannelNumber0
501272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t acl_handle = 0x0009;
502272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t lcid = 0x0054;
503272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_mtu = 1600;
504272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const RawAddress test_address = GetTestAddress(0);
505272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
506272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Service 0
507272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint16_t server_handle_0 = 0;
508272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint8_t test_scn_0 = 8;
509272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_uuid_0 = 0x1112;
510272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(StartServerPort(test_uuid_0, test_scn_0, test_mtu,
511272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                          port_mgmt_cback_0, port_event_cback_0,
512272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                          &server_handle_0));
513272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectServerL2cap(test_address, acl_handle, lcid));
514272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectServerPort(test_address, server_handle_0,
515272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            test_scn_0, test_mtu, acl_handle,
516272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            lcid, 0));
517272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
518272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Service 1
519272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint16_t server_handle_1 = 0;
520272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint8_t test_scn_1 = 10;
521272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_uuid_1 = 0x111F;
522272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NE(test_scn_1, test_scn_0);
523272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NE(test_uuid_1, test_uuid_0);
524272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(StartServerPort(test_uuid_1, test_scn_1, test_mtu,
525272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                          port_mgmt_cback_1, port_event_cback_1,
526272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                          &server_handle_1));
527272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // No L2CAP setup for 2nd device
528272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectServerPort(test_address, server_handle_1,
529272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            test_scn_1, test_mtu, acl_handle,
530272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            lcid, 1));
531272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
532272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Use service 0
533272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
534272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      server_handle_0, false, test_scn_0, true, "Hello World0!\r", 50,
535272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle, lcid, 0));
536272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
537272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      server_handle_0, false, test_scn_0, false, "\r!0dlroW olleH", 4,
538272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle, lcid));
539272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Use service 1
540272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
541272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      server_handle_1, false, test_scn_1, true, "Hello World1!\r", 50,
542272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle, lcid, 1));
543272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
544272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      server_handle_1, false, test_scn_1, false, "\r!1dlroW olleH", 4,
545272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle, lcid));
546272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
547272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
548272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack HeTEST_F(StackRfcommTest, SameServerPortMultiDeviceHelloWorld) {
549272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Prepare a server channel at kTestChannelNumber0
550272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_mtu = 1600;
551272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint8_t test_scn = 3;
552272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_uuid = 0x1112;
553272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
554272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Service 0
555272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const RawAddress test_address_0 = GetTestAddress(0);
556272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t acl_handle_0 = 0x0009;
557272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t lcid_0 = 0x0054;
558272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint16_t server_handle_0 = 0;
559272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(StartServerPort(test_uuid, test_scn, test_mtu,
560272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                          port_mgmt_cback_0, port_event_cback_0,
561272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                          &server_handle_0));
562272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(
563272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      ConnectServerL2cap(test_address_0, acl_handle_0, lcid_0));
564272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectServerPort(test_address_0, server_handle_0,
565272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            test_scn, test_mtu, acl_handle_0,
566272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            lcid_0, 0));
567272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
568272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Service 1
569272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const RawAddress test_address_1 = GetTestAddress(1);
570272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t acl_handle_1 = 0x0012;
571272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t lcid_1 = 0x0045;
572272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint16_t server_handle_1 = 0;
573272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(StartServerPort(test_uuid, test_scn, test_mtu,
574272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                          port_mgmt_cback_1, port_event_cback_1,
575272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                          &server_handle_1));
576272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(
577272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      ConnectServerL2cap(test_address_1, acl_handle_1, lcid_1));
578272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectServerPort(test_address_1, server_handle_1,
579272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            test_scn, test_mtu, acl_handle_1,
580272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            lcid_1, 1));
581272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
582272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Use service 0
583272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
584272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      server_handle_0, false, test_scn, true, "Hello World0!\r", 50,
585272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle_0, lcid_0, 0));
586272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
587272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      server_handle_0, false, test_scn, false, "\r!0dlroW olleH", 4,
588272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle_0, lcid_0));
589272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Use service 1
590272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
591272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      server_handle_1, false, test_scn, true, "Hello World1!\r", 50,
592272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle_1, lcid_1, 1));
593272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
594272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      server_handle_1, false, test_scn, false, "\r!1dlroW olleH", 4,
595272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle_1, lcid_1));
596272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
597272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
598272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack HeTEST_F(StackRfcommTest, SingleClientConnectionHelloWorld) {
599272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t acl_handle = 0x0009;
600272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t lcid = 0x0054;
601272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_uuid = 0x1112;
602272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint8_t test_scn = 8;
603272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_mtu = 1600;
604272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const RawAddress test_address = GetTestAddress(0);
605272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint16_t client_handle = 0;
606272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(StartClientPort(
607272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      test_address, test_uuid, test_scn, test_mtu, port_mgmt_cback_0,
608272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      port_event_cback_0, lcid, acl_handle, &client_handle, true));
609272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(TestConnectClientPortL2cap(acl_handle, lcid));
610272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectClientPort(test_address, client_handle,
611272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            test_scn, test_mtu, acl_handle,
612272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            lcid, 0, true));
613272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
614272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      client_handle, false, test_scn, true, "\r!dlroW olleH", -1, acl_handle,
615272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      lcid));
616272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
617272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      client_handle, false, test_scn, false, "Hello World!\r", -1, acl_handle,
618272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      lcid, 0));
619272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
620272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
621272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack HeTEST_F(StackRfcommTest, MultiClientPortSameDeviceHelloWorld) {
622272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t acl_handle = 0x0009;
623272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t lcid = 0x0054;
624272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_mtu = 1600;
625272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const RawAddress test_address = GetTestAddress(0);
626272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
627272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Connection 0
628272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_uuid_0 = 0x1112;
629272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint8_t test_scn_0 = 8;
630272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint16_t client_handle_0 = 0;
631272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(StartClientPort(
632272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      test_address, test_uuid_0, test_scn_0, test_mtu, port_mgmt_cback_0,
633272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      port_event_cback_0, lcid, acl_handle, &client_handle_0, true));
634272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(TestConnectClientPortL2cap(acl_handle, lcid));
635272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectClientPort(test_address, client_handle_0,
636272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            test_scn_0, test_mtu, acl_handle,
637272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            lcid, 0, true));
638272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
639272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Connection 1
640272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_uuid_1 = 0x111F;
641272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint8_t test_scn_1 = 10;
642272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint16_t client_handle_1 = 0;
643272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(StartClientPort(
644272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      test_address, test_uuid_1, test_scn_1, test_mtu, port_mgmt_cback_1,
645272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      port_event_cback_1, lcid, acl_handle, &client_handle_1, false));
646272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectClientPort(test_address, client_handle_1,
647272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            test_scn_1, test_mtu, acl_handle,
648272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            lcid, 1, false));
649272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
650272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Use connection 0
651272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
652272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      client_handle_0, false, test_scn_0, true, "\r!dlroW olleH", -1,
653272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle, lcid));
654272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
655272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      client_handle_0, false, test_scn_0, false, "Hello World!\r", -1,
656272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle, lcid, 0));
657272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
658272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Use connection 1
659272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
660272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      client_handle_1, false, test_scn_1, true, "\r!dlroW olleH", -1,
661272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle, lcid));
662272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
663272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      client_handle_1, false, test_scn_1, false, "Hello World!\r", -1,
664272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle, lcid, 1));
665272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
666272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
667272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack HeTEST_F(StackRfcommTest, SameClientPortMultiDeviceHelloWorld) {
668272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_uuid = 0x1112;
669272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint8_t test_scn = 8;
670272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t test_mtu = 1600;
671272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
672272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Connection 0
673272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const RawAddress test_address_0 = GetTestAddress(0);
674272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t acl_handle_0 = 0x0009;
675272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t lcid_0 = 0x0054;
676272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint16_t client_handle_0 = 0;
677272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(StartClientPort(
678272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      test_address_0, test_uuid, test_scn, test_mtu, port_mgmt_cback_0,
679272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      port_event_cback_0, lcid_0, acl_handle_0, &client_handle_0, true));
680272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(TestConnectClientPortL2cap(acl_handle_0, lcid_0));
681272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectClientPort(test_address_0, client_handle_0,
682272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            test_scn, test_mtu, acl_handle_0,
683272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            lcid_0, 0, true));
684272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
685272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Connection 1
686272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const RawAddress test_address_1 = GetTestAddress(1);
687272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t acl_handle_1 = 0x0012;
688272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  static const uint16_t lcid_1 = 0x0045;
689272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  uint16_t client_handle_1 = 0;
690272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(StartClientPort(
691272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      test_address_1, test_uuid, test_scn, test_mtu, port_mgmt_cback_1,
692272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      port_event_cback_1, lcid_1, acl_handle_1, &client_handle_1, true));
693272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(TestConnectClientPortL2cap(acl_handle_1, lcid_1));
694272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ConnectClientPort(test_address_1, client_handle_1,
695272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            test_scn, test_mtu, acl_handle_1,
696272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He                                            lcid_1, 1, true));
697272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
698272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Use connection 0
699272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
700272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      client_handle_0, false, test_scn, true, "\r!dlroW olleH", -1,
701272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle_0, lcid_0));
702272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
703272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      client_handle_0, false, test_scn, false, "Hello World!\r", -1,
704272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle_0, lcid_0, 0));
705272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
706272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  // Use connection 1
707272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(SendAndVerifyOutgoingTransmission(
708272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      client_handle_1, false, test_scn, true, "\r!dlroW olleH", -1,
709272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle_1, lcid_1));
710272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He  ASSERT_NO_FATAL_FAILURE(ReceiveAndVerifyIncomingTransmission(
711272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      client_handle_1, false, test_scn, false, "Hello World!\r", -1,
712272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He      acl_handle_1, lcid_1, 1));
713272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}
714272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He
715b690c22637e522acdd8aebcd18699abc5dd0425cJack HeTEST_F(StackRfcommTest, TestConnectionCollision) {
716b690c22637e522acdd8aebcd18699abc5dd0425cJack He  static const uint16_t acl_handle = 0x0008;
717b690c22637e522acdd8aebcd18699abc5dd0425cJack He  static const uint16_t old_lcid = 0x004a;
718b690c22637e522acdd8aebcd18699abc5dd0425cJack He  static const uint16_t new_lcid = 0x005c;
719b690c22637e522acdd8aebcd18699abc5dd0425cJack He  static const uint16_t test_uuid = 0x1112;
720b690c22637e522acdd8aebcd18699abc5dd0425cJack He  static const uint8_t test_server_scn = 3;
721b690c22637e522acdd8aebcd18699abc5dd0425cJack He  static const uint8_t test_peer_scn = 10;
722b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Must be smaller than L2CAP_MTU_SIZE by at least 4 bytes
723b690c22637e522acdd8aebcd18699abc5dd0425cJack He  static const uint16_t test_mtu = 1000;
724b690c22637e522acdd8aebcd18699abc5dd0425cJack He  static const RawAddress test_address = GetTestAddress(0);
725b690c22637e522acdd8aebcd18699abc5dd0425cJack He  uint16_t server_handle = 0;
726b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 1";
727b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Prepare a server port
728b690c22637e522acdd8aebcd18699abc5dd0425cJack He  int status = RFCOMM_CreateConnection(test_uuid, test_server_scn, true,
729b690c22637e522acdd8aebcd18699abc5dd0425cJack He                                       test_mtu, RawAddress::kAny,
730b690c22637e522acdd8aebcd18699abc5dd0425cJack He                                       &server_handle, port_mgmt_cback_0);
731b690c22637e522acdd8aebcd18699abc5dd0425cJack He  ASSERT_EQ(status, PORT_SUCCESS);
732b690c22637e522acdd8aebcd18699abc5dd0425cJack He  status = PORT_SetEventMask(server_handle, PORT_EV_RXCHAR);
733b690c22637e522acdd8aebcd18699abc5dd0425cJack He  ASSERT_EQ(status, PORT_SUCCESS);
734b690c22637e522acdd8aebcd18699abc5dd0425cJack He  status = PORT_SetEventCallback(server_handle, port_event_cback_0);
735b690c22637e522acdd8aebcd18699abc5dd0425cJack He  ASSERT_EQ(status, PORT_SUCCESS);
736b690c22637e522acdd8aebcd18699abc5dd0425cJack He
737b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 2";
738b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Try to connect to a client port
739b690c22637e522acdd8aebcd18699abc5dd0425cJack He  uint16_t client_handle_1 = 0;
740b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(l2cap_interface_, ConnectRequest(BT_PSM_RFCOMM, test_address))
741b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .Times(1)
742b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(Return(old_lcid));
743b690c22637e522acdd8aebcd18699abc5dd0425cJack He  status = RFCOMM_CreateConnection(test_uuid, test_peer_scn, false, test_mtu,
744b690c22637e522acdd8aebcd18699abc5dd0425cJack He                                   test_address, &client_handle_1,
745b690c22637e522acdd8aebcd18699abc5dd0425cJack He                                   port_mgmt_cback_1);
746b690c22637e522acdd8aebcd18699abc5dd0425cJack He  ASSERT_EQ(status, PORT_SUCCESS);
747b690c22637e522acdd8aebcd18699abc5dd0425cJack He  status = PORT_SetEventMask(client_handle_1, PORT_EV_RXCHAR);
748b690c22637e522acdd8aebcd18699abc5dd0425cJack He  ASSERT_EQ(status, PORT_SUCCESS);
749b690c22637e522acdd8aebcd18699abc5dd0425cJack He  status = PORT_SetEventCallback(client_handle_1, port_event_cback_1);
750b690c22637e522acdd8aebcd18699abc5dd0425cJack He  ASSERT_EQ(status, PORT_SUCCESS);
751b690c22637e522acdd8aebcd18699abc5dd0425cJack He
752b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 3";
753b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // While our connection is pending, remote device tries to connect to
754b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // new_lcid, with L2CAP command id: pending_cmd_id
755b690c22637e522acdd8aebcd18699abc5dd0425cJack He  static const uint8_t pending_cmd_id = 0x05;
756b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // RFCOMM starts timer for collision:
757b690c22637e522acdd8aebcd18699abc5dd0425cJack He  l2cap_appl_info_.pL2CA_ConnectInd_Cb(test_address, new_lcid, BT_PSM_RFCOMM,
758b690c22637e522acdd8aebcd18699abc5dd0425cJack He                                       pending_cmd_id);
759b690c22637e522acdd8aebcd18699abc5dd0425cJack He
760b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 4";
761b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Remote reject our connection request saying PSM not allowed
762b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // This should trigger RFCOMM to accept remote L2CAP connection at new_lcid
763b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(l2cap_interface_, ConnectResponse(test_address, pending_cmd_id,
764b690c22637e522acdd8aebcd18699abc5dd0425cJack He                                                new_lcid, L2CAP_CONN_OK, 0))
765b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(Return(true));
766b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Followed by configure request for MTU size
767b690c22637e522acdd8aebcd18699abc5dd0425cJack He  tL2CAP_CFG_INFO our_cfg_req = {.mtu_present = true, .mtu = L2CAP_MTU_SIZE};
768b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(l2cap_interface_,
769b690c22637e522acdd8aebcd18699abc5dd0425cJack He              ConfigRequest(new_lcid, PointerMemoryEqual(&our_cfg_req)))
770b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(Return(true));
771b690c22637e522acdd8aebcd18699abc5dd0425cJack He  l2cap_appl_info_.pL2CA_ConnectCfm_Cb(old_lcid, L2CAP_CONN_NO_PSM);
772b690c22637e522acdd8aebcd18699abc5dd0425cJack He
773b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 5";
774b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Remote device also ask to configure MTU size as well
775b690c22637e522acdd8aebcd18699abc5dd0425cJack He  tL2CAP_CFG_INFO peer_cfg_req = {.mtu_present = true, .mtu = test_mtu};
776b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // We responded by saying OK
777b690c22637e522acdd8aebcd18699abc5dd0425cJack He  tL2CAP_CFG_INFO our_cfg_rsp = {.result = L2CAP_CFG_OK,
778b690c22637e522acdd8aebcd18699abc5dd0425cJack He                                 .mtu = peer_cfg_req.mtu};
779b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(l2cap_interface_,
780b690c22637e522acdd8aebcd18699abc5dd0425cJack He              ConfigResponse(new_lcid, PointerMemoryEqual(&our_cfg_rsp)))
781b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(Return(true));
782b690c22637e522acdd8aebcd18699abc5dd0425cJack He  l2cap_appl_info_.pL2CA_ConfigInd_Cb(new_lcid, &peer_cfg_req);
783b690c22637e522acdd8aebcd18699abc5dd0425cJack He
784b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 6";
785b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Remote device accepted our MTU size
786b690c22637e522acdd8aebcd18699abc5dd0425cJack He  tL2CAP_CFG_INFO peer_cfg_rsp = {.mtu_present = true, .mtu = L2CAP_MTU_SIZE};
787b690c22637e522acdd8aebcd18699abc5dd0425cJack He  l2cap_appl_info_.pL2CA_ConfigCfm_Cb(new_lcid, &peer_cfg_rsp);
788b690c22637e522acdd8aebcd18699abc5dd0425cJack He
789b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // L2CAP collision and connection setup done
790b690c22637e522acdd8aebcd18699abc5dd0425cJack He
791b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 7";
792b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Remote device connect multiplexer channel
793b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* sabm_channel_0 = AllocateWrappedIncomingL2capAclPacket(
794b690c22637e522acdd8aebcd18699abc5dd0425cJack He      CreateQuickSabmPacket(RFCOMM_MX_DLCI, new_lcid, acl_handle));
795b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // We accept
796b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* ua_channel_0 = AllocateWrappedOutgoingL2capAclPacket(
797b690c22637e522acdd8aebcd18699abc5dd0425cJack He      CreateQuickUaPacket(RFCOMM_MX_DLCI, new_lcid, acl_handle));
798b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(ua_channel_0)))
799b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(Return(L2CAP_DW_SUCCESS));
800b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // And immediately try to configure test_peer_scn
801b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* uih_pn_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket(
802b690c22637e522acdd8aebcd18699abc5dd0425cJack He      CreateQuickPnPacket(false, GetDlci(true, test_peer_scn), true, test_mtu,
803b690c22637e522acdd8aebcd18699abc5dd0425cJack He                          RFCOMM_PN_CONV_LAYER_CBFC_I >> 4, 0, RFCOMM_K_MAX,
804b690c22637e522acdd8aebcd18699abc5dd0425cJack He                          new_lcid, acl_handle));
805b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(l2cap_interface_,
806b690c22637e522acdd8aebcd18699abc5dd0425cJack He              DataWrite(new_lcid, BtHdrEqual(uih_pn_cmd_to_peer)))
807b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(Return(L2CAP_DW_SUCCESS));
808b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Packet should be freed by this method
809b690c22637e522acdd8aebcd18699abc5dd0425cJack He  l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, sabm_channel_0);
810b690c22637e522acdd8aebcd18699abc5dd0425cJack He  osi_free(ua_channel_0);
811b690c22637e522acdd8aebcd18699abc5dd0425cJack He  osi_free(uih_pn_cmd_to_peer);
812b690c22637e522acdd8aebcd18699abc5dd0425cJack He
813b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 8";
814b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Peer tries to configure test_server_scn
815b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* uih_pn_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket(
816b690c22637e522acdd8aebcd18699abc5dd0425cJack He      CreateQuickPnPacket(true, GetDlci(false, test_server_scn), true, test_mtu,
817b690c22637e522acdd8aebcd18699abc5dd0425cJack He                          RFCOMM_PN_CONV_LAYER_CBFC_I >> 4, 0, RFCOMM_K_MAX,
818b690c22637e522acdd8aebcd18699abc5dd0425cJack He                          new_lcid, acl_handle));
819b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // We, as acceptor, must accept
820b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* uih_pn_rsp_to_peer = AllocateWrappedOutgoingL2capAclPacket(
821b690c22637e522acdd8aebcd18699abc5dd0425cJack He      CreateQuickPnPacket(false, GetDlci(false, test_server_scn), false,
822b690c22637e522acdd8aebcd18699abc5dd0425cJack He                          test_mtu, RFCOMM_PN_CONV_LAYER_CBFC_R >> 4, 0,
823b690c22637e522acdd8aebcd18699abc5dd0425cJack He                          RFCOMM_K_MAX, new_lcid, acl_handle));
824b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(l2cap_interface_,
825b690c22637e522acdd8aebcd18699abc5dd0425cJack He              DataWrite(new_lcid, BtHdrEqual(uih_pn_rsp_to_peer)))
826b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .Times(1)
827b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(Return(L2CAP_DW_SUCCESS));
828b690c22637e522acdd8aebcd18699abc5dd0425cJack He  l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_pn_cmd_from_peer);
829b690c22637e522acdd8aebcd18699abc5dd0425cJack He  osi_free(uih_pn_rsp_to_peer);
830b690c22637e522acdd8aebcd18699abc5dd0425cJack He
831b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 9";
832b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Remote never replies our configuration request for test_peer_scn
833b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // But instead connect to test_server_scn directly
834b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* sabm_server_scn =
835b690c22637e522acdd8aebcd18699abc5dd0425cJack He      AllocateWrappedIncomingL2capAclPacket(CreateQuickSabmPacket(
836b690c22637e522acdd8aebcd18699abc5dd0425cJack He          GetDlci(false, test_server_scn), new_lcid, acl_handle));
837b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // We must do security check first
838b690c22637e522acdd8aebcd18699abc5dd0425cJack He  tBTM_SEC_CALLBACK* security_callback = nullptr;
839b690c22637e522acdd8aebcd18699abc5dd0425cJack He  void* p_port = nullptr;
840b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(btm_security_internal_interface_,
841b690c22637e522acdd8aebcd18699abc5dd0425cJack He              MultiplexingProtocolAccessRequest(
842b690c22637e522acdd8aebcd18699abc5dd0425cJack He                  test_address, BT_PSM_RFCOMM, false, BTM_SEC_PROTO_RFCOMM,
843b690c22637e522acdd8aebcd18699abc5dd0425cJack He                  test_server_scn, NotNull(), NotNull()))
844b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(DoAll(SaveArg<5>(&security_callback), SaveArg<6>(&p_port),
845b690c22637e522acdd8aebcd18699abc5dd0425cJack He                      Return(BTM_SUCCESS)));
846b690c22637e522acdd8aebcd18699abc5dd0425cJack He  l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, sabm_server_scn);
847b690c22637e522acdd8aebcd18699abc5dd0425cJack He
848b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 10";
849b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // After security check, we accept the connection
850b690c22637e522acdd8aebcd18699abc5dd0425cJack He  ASSERT_TRUE(security_callback);
851b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* ua_server_scn =
852b690c22637e522acdd8aebcd18699abc5dd0425cJack He      AllocateWrappedOutgoingL2capAclPacket(CreateQuickUaPacket(
853b690c22637e522acdd8aebcd18699abc5dd0425cJack He          GetDlci(false, test_server_scn), new_lcid, acl_handle));
854b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(l2cap_interface_, DataWrite(new_lcid, BtHdrEqual(ua_server_scn)))
855b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(Return(L2CAP_DW_SUCCESS));
856b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // Callback should come from server port instead, client port will timeout
857b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // in 20 seconds
858b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(rfcomm_callback_,
859b690c22637e522acdd8aebcd18699abc5dd0425cJack He              PortManagementCallback(PORT_SUCCESS, server_handle, 0));
860b690c22637e522acdd8aebcd18699abc5dd0425cJack He  security_callback(&test_address, BT_TRANSPORT_BR_EDR, p_port, BTM_SUCCESS);
861b690c22637e522acdd8aebcd18699abc5dd0425cJack He  osi_free(ua_server_scn);
862b690c22637e522acdd8aebcd18699abc5dd0425cJack He
863b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 11";
864b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // MPX_CTRL Modem Status Command (MSC)
865b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* uih_msc_cmd_from_peer = AllocateWrappedIncomingL2capAclPacket(
866b690c22637e522acdd8aebcd18699abc5dd0425cJack He      CreateQuickMscPacket(true, GetDlci(false, test_server_scn), new_lcid,
867b690c22637e522acdd8aebcd18699abc5dd0425cJack He                           acl_handle, true, false, true, true, false, true));
868b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* uih_msc_rsp_to_peer = AllocateWrappedOutgoingL2capAclPacket(
869b690c22637e522acdd8aebcd18699abc5dd0425cJack He      CreateQuickMscPacket(false, GetDlci(false, test_server_scn), new_lcid,
870b690c22637e522acdd8aebcd18699abc5dd0425cJack He                           acl_handle, false, false, true, true, false, true));
871b690c22637e522acdd8aebcd18699abc5dd0425cJack He  // MPX_CTRL Modem Status Response (MSC)
872b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(l2cap_interface_,
873b690c22637e522acdd8aebcd18699abc5dd0425cJack He              DataWrite(new_lcid, BtHdrEqual(uih_msc_rsp_to_peer)))
874b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(Return(L2CAP_DW_SUCCESS));
875b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* uih_msc_cmd_to_peer = AllocateWrappedOutgoingL2capAclPacket(
876b690c22637e522acdd8aebcd18699abc5dd0425cJack He      CreateQuickMscPacket(false, GetDlci(false, test_server_scn), new_lcid,
877b690c22637e522acdd8aebcd18699abc5dd0425cJack He                           acl_handle, true, false, true, true, false, true));
878b690c22637e522acdd8aebcd18699abc5dd0425cJack He  EXPECT_CALL(l2cap_interface_,
879b690c22637e522acdd8aebcd18699abc5dd0425cJack He              DataWrite(new_lcid, BtHdrEqual(uih_msc_cmd_to_peer)))
880b690c22637e522acdd8aebcd18699abc5dd0425cJack He      .WillOnce(Return(L2CAP_DW_SUCCESS));
881b690c22637e522acdd8aebcd18699abc5dd0425cJack He  l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_msc_cmd_from_peer);
882b690c22637e522acdd8aebcd18699abc5dd0425cJack He  osi_free(uih_msc_rsp_to_peer);
883b690c22637e522acdd8aebcd18699abc5dd0425cJack He  osi_free(uih_msc_cmd_to_peer);
884b690c22637e522acdd8aebcd18699abc5dd0425cJack He
885b690c22637e522acdd8aebcd18699abc5dd0425cJack He  VLOG(1) << "Step 12";
886b690c22637e522acdd8aebcd18699abc5dd0425cJack He  BT_HDR* uih_msc_rsp_from_peer = AllocateWrappedIncomingL2capAclPacket(
887b690c22637e522acdd8aebcd18699abc5dd0425cJack He      CreateQuickMscPacket(true, GetDlci(false, test_server_scn), new_lcid,
888b690c22637e522acdd8aebcd18699abc5dd0425cJack He                           acl_handle, false, false, true, true, false, true));
889b690c22637e522acdd8aebcd18699abc5dd0425cJack He  l2cap_appl_info_.pL2CA_DataInd_Cb(new_lcid, uih_msc_rsp_from_peer);
890b690c22637e522acdd8aebcd18699abc5dd0425cJack He}
891b690c22637e522acdd8aebcd18699abc5dd0425cJack He
892272534fc2ce4433c89352d84fb07a5a8fc52ed50Jack He}  // namespace
893