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 <string>
26 
27 #include "packet/custom_field_fixed_size_interface.h"
28 #include "storage/serializable.h"
29 
30 namespace bluetooth {
31 namespace hci {
32 
33 class Address final : public packet::CustomFieldFixedSizeInterface<Address>, public storage::Serializable<Address> {
34  public:
35   static constexpr size_t kLength = 6;
36 
37   std::array<uint8_t, kLength> address = {};
38 
39   Address() = default;
40   Address(const uint8_t (&addr)[kLength]);
41   Address(std::initializer_list<uint8_t> l);
42 
43   // CustomFieldFixedSizeInterface methods
data()44   inline uint8_t* data() override {
45     return address.data();
46   }
data()47   inline const uint8_t* data() const override {
48     return address.data();
49   }
50 
51   // storage::Serializable methods
52   std::string ToString() const override;
53   static std::optional<Address> FromString(const std::string& from);
54   std::string ToLegacyConfigString() const override;
55   static std::optional<Address> FromLegacyConfigString(const std::string& str);
56 
57   bool operator<(const Address& rhs) const {
58     return address < rhs.address;
59   }
60   bool operator==(const Address& rhs) const {
61     return address == rhs.address;
62   }
63   bool operator>(const Address& rhs) const {
64     return (rhs < *this);
65   }
66   bool operator<=(const Address& rhs) const {
67     return !(*this > rhs);
68   }
69   bool operator>=(const Address& rhs) const {
70     return !(*this < rhs);
71   }
72   bool operator!=(const Address& rhs) const {
73     return !(*this == rhs);
74   }
75 
IsEmpty()76   bool IsEmpty() const {
77     return *this == kEmpty;
78   }
79 
80   // Converts |string| to Address and places it in |to|. If |from| does
81   // not represent a Bluetooth address, |to| is not modified and this function
82   // returns false. Otherwise, it returns true.
83   static bool FromString(const std::string& from, Address& to);
84 
85   // Copies |from| raw Bluetooth address octets to the local object.
86   // Returns the number of copied octets - should be always Address::kLength
87   size_t FromOctets(const uint8_t* from);
88 
89   static bool IsValidAddress(const std::string& address);
90 
91   static const Address kEmpty;  // 00:00:00:00:00:00
92   static const Address kAny;    // FF:FF:FF:FF:FF:FF
93 };
94 
95 inline std::ostream& operator<<(std::ostream& os, const Address& a) {
96   os << a.ToString();
97   return os;
98 }
99 
100 }  // namespace hci
101 }  // namespace bluetooth
102 
103 namespace std {
104 template <>
105 struct hash<bluetooth::hci::Address> {
106   std::size_t operator()(const bluetooth::hci::Address& val) const {
107     static_assert(sizeof(uint64_t) >= bluetooth::hci::Address::kLength);
108     uint64_t int_addr = 0;
109     memcpy(reinterpret_cast<uint8_t*>(&int_addr), val.data(), bluetooth::hci::Address::kLength);
110     return std::hash<uint64_t>{}(int_addr);
111   }
112 };
113 }  // namespace std
114