Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "l2cap_packet"
     18 
     19 #include "l2cap_packet.h"
     20 
     21 #include <algorithm>
     22 
     23 #include "osi/include/log.h"
     24 
     25 namespace test_vendor_lib {
     26 
     27 const size_t kL2capHeaderLength = 4;
     28 const size_t kSduFirstHeaderLength = 8;
     29 const size_t kSduStandardHeaderLength = 6;
     30 const size_t kFcsBytes = 2;
     31 const uint16_t kSduTxSeqBits = 0x007E;
     32 const uint8_t kSduFirstReqseq = 0x40;
     33 const uint8_t kSduContinuationReqseq = 0xC0;
     34 const uint8_t kSduEndReqseq = 0x80;
     35 
     36 std::shared_ptr<L2capPacket> L2capPacket::assemble(
     37     const std::vector<std::shared_ptr<L2capSdu> >& sdu_packets) {
     38   std::shared_ptr<L2capPacket> built_l2cap_packet(new L2capPacket());
     39   uint16_t l2cap_payload_length = 0;
     40   uint16_t first_packet_channel_id = 0;
     41   uint16_t total_expected_l2cap_length;
     42   uint8_t txseq_start;
     43 
     44   if (sdu_packets.size() == 0) {
     45     LOG_DEBUG(LOG_TAG, "%s: No SDU received.", __func__);
     46     return nullptr;
     47   }
     48   if (sdu_packets.size() == 1 &&
     49       !L2capSdu::is_complete_l2cap(*sdu_packets[0])) {
     50     LOG_DEBUG(LOG_TAG, "%s: Unsegmented SDU has incorrect SAR bits.", __func__);
     51     return nullptr;
     52   }
     53 
     54   first_packet_channel_id = sdu_packets[0]->get_channel_id();
     55 
     56   built_l2cap_packet->l2cap_packet_.resize(kL2capHeaderLength);
     57 
     58   for (size_t i = 0; i < sdu_packets.size(); i++) {
     59     uint16_t payload_length = sdu_packets[i]->get_payload_length();
     60 
     61     // TODO(jruthe): Remove these checks when ACL packets have been
     62     // implemented. Once those are done, that will be the only way to create
     63     // L2capSdu objects and these checks will be moved there instead.
     64     //
     65     // Check the integrity of the packet length, if it is zero, it is invalid.
     66     // The maximum size of a single, segmented L2CAP payload is 1016 bytes.
     67     if ((payload_length <= 0) ||
     68         (payload_length != sdu_packets[i]->get_vector_size() - 4)) {
     69       LOG_DEBUG(LOG_TAG, "%s: SDU payload length incorrect.", __func__);
     70       return nullptr;
     71     }
     72 
     73     uint16_t fcs_check = sdu_packets[i]->get_fcs();
     74 
     75     if (sdu_packets[i]->calculate_fcs() != fcs_check) {
     76       LOG_DEBUG(LOG_TAG, "%s: SDU fcs is incorrect.", __func__);
     77       return nullptr;
     78     }
     79 
     80     uint16_t controls = sdu_packets[i]->get_controls();
     81 
     82     if (sdu_packets[i]->get_channel_id() != first_packet_channel_id) {
     83       LOG_DEBUG(LOG_TAG, "%s: SDU CID does not match expected.", __func__);
     84       return nullptr;
     85     }
     86 
     87     if (i == 0) txseq_start = controls & kSduTxSeqBits;
     88 
     89     // Bluetooth Specification version 4.2 volume 3 part A 3.3.2:
     90     // If there is only a single SDU, the first two bits of the control must be
     91     // set to 00b, representing an unsegmented SDU. If the SDU is segmented,
     92     // there is a begin and an end. The first segment must have the first two
     93     // control bits set to 01b and the ending segment must have them set to 10b.
     94     // Meanwhile all segments in between the start and end must have the bits
     95     // set to 11b.
     96     size_t starting_index;
     97     uint8_t txseq = controls & kSduTxSeqBits;
     98     if (sdu_packets.size() > 1 && i == 0 &&
     99         !L2capSdu::is_starting_sdu(*sdu_packets[i])) {
    100       LOG_DEBUG(LOG_TAG, "%s: First segmented SDU has incorrect SAR bits.",
    101                 __func__);
    102       return nullptr;
    103     }
    104     if (i != 0 && L2capSdu::is_starting_sdu(*sdu_packets[i])) {
    105       LOG_DEBUG(LOG_TAG,
    106                 "%s: SAR bits set to first segmented SDU on "
    107                 "non-starting SDU.",
    108                 __func__);
    109       return nullptr;
    110     }
    111     if (txseq != (txseq_start + (static_cast<uint8_t>(i) << 1))) {
    112       LOG_DEBUG(LOG_TAG, "%s: TxSeq incorrect.", __func__);
    113       return nullptr;
    114     }
    115     if (sdu_packets.size() > 1 && i == sdu_packets.size() - 1 &&
    116         !L2capSdu::is_ending_sdu(*sdu_packets[i])) {
    117       LOG_DEBUG(LOG_TAG, "%s: Final segmented SDU has incorrect SAR bits.",
    118                 __func__);
    119       return nullptr;
    120     }
    121 
    122     // Subtract the control and fcs from every SDU payload length.
    123     l2cap_payload_length += (payload_length - 4);
    124 
    125     if (L2capSdu::is_starting_sdu(*sdu_packets[i])) {
    126       starting_index = kSduFirstHeaderLength;
    127       total_expected_l2cap_length = sdu_packets[i]->get_total_l2cap_length();
    128 
    129       // Subtract the additional two bytes from the first packet of a segmented
    130       // SDU.
    131       l2cap_payload_length -= 2;
    132     } else {
    133       starting_index = kSduStandardHeaderLength;
    134     }
    135 
    136     Iterator payload_begin = sdu_packets[i]->get_begin() + starting_index;
    137     Iterator payload_end = sdu_packets[i]->get_end() - kFcsBytes;
    138 
    139     built_l2cap_packet->l2cap_packet_.insert(
    140         built_l2cap_packet->l2cap_packet_.end(), payload_begin, payload_end);
    141   }
    142 
    143   if (l2cap_payload_length != total_expected_l2cap_length &&
    144       sdu_packets.size() > 1) {
    145     LOG_DEBUG(LOG_TAG, "%s: Total expected L2CAP payload length incorrect.",
    146               __func__);
    147     return nullptr;
    148   }
    149 
    150   built_l2cap_packet->l2cap_packet_[0] = l2cap_payload_length & 0xFF;
    151   built_l2cap_packet->l2cap_packet_[1] = (l2cap_payload_length & 0xFF00) >> 8;
    152   built_l2cap_packet->l2cap_packet_[2] = first_packet_channel_id & 0xFF;
    153   built_l2cap_packet->l2cap_packet_[3] =
    154       (first_packet_channel_id & 0xFF00) >> 8;
    155 
    156   return built_l2cap_packet;
    157 }  // Assemble
    158 
    159 uint16_t L2capPacket::get_l2cap_cid() const {
    160   return ((l2cap_packet_[3] << 8) | l2cap_packet_[2]);
    161 }
    162 
    163 std::vector<std::shared_ptr<L2capSdu> > L2capPacket::fragment(
    164     uint16_t maximum_sdu_size, uint8_t txseq, uint8_t reqseq) {
    165   std::vector<std::shared_ptr<L2capSdu> > sdu;
    166   if (!check_l2cap_packet()) return sdu;
    167 
    168   std::vector<uint8_t> current_sdu;
    169 
    170   Iterator current_iter = get_begin() + kL2capHeaderLength;
    171   Iterator end_iter = get_end();
    172 
    173   size_t number_of_packets = ceil((l2cap_packet_.size() - kL2capHeaderLength) /
    174                                   static_cast<float>(maximum_sdu_size));
    175 
    176   if (number_of_packets == 0) {
    177     current_sdu.resize(kSduStandardHeaderLength);
    178 
    179     set_sdu_header_length(current_sdu, kL2capHeaderLength);
    180 
    181     set_sdu_cid(current_sdu, get_l2cap_cid());
    182 
    183     reqseq = (reqseq & 0xF0) >> 4;
    184     set_sdu_control_bytes(current_sdu, txseq, reqseq);
    185 
    186     sdu.push_back(L2capSdu::L2capSduBuilder(current_sdu));
    187 
    188     return sdu;
    189   }
    190 
    191   uint16_t header_length = 0x0000;
    192 
    193   if (number_of_packets == 1) {
    194     current_sdu.clear();
    195     current_sdu.resize(kSduStandardHeaderLength);
    196 
    197     header_length = ((l2cap_packet_[1] & 0xFF) << 8) | l2cap_packet_[0];
    198     header_length += kL2capHeaderLength;
    199     set_sdu_header_length(current_sdu, header_length);
    200 
    201     set_sdu_cid(current_sdu, get_l2cap_cid());
    202 
    203     set_sdu_control_bytes(current_sdu, txseq, 0x00);
    204 
    205     current_sdu.insert(current_sdu.end(), current_iter, end_iter);
    206 
    207     sdu.push_back(L2capSdu::L2capSduBuilder(current_sdu));
    208 
    209     return sdu;
    210   }
    211 
    212   Iterator next_iter =
    213       current_iter + (maximum_sdu_size - (kSduFirstHeaderLength + 2));
    214 
    215   sdu.reserve(number_of_packets);
    216   sdu.clear();
    217 
    218   for (size_t i = 0; i <= number_of_packets; i++) {
    219     if (i == 0) {
    220       current_sdu.resize(kSduFirstHeaderLength);
    221 
    222       header_length = maximum_sdu_size - kL2capHeaderLength;
    223 
    224       reqseq = reqseq | kSduFirstReqseq;
    225 
    226       set_total_sdu_length(current_sdu, l2cap_packet_.size() - 4);
    227     } else {
    228       current_sdu.resize(kSduStandardHeaderLength);
    229 
    230       header_length = (next_iter - current_iter) + kL2capHeaderLength;
    231 
    232       reqseq = reqseq & 0x0F;
    233 
    234       if (i < number_of_packets) {
    235         reqseq |= kSduContinuationReqseq;
    236       } else {
    237         reqseq |= kSduEndReqseq;
    238       }
    239     }
    240     set_sdu_header_length(current_sdu, header_length);
    241 
    242     set_sdu_cid(current_sdu, get_l2cap_cid());
    243 
    244     set_sdu_control_bytes(current_sdu, txseq, reqseq);
    245     txseq += 2;
    246 
    247     // Txseq has a maximum of 0x3F. If it exceeds that, it restarts at 0x00.
    248     if (txseq > 0x3F) txseq = 0x00;
    249 
    250     current_sdu.insert(current_sdu.end(), current_iter, next_iter);
    251     current_iter = next_iter;
    252 
    253     next_iter = current_iter + (maximum_sdu_size - kSduFirstHeaderLength);
    254 
    255     sdu.push_back(L2capSdu::L2capSduBuilder(std::move(current_sdu)));
    256   }
    257 
    258   return sdu;
    259 }  // fragment
    260 
    261 void L2capPacket::set_sdu_header_length(std::vector<uint8_t>& sdu,
    262                                         uint16_t length) {
    263   sdu[0] = length & 0xFF;
    264   sdu[1] = (length & 0xFF00) >> 8;
    265 }
    266 
    267 void L2capPacket::set_total_sdu_length(std::vector<uint8_t>& sdu,
    268                                        uint16_t total_sdu_length) {
    269   sdu[6] = total_sdu_length & 0xFF;
    270   sdu[7] = (total_sdu_length & 0xFF00) >> 8;
    271 }
    272 
    273 void L2capPacket::set_sdu_cid(std::vector<uint8_t>& sdu, uint16_t cid) {
    274   sdu[2] = cid & 0xFF;
    275   sdu[3] = (cid & 0xFF00) >> 8;
    276 }
    277 
    278 void L2capPacket::set_sdu_control_bytes(std::vector<uint8_t>& sdu,
    279                                         uint8_t txseq, uint8_t reqseq) {
    280   sdu[4] = txseq;
    281   sdu[5] = reqseq;
    282 }
    283 
    284 bool L2capPacket::check_l2cap_packet() const {
    285   uint16_t payload_length = ((l2cap_packet_[1] & 0xFF) << 8) | l2cap_packet_[0];
    286 
    287   if (l2cap_packet_.size() < 4) return false;
    288   if (payload_length != (l2cap_packet_.size() - 4)) return false;
    289 
    290   return true;
    291 }
    292 
    293 // HciPacket Functions
    294 size_t L2capPacket::get_length() { return l2cap_packet_.size(); }
    295 
    296 uint8_t& L2capPacket::get_at_index(size_t index) {
    297   return l2cap_packet_[index];
    298 }
    299 
    300 }  // namespace test_vendor_lib
    301