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