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