1 /******************************************************************************
2 *
3 * Copyright 2018 The Android Open Source Project
4 *
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:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 *
17 ******************************************************************************/
18
19 #include <bitset>
20 #include <string>
21 #include <vector>
22
23 #include "stack/rfcomm/rfc_int.h"
24 #include "stack_rfcomm_test_utils.h"
25 #include "stack_test_packet_utils.h"
26
27 namespace bluetooth {
28 namespace rfcomm {
29
GetDlci(bool on_originator_side,uint8_t scn)30 uint8_t GetDlci(bool on_originator_side, uint8_t scn) {
31 return static_cast<uint8_t>((scn << 1) + (on_originator_side ? 1 : 0));
32 }
33
GetAddressField(bool ea,bool cr,uint8_t dlci)34 uint8_t GetAddressField(bool ea, bool cr, uint8_t dlci) {
35 std::bitset<8> address;
36 address.set(0, ea);
37 // For UIH frame, cr for initiating device is 1, otherwise 0
38 // Otherwise:
39 // Command: Initiator -> Responder: 1
40 // Command: Responder -> Initiator 0
41 // Response: Initiator -> Responder 0
42 // Response: Responder -> Initiator 1
43 // Initiator is defined by the one who send SABM=1 command
44 address.set(1, cr);
45 address |= dlci << 2;
46 return static_cast<uint8_t>(address.to_ulong());
47 }
48
GetControlField(bool pf,uint8_t frame_type)49 uint8_t GetControlField(bool pf, uint8_t frame_type) {
50 std::bitset<8> control;
51 control |= frame_type;
52 control.set(4, pf);
53 return static_cast<uint8_t>(control.to_ulong());
54 }
55
GetFrameTypeFromControlField(uint8_t control_field)56 uint8_t GetFrameTypeFromControlField(uint8_t control_field) {
57 return static_cast<uint8_t>(control_field & ~(0b10000));
58 }
59
CreateMccPnFrame(uint8_t dlci,uint8_t i_bits,uint8_t cl_bits,uint8_t priority,uint8_t timer_value,uint16_t rfcomm_mtu,uint8_t max_num_retransmission,uint8_t err_recovery_window_k)60 std::vector<uint8_t> CreateMccPnFrame(uint8_t dlci, uint8_t i_bits,
61 uint8_t cl_bits, uint8_t priority,
62 uint8_t timer_value, uint16_t rfcomm_mtu,
63 uint8_t max_num_retransmission,
64 uint8_t err_recovery_window_k) {
65 // Data in little endian order
66 std::vector<uint8_t> result;
67 result.push_back(static_cast<uint8_t>(dlci & 0b00111111));
68 result.push_back(static_cast<uint8_t>((cl_bits << 4) | (i_bits & 0x0F)));
69 result.push_back(static_cast<uint8_t>(priority & 0b00111111));
70 result.push_back(timer_value);
71 result.push_back(static_cast<uint8_t>(rfcomm_mtu));
72 result.push_back(static_cast<uint8_t>(rfcomm_mtu >> 8));
73 result.push_back(max_num_retransmission);
74 result.push_back(static_cast<uint8_t>(err_recovery_window_k & 0b111));
75 return result;
76 }
77
CreateMccMscFrame(uint8_t dlci,bool fc,bool rtc,bool rtr,bool ic,bool dv)78 std::vector<uint8_t> CreateMccMscFrame(uint8_t dlci, bool fc, bool rtc,
79 bool rtr, bool ic, bool dv) {
80 // Data in little endian order
81 std::vector<uint8_t> result;
82 result.push_back(static_cast<uint8_t>((dlci << 2) | 0b11));
83 std::bitset<8> v24_signals;
84 // EA = 1, single byte
85 v24_signals.set(0, true);
86 v24_signals.set(1, fc);
87 v24_signals.set(2, rtc);
88 v24_signals.set(3, rtr);
89 v24_signals.set(6, ic);
90 v24_signals.set(7, dv);
91 result.push_back(static_cast<uint8_t>(v24_signals.to_ulong()));
92 return result;
93 }
94
CreateMultiplexerControlFrame(uint8_t command_type,bool cr,const std::vector<uint8_t> & data)95 std::vector<uint8_t> CreateMultiplexerControlFrame(
96 uint8_t command_type, bool cr, const std::vector<uint8_t>& data) {
97 // Data in little endian order
98 std::vector<uint8_t> result;
99 std::bitset<8> header;
100 header.set(0, true); // EA is always 1
101 header.set(1, cr);
102 header |= command_type << 2;
103 result.push_back(static_cast<uint8_t>(header.to_ulong()));
104 // 7 bit length + EA(1)
105 result.push_back(static_cast<uint8_t>((data.size() << 1) + 1));
106 result.insert(result.end(), data.begin(), data.end());
107 return result;
108 }
109
CreateRfcommPacket(uint8_t address,uint8_t control,int credits,const std::vector<uint8_t> & data)110 std::vector<uint8_t> CreateRfcommPacket(uint8_t address, uint8_t control,
111 int credits,
112 const std::vector<uint8_t>& data) {
113 // Data in little endian order
114 std::vector<uint8_t> result;
115 result.push_back(address);
116 result.push_back(control);
117 size_t length = data.size();
118 if ((length & 0b1000000) != 0) {
119 // 15 bits of length in little endian order + EA(0)
120 // Lower 7 bits + EA(0)
121 result.push_back(static_cast<uint8_t>(length) << 1);
122 // Upper 8 bits
123 result.push_back(static_cast<uint8_t>(length >> 8));
124 } else {
125 // 7 bits of length + EA(1)
126 result.push_back(static_cast<uint8_t>((length << 1) + 1));
127 }
128 if (credits > 0) {
129 result.push_back(static_cast<uint8_t>(credits));
130 }
131 result.insert(result.end(), data.begin(), data.end());
132 if (GetFrameTypeFromControlField(control) == RFCOMM_UIH) {
133 result.push_back(rfc_calc_fcs(2, result.data()));
134 } else {
135 result.push_back(
136 rfc_calc_fcs(static_cast<uint16_t>(result.size()), result.data()));
137 }
138 return result;
139 }
140
CreateQuickUaPacket(uint8_t dlci,uint16_t l2cap_lcid,uint16_t acl_handle)141 std::vector<uint8_t> CreateQuickUaPacket(uint8_t dlci, uint16_t l2cap_lcid,
142 uint16_t acl_handle) {
143 uint8_t address_field = GetAddressField(true, true, dlci);
144 uint8_t control_field = GetControlField(true, RFCOMM_UA);
145 std::vector<uint8_t> rfcomm_packet =
146 CreateRfcommPacket(address_field, control_field, -1, {});
147 std::vector<uint8_t> l2cap_packet =
148 CreateL2capDataPacket(l2cap_lcid, rfcomm_packet);
149 return CreateAclPacket(acl_handle, 0b10, 0b00, l2cap_packet);
150 }
151
CreateQuickSabmPacket(uint8_t dlci,uint16_t l2cap_lcid,uint16_t acl_handle)152 std::vector<uint8_t> CreateQuickSabmPacket(uint8_t dlci, uint16_t l2cap_lcid,
153 uint16_t acl_handle) {
154 uint8_t address_field = GetAddressField(true, true, dlci);
155 uint8_t control_field = GetControlField(true, RFCOMM_SABME);
156 std::vector<uint8_t> rfcomm_packet =
157 CreateRfcommPacket(address_field, control_field, -1, {});
158 std::vector<uint8_t> l2cap_packet =
159 CreateL2capDataPacket(l2cap_lcid, rfcomm_packet);
160 return CreateAclPacket(acl_handle, 0b10, 0b00, l2cap_packet);
161 }
162
CreateQuickPnPacket(bool rfc_cr,uint8_t target_dlci,bool mx_cr,uint16_t rfc_mtu,uint8_t cl,uint8_t priority,uint8_t k,uint16_t l2cap_lcid,uint16_t acl_handle)163 std::vector<uint8_t> CreateQuickPnPacket(bool rfc_cr, uint8_t target_dlci,
164 bool mx_cr, uint16_t rfc_mtu,
165 uint8_t cl, uint8_t priority,
166 uint8_t k, uint16_t l2cap_lcid,
167 uint16_t acl_handle) {
168 uint8_t address_field = GetAddressField(true, rfc_cr, RFCOMM_MX_DLCI);
169 uint8_t control_field = GetControlField(false, RFCOMM_UIH);
170 std::vector<uint8_t> mcc_pn_data = CreateMccPnFrame(
171 target_dlci, 0x0, cl, priority, RFCOMM_T1_DSEC, rfc_mtu, RFCOMM_N2, k);
172 std::vector<uint8_t> mcc_payload =
173 CreateMultiplexerControlFrame(0x20, mx_cr, mcc_pn_data);
174 std::vector<uint8_t> rfcomm_packet =
175 CreateRfcommPacket(address_field, control_field, -1, mcc_payload);
176 std::vector<uint8_t> l2cap_packet =
177 CreateL2capDataPacket(l2cap_lcid, rfcomm_packet);
178 return CreateAclPacket(acl_handle, 0b10, 0b00, l2cap_packet);
179 }
180
CreateQuickMscPacket(bool rfc_cr,uint8_t dlci,uint16_t l2cap_lcid,uint16_t acl_handle,bool mx_cr,bool fc,bool rtc,bool rtr,bool ic,bool dv)181 std::vector<uint8_t> CreateQuickMscPacket(bool rfc_cr, uint8_t dlci,
182 uint16_t l2cap_lcid,
183 uint16_t acl_handle, bool mx_cr,
184 bool fc, bool rtc, bool rtr, bool ic,
185 bool dv) {
186 uint8_t address_field = GetAddressField(true, rfc_cr, RFCOMM_MX_DLCI);
187 uint8_t control_field = GetControlField(false, RFCOMM_UIH);
188 std::vector<uint8_t> mcc_msc_data =
189 CreateMccMscFrame(dlci, fc, rtc, rtr, ic, dv);
190 std::vector<uint8_t> mcc_payload =
191 CreateMultiplexerControlFrame(0x38, mx_cr, mcc_msc_data);
192 std::vector<uint8_t> rfcomm_packet =
193 CreateRfcommPacket(address_field, control_field, -1, mcc_payload);
194 std::vector<uint8_t> l2cap_packet =
195 CreateL2capDataPacket(l2cap_lcid, rfcomm_packet);
196 return CreateAclPacket(acl_handle, 0b10, 0b00, l2cap_packet);
197 }
198
CreateQuickDataPacket(uint8_t dlci,bool cr,uint16_t l2cap_lcid,uint16_t acl_handle,int credits,const std::vector<uint8_t> & data)199 std::vector<uint8_t> CreateQuickDataPacket(uint8_t dlci, bool cr,
200 uint16_t l2cap_lcid,
201 uint16_t acl_handle, int credits,
202 const std::vector<uint8_t>& data) {
203 uint8_t address_field = GetAddressField(true, cr, dlci);
204 uint8_t control_field =
205 GetControlField(credits > 0 ? true : false, RFCOMM_UIH);
206 std::vector<uint8_t> rfcomm_packet =
207 CreateRfcommPacket(address_field, control_field, credits, data);
208 std::vector<uint8_t> l2cap_packet =
209 CreateL2capDataPacket(l2cap_lcid, rfcomm_packet);
210 return CreateAclPacket(acl_handle, 0b10, 0b00, l2cap_packet);
211 }
212
CreateQuickDataPacket(uint8_t dlci,bool cr,uint16_t l2cap_lcid,uint16_t acl_handle,int credits,const std::string & str)213 std::vector<uint8_t> CreateQuickDataPacket(uint8_t dlci, bool cr,
214 uint16_t l2cap_lcid,
215 uint16_t acl_handle, int credits,
216 const std::string& str) {
217 std::vector<uint8_t> data(str.begin(), str.end());
218 return CreateQuickDataPacket(dlci, cr, l2cap_lcid, acl_handle, credits, data);
219 }
220
221 } // namespace rfcomm
222 } // namespace bluetooth
223