Home | History | Annotate | Download | only in rfcomm
      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