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 { return address.data(); } data()54 inline const uint8_t* data() const override { return address.data(); } 55 56 // storage::Serializable methods 57 std::string ToString() const override; 58 std::string ToColonSepHexString() const; 59 std::string ToStringForLogging() const override; 60 std::string ToRedactedStringForLogging() const override; 61 62 static std::optional<Address> FromString(const std::string& from); 63 std::string ToLegacyConfigString() const override; 64 static std::optional<Address> FromLegacyConfigString(const std::string& str); 65 66 bool operator<(const Address& rhs) const { return address < rhs.address; } 67 bool operator==(const Address& rhs) const { return address == rhs.address; } 68 bool operator>(const Address& rhs) const { return rhs < *this; } 69 bool operator<=(const Address& rhs) const { return !(*this > rhs); } 70 bool operator>=(const Address& rhs) const { return !(*this < rhs); } 71 bool operator!=(const Address& rhs) const { return !(*this == rhs); } 72 IsEmpty()73 bool IsEmpty() const { return *this == kEmpty; } 74 75 // Converts |string| to Address and places it in |to|. If |from| does 76 // not represent a Bluetooth address, |to| is not modified and this function 77 // returns false. Otherwise, it returns true. 78 static bool FromString(const std::string& from, Address& to); 79 80 // Copies |from| raw Bluetooth address octets to the local object. 81 // Returns the number of copied octets - should be always Address::kLength 82 size_t FromOctets(const uint8_t* from); 83 84 static bool IsValidAddress(const std::string& address); 85 86 static const Address kEmpty; // 00:00:00:00:00:00 87 static const Address kAny; // FF:FF:FF:FF:FF:FF 88 private: 89 std::string _ToMaskedColonSepHexString(int bytes_to_mask) const; 90 }; 91 92 // TODO: to fine-tune this. 93 // we need an interface between the logger and ILoggable 94 inline std::ostream& operator<<(std::ostream& os, const Address& a) { 95 os << a.ToString(); 96 return os; 97 } 98 99 } // namespace hci 100 } // namespace bluetooth 101 102 namespace std { 103 template <> 104 struct hash<bluetooth::hci::Address> { 105 std::size_t operator()(const bluetooth::hci::Address& val) const { 106 static_assert(sizeof(uint64_t) >= bluetooth::hci::Address::kLength); 107 uint64_t int_addr = 0; 108 memcpy(reinterpret_cast<uint8_t*>(&int_addr), val.data(), bluetooth::hci::Address::kLength); 109 return std::hash<uint64_t>{}(int_addr); 110 } 111 }; 112 } // namespace std 113 114 #if __has_include(<bluetooth/log.h>) 115 #include <bluetooth/log.h> 116 117 namespace std { 118 template <> 119 struct formatter<bluetooth::hci::Address> : formatter<std::string> { 120 template <class Context> 121 typename Context::iterator format(const bluetooth::hci::Address& address, Context& ctx) const { 122 std::string repr = address.ToRedactedStringForLogging(); 123 return std::formatter<std::string>::format(repr, ctx); 124 } 125 }; 126 } // namespace std 127 128 #endif // __has_include(<bluetooth/log.h> 129