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