1 /****************************************************************************** 2 * 3 * Copyright 2019 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 <array> 22 #include <cstring> 23 #include <initializer_list> 24 #include <optional> 25 #include <ostream> 26 #include <string> 27 28 #include "common/interfaces/ILoggable.h" 29 #include "packet/custom_field_fixed_size_interface.h" 30 #include "storage/serializable.h" 31 32 namespace bluetooth { 33 namespace hci { 34 35 class Address final : public packet::CustomFieldFixedSizeInterface<Address>, 36 public storage::Serializable<Address>, 37 public bluetooth::common::IRedactableLoggable { 38 public: 39 static constexpr size_t kLength = 6; 40 41 // Bluetooth MAC address bytes saved in little endian format. 42 // The address MSB is address[5], the address LSB is address[0]. 43 // Note that the textual representation follows the big endian format, 44 // ie. Address{0, 1, 2, 3, 4, 5} is represented as 05:04:03:02:01:00. 45 std::array<uint8_t, kLength> address = {}; 46 47 Address() = default; 48 Address(const uint8_t (&addr)[kLength]); 49 Address(std::initializer_list<uint8_t> l); 50 51 // CustomFieldFixedSizeInterface methods data()52 inline uint8_t* data() override { 53 return address.data(); 54 } data()55 inline const uint8_t* data() const override { 56 return address.data(); 57 } 58 59 // storage::Serializable methods 60 std::string ToString() const override; 61 std::string ToColonSepHexString() const; 62 std::string ToStringForLogging() const override; 63 std::string ToRedactedStringForLogging() const override; 64 65 static std::optional<Address> FromString(const std::string& from); 66 std::string ToLegacyConfigString() const override; 67 static std::optional<Address> FromLegacyConfigString(const std::string& str); 68 69 bool operator<(const Address& rhs) const { 70 return address < rhs.address; 71 } 72 bool operator==(const Address& rhs) const { 73 return address == rhs.address; 74 } 75 bool operator>(const Address& rhs) const { 76 return (rhs < *this); 77 } 78 bool operator<=(const Address& rhs) const { 79 return !(*this > rhs); 80 } 81 bool operator>=(const Address& rhs) const { 82 return !(*this < rhs); 83 } 84 bool operator!=(const Address& rhs) const { 85 return !(*this == rhs); 86 } 87 IsEmpty()88 bool IsEmpty() const { 89 return *this == kEmpty; 90 } 91 92 // Converts |string| to Address and places it in |to|. If |from| does 93 // not represent a Bluetooth address, |to| is not modified and this function 94 // returns false. Otherwise, it returns true. 95 static bool FromString(const std::string& from, Address& to); 96 97 // Copies |from| raw Bluetooth address octets to the local object. 98 // Returns the number of copied octets - should be always Address::kLength 99 size_t FromOctets(const uint8_t* from); 100 101 static bool IsValidAddress(const std::string& address); 102 103 static const Address kEmpty; // 00:00:00:00:00:00 104 static const Address kAny; // FF:FF:FF:FF:FF:FF 105 private: 106 std::string _ToMaskedColonSepHexString(int bytes_to_mask) const; 107 }; 108 109 // TODO: to fine-tune this. 110 // we need an interface between the logger and ILoggable 111 inline std::ostream& operator<<(std::ostream& os, const Address& a) { 112 os << a.ToString(); 113 return os; 114 } 115 116 } // namespace hci 117 } // namespace bluetooth 118 119 namespace std { 120 template <> 121 struct hash<bluetooth::hci::Address> { 122 std::size_t operator()(const bluetooth::hci::Address& val) const { 123 static_assert(sizeof(uint64_t) >= bluetooth::hci::Address::kLength); 124 uint64_t int_addr = 0; 125 memcpy(reinterpret_cast<uint8_t*>(&int_addr), val.data(), bluetooth::hci::Address::kLength); 126 return std::hash<uint64_t>{}(int_addr); 127 } 128 }; 129 } // namespace std 130