1 /****************************************************************************** 2 * 3 * Copyright (C) 2017 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 #pragma once 20 21 #include <vector> 22 23 class AdvertiseDataParser { 24 public: 25 /** 26 * Return true if this |ad| represent properly formatted advertising data. 27 */ IsValid(const std::vector<uint8_t> & ad)28 static bool IsValid(const std::vector<uint8_t>& ad) { 29 size_t position = 0; 30 31 size_t ad_len = ad.size(); 32 while (position != ad_len) { 33 uint8_t len = ad[position]; 34 35 // A field length of 0 would be invalid as it should at least contain the 36 // EIR field type. 37 if (len == 0) return false; 38 39 // If the length of the current field would exceed the total data length, 40 // then the data is badly formatted. 41 if (position + len >= ad_len) { 42 return false; 43 } 44 45 position += len + 1; 46 } 47 48 return true; 49 } 50 51 /** 52 * This function returns a pointer inside the |ad| array of length |ad_len| 53 * where a field of |type| is located, together with its length in |p_length| 54 */ GetFieldByType(const uint8_t * ad,size_t ad_len,uint8_t type,uint8_t * p_length)55 static const uint8_t* GetFieldByType(const uint8_t* ad, size_t ad_len, 56 uint8_t type, uint8_t* p_length) { 57 size_t position = 0; 58 59 while (position != ad_len) { 60 uint8_t len = ad[position]; 61 62 if (len == 0) break; 63 if (position + len >= ad_len) break; 64 65 uint8_t adv_type = ad[position + 1]; 66 67 if (adv_type == type) { 68 /* length doesn't include itself */ 69 *p_length = len - 1; /* minus the length of type */ 70 return ad + position + 2; 71 } 72 73 position += len + 1; /* skip the length of data */ 74 } 75 76 *p_length = 0; 77 return NULL; 78 } 79 80 /** 81 * This function returns a pointer inside the |adv| where a field of |type| is 82 * located, together with it' length in |p_length| 83 */ GetFieldByType(std::vector<uint8_t> const & ad,uint8_t type,uint8_t * p_length)84 static const uint8_t* GetFieldByType(std::vector<uint8_t> const& ad, 85 uint8_t type, uint8_t* p_length) { 86 return GetFieldByType(ad.data(), ad.size(), type, p_length); 87 } 88 }; 89