Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright 2016 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 "broken_adv"
     18 
     19 #include "broken_adv.h"
     20 
     21 #include "osi/include/log.h"
     22 #include "stack/include/hcidefs.h"
     23 
     24 using std::vector;
     25 
     26 namespace test_vendor_lib {
     27 
     28 BrokenAdv::BrokenAdv() {
     29   advertising_interval_ms_ = std::chrono::milliseconds(1280);
     30   advertising_type_ = BTM_BLE_NON_CONNECT_EVT;
     31   adv_data_ = {
     32       0x02,  // Length
     33       BTM_BLE_AD_TYPE_FLAG,
     34       BTM_BLE_BREDR_NOT_SPT | BTM_BLE_GEN_DISC_FLAG,
     35       0x13,  // Length
     36       BTM_BLE_AD_TYPE_NAME_CMPL,
     37       'g',
     38       'D',
     39       'e',
     40       'v',
     41       'i',
     42       'c',
     43       'e',
     44       '-',
     45       'b',
     46       'r',
     47       'o',
     48       'k',
     49       'e',
     50       'n',
     51       '_',
     52       'a',
     53       'd',
     54       'v',
     55   };
     56 
     57   constant_adv_data_ = adv_data_;
     58 
     59   scan_response_present_ = true;
     60   scan_data_ = {0x0b,  // Length
     61                 BTM_BLE_AD_TYPE_NAME_SHORT,
     62                 'b',
     63                 'r',
     64                 'o',
     65                 'k',
     66                 'e',
     67                 'n',
     68                 'n',
     69                 'e',
     70                 's',
     71                 's'};
     72 
     73   extended_inquiry_data_ = {0x07,  // Length
     74                             BT_EIR_COMPLETE_LOCAL_NAME_TYPE,
     75                             'B',
     76                             'R',
     77                             '0',
     78                             'K',
     79                             '3',
     80                             'N'};
     81   page_scan_repetition_mode_ = 0;
     82   page_scan_delay_ms_ = std::chrono::milliseconds(600);
     83 }
     84 
     85 void BrokenAdv::Initialize(const vector<std::string>& args) {
     86   if (args.size() < 2) return;
     87 
     88   BtAddress addr;
     89   if (addr.FromString(args[1])) SetBtAddress(addr);
     90 
     91   if (args.size() < 3) return;
     92 
     93   SetAdvertisementInterval(std::chrono::milliseconds(std::stoi(args[2])));
     94 }
     95 
     96 // Mostly return the correct length
     97 static uint8_t random_length(size_t bytes_remaining) {
     98   uint32_t randomness = rand();
     99 
    100   switch ((randomness & 0xf000000) >> 24) {
    101     case (0):
    102       return bytes_remaining + (randomness & 0xff);
    103     case (1):
    104       return bytes_remaining - (randomness & 0xff);
    105     case (2):
    106       return bytes_remaining + (randomness & 0xf);
    107     case (3):
    108       return bytes_remaining - (randomness & 0xf);
    109     case (5):
    110     case (6):
    111       return bytes_remaining + (randomness & 0x3);
    112     case (7):
    113     case (8):
    114       return bytes_remaining - (randomness & 0x3);
    115     default:
    116       return bytes_remaining;
    117   }
    118 }
    119 
    120 static size_t random_adv_type() {
    121   uint32_t randomness = rand();
    122 
    123   switch ((randomness & 0xf000000) >> 24) {
    124     case (0):
    125       return BTM_EIR_MANUFACTURER_SPECIFIC_TYPE;
    126     case (1):
    127       return (randomness & 0xff);
    128     default:
    129       return (randomness & 0x1f);
    130   }
    131 }
    132 
    133 static size_t random_data_length(size_t length, size_t bytes_remaining) {
    134   uint32_t randomness = rand();
    135 
    136   switch ((randomness & 0xf000000) >> 24) {
    137     case (0):
    138       return bytes_remaining;
    139     case (1):
    140       return (length + (randomness & 0xff)) % bytes_remaining;
    141     default:
    142       return (length <= bytes_remaining ? length : bytes_remaining);
    143   }
    144 }
    145 
    146 static void RandomizeAdvertisement(vector<uint8_t>& ad, size_t max) {
    147   uint8_t length = random_length(max);
    148   uint8_t data_length = random_data_length(length, max);
    149 
    150   ad.push_back(random_adv_type());
    151   ad.push_back(length);
    152   for (size_t i = 0; i < data_length; i++) ad.push_back(rand() & 0xff);
    153 }
    154 
    155 void BrokenAdv::UpdateAdvertisement() {
    156   adv_data_.clear();
    157   for (size_t i = 0; i < constant_adv_data_.size(); i++)
    158     adv_data_.push_back(constant_adv_data_[i]);
    159 
    160   RandomizeAdvertisement(adv_data_, 31 - adv_data_.size());
    161 
    162   RandomizeAdvertisement(scan_data_, 31);
    163 
    164   std::vector<uint8_t> curr_addr;
    165   BtAddress next_addr;
    166   GetBtAddress().ToVector(curr_addr);
    167   curr_addr[0]++;
    168   next_addr.FromVector(curr_addr);
    169 
    170   SetBtAddress(next_addr);
    171 }
    172 
    173 std::string BrokenAdv::ToString() const {
    174   std::string str = Device::ToString() + std::string(": Interval = ") +
    175                     std::to_string(advertising_interval_ms_.count());
    176   return str;
    177 }
    178 
    179 void BrokenAdv::UpdatePageScan() {
    180   std::vector<uint8_t> broken_addr;
    181   RandomizeAdvertisement(scan_data_, 31);
    182 
    183   BtAddress next_addr;
    184   GetBtAddress().ToVector(broken_addr);
    185   broken_addr[1]++;
    186   next_addr.FromVector(broken_addr);
    187 
    188   SetBtAddress(next_addr);
    189 }
    190 
    191 void BrokenAdv::TimerTick() {
    192   UpdatePageScan();
    193   UpdateAdvertisement();
    194 }
    195 
    196 }  // namespace test_vendor_lib
    197