• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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