2020-03-29 17:44:20 -06:00
|
|
|
/*
|
2024-12-12 19:21:03 -07:00
|
|
|
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
|
|
|
|
* esp-nimble-cpp, NimBLE-Arduino contributors.
|
2020-03-29 17:44:20 -06:00
|
|
|
*
|
2024-12-12 19:21:03 -07:00
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
2020-05-13 22:03:56 -06:00
|
|
|
*
|
2024-12-12 19:21:03 -07:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2020-03-29 17:44:20 -06:00
|
|
|
*
|
2024-12-12 19:21:03 -07:00
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-12-12 19:21:03 -07:00
|
|
|
|
2021-09-06 21:14:43 -06:00
|
|
|
#include "nimconfig.h"
|
2020-03-29 17:44:20 -06:00
|
|
|
#if defined(CONFIG_BT_ENABLED)
|
|
|
|
|
2024-07-04 19:17:13 -06:00
|
|
|
# include "NimBLEAddress.h"
|
|
|
|
# include "NimBLELog.h"
|
2020-05-10 07:21:46 -06:00
|
|
|
|
2024-07-04 19:17:13 -06:00
|
|
|
# include <algorithm>
|
2020-03-29 17:44:20 -06:00
|
|
|
|
2025-01-07 14:07:33 -05:00
|
|
|
# ifdef CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER
|
2025-01-06 14:13:02 -05:00
|
|
|
# define NIMBLE_CPP_ADDR_DELIMITER ""
|
2025-01-07 14:07:33 -05:00
|
|
|
# else
|
|
|
|
# define NIMBLE_CPP_ADDR_DELIMITER ":"
|
2025-01-06 14:13:02 -05:00
|
|
|
# endif
|
|
|
|
|
|
|
|
# ifdef CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE
|
|
|
|
# define NIMBLE_CPP_ADDR_FMT "%02X%s%02X%s%02X%s%02X%s%02X%s%02X"
|
|
|
|
# else
|
|
|
|
# define NIMBLE_CPP_ADDR_FMT "%02x%s%02x%s%02x%s%02x%s%02x%s%02x"
|
|
|
|
# endif
|
|
|
|
|
2020-05-10 07:21:46 -06:00
|
|
|
static const char* LOG_TAG = "NimBLEAddress";
|
2020-03-29 17:44:20 -06:00
|
|
|
|
|
|
|
/*************************************************
|
2020-07-08 19:27:26 -06:00
|
|
|
* NOTE: NimBLE address bytes are in INVERSE ORDER!
|
2024-07-04 19:17:13 -06:00
|
|
|
* We will accommodate that fact in these methods.
|
|
|
|
*************************************************/
|
2020-03-29 17:44:20 -06:00
|
|
|
|
|
|
|
/**
|
2020-07-08 19:27:26 -06:00
|
|
|
* @brief Create an address from the native NimBLE representation.
|
|
|
|
* @param [in] address The native NimBLE address.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-07-04 19:17:13 -06:00
|
|
|
NimBLEAddress::NimBLEAddress(ble_addr_t address) : ble_addr_t{address} {}
|
2020-03-29 17:44:20 -06:00
|
|
|
|
2020-09-02 14:52:34 -06:00
|
|
|
/**
|
2024-07-04 19:17:13 -06:00
|
|
|
* @brief Create an address from a hex string.
|
2020-03-29 17:44:20 -06:00
|
|
|
*
|
|
|
|
* A hex string is of the format:
|
|
|
|
* ```
|
|
|
|
* 00:00:00:00:00:00
|
|
|
|
* ```
|
|
|
|
* which is 17 characters in length.
|
2024-07-04 19:17:13 -06:00
|
|
|
* @param [in] addr The hex string representation of the address.
|
2024-12-14 13:11:36 -07:00
|
|
|
* @param [in] type The type of the address, should be one of:
|
|
|
|
* * BLE_ADDR_PUBLIC (0)
|
|
|
|
* * BLE_ADDR_RANDOM (1)
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-07-04 19:17:13 -06:00
|
|
|
NimBLEAddress::NimBLEAddress(const std::string& addr, uint8_t type) {
|
|
|
|
this->type = type;
|
2020-05-18 10:11:54 -06:00
|
|
|
|
2024-07-04 19:17:13 -06:00
|
|
|
if (addr.length() == BLE_DEV_ADDR_LEN) {
|
|
|
|
std::reverse_copy(addr.data(), addr.data() + BLE_DEV_ADDR_LEN, this->val);
|
2020-05-18 10:11:54 -06:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-07-04 19:17:13 -06:00
|
|
|
if (addr.length() == 17) {
|
|
|
|
std::string mac{addr};
|
|
|
|
mac.erase(std::remove(mac.begin(), mac.end(), ':'), mac.end());
|
2024-08-12 07:56:38 -06:00
|
|
|
uint64_t address = std::stoull(mac, nullptr, 16);
|
2025-01-10 10:15:29 -05:00
|
|
|
memcpy(this->val, &address, sizeof(this->val));
|
2020-05-10 07:21:46 -06:00
|
|
|
return;
|
|
|
|
}
|
2020-03-29 17:44:20 -06:00
|
|
|
|
2024-07-04 19:17:13 -06:00
|
|
|
*this = NimBLEAddress{};
|
|
|
|
NIMBLE_LOGE(LOG_TAG, "Invalid address '%s'", addr.c_str());
|
2020-07-08 19:27:26 -06:00
|
|
|
} // NimBLEAddress
|
2020-03-29 17:44:20 -06:00
|
|
|
|
|
|
|
/**
|
2020-07-08 19:27:26 -06:00
|
|
|
* @brief Constructor for compatibility with bluedroid esp library using native ESP representation.
|
|
|
|
* @param [in] address A uint8_t[6] or esp_bd_addr_t containing the address.
|
2024-12-14 13:11:36 -07:00
|
|
|
* @param [in] type The type of the address should be one of:
|
|
|
|
* * BLE_ADDR_PUBLIC (0)
|
|
|
|
* * BLE_ADDR_RANDOM (1)
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-07-04 19:17:13 -06:00
|
|
|
NimBLEAddress::NimBLEAddress(const uint8_t address[BLE_DEV_ADDR_LEN], uint8_t type) {
|
|
|
|
std::reverse_copy(address, address + BLE_DEV_ADDR_LEN, this->val);
|
|
|
|
this->type = type;
|
2020-05-10 07:21:46 -06:00
|
|
|
} // NimBLEAddress
|
|
|
|
|
|
|
|
/**
|
2020-07-08 19:27:26 -06:00
|
|
|
* @brief Constructor for address using a hex value.\n
|
|
|
|
* Use the same byte order, so use 0xa4c1385def16 for "a4:c1:38:5d:ef:16"
|
|
|
|
* @param [in] address uint64_t containing the address.
|
2024-12-14 13:11:36 -07:00
|
|
|
* @param [in] type The type of the address should be one of:
|
|
|
|
* * BLE_ADDR_PUBLIC (0)
|
|
|
|
* * BLE_ADDR_RANDOM (1)
|
2020-05-10 07:21:46 -06:00
|
|
|
*/
|
2024-07-04 19:17:13 -06:00
|
|
|
NimBLEAddress::NimBLEAddress(const uint64_t& address, uint8_t type) {
|
2025-01-10 10:15:29 -05:00
|
|
|
memcpy(this->val, &address, sizeof(this->val));
|
2024-07-04 19:17:13 -06:00
|
|
|
this->type = type;
|
2020-03-29 17:44:20 -06:00
|
|
|
} // NimBLEAddress
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Determine if this address equals another.
|
|
|
|
* @param [in] otherAddress The other address to compare against.
|
|
|
|
* @return True if the addresses are equal.
|
|
|
|
*/
|
2024-07-04 19:17:13 -06:00
|
|
|
bool NimBLEAddress::equals(const NimBLEAddress& otherAddress) const {
|
2020-05-10 07:21:46 -06:00
|
|
|
return *this == otherAddress;
|
2020-03-29 17:44:20 -06:00
|
|
|
} // equals
|
|
|
|
|
|
|
|
/**
|
2024-07-04 19:17:13 -06:00
|
|
|
* @brief Get the NimBLE base struct of the address.
|
|
|
|
* @return A read only reference to the NimBLE base struct of the address.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2024-07-04 19:17:13 -06:00
|
|
|
const ble_addr_t* NimBLEAddress::getBase() const {
|
|
|
|
return reinterpret_cast<const ble_addr_t*>(this);
|
|
|
|
} // getBase
|
2020-03-29 17:44:20 -06:00
|
|
|
|
2020-07-30 14:57:47 -06:00
|
|
|
/**
|
|
|
|
* @brief Get the address type.
|
|
|
|
* @return The address type.
|
|
|
|
*/
|
|
|
|
uint8_t NimBLEAddress::getType() const {
|
2024-07-04 19:17:13 -06:00
|
|
|
return this->type;
|
2020-07-30 14:57:47 -06:00
|
|
|
} // getType
|
|
|
|
|
2024-07-04 19:17:13 -06:00
|
|
|
/**
|
|
|
|
* @brief Get the address value.
|
|
|
|
* @return A read only reference to the address value.
|
|
|
|
*/
|
|
|
|
const uint8_t* NimBLEAddress::getVal() const {
|
|
|
|
return this->val;
|
|
|
|
} // getVal
|
2020-07-30 14:57:47 -06:00
|
|
|
|
2024-06-12 09:30:16 -06:00
|
|
|
/**
|
|
|
|
* @brief Determine if this address is a Resolvable Private Address.
|
|
|
|
* @return True if the address is a RPA.
|
|
|
|
*/
|
|
|
|
bool NimBLEAddress::isRpa() const {
|
2024-07-04 19:17:13 -06:00
|
|
|
return BLE_ADDR_IS_RPA(this);
|
2024-06-12 09:30:16 -06:00
|
|
|
} // isRpa
|
|
|
|
|
2024-07-04 19:17:13 -06:00
|
|
|
/**
|
|
|
|
* @brief Determine if this address is a Non-Resolvable Private Address.
|
|
|
|
* @return True if the address is a NRPA.
|
|
|
|
*/
|
|
|
|
bool NimBLEAddress::isNrpa() const {
|
|
|
|
return BLE_ADDR_IS_NRPA(this);
|
|
|
|
} // isNrpa
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Determine if this address is a Static Address.
|
|
|
|
* @return True if the address is a Static Address.
|
|
|
|
*/
|
|
|
|
bool NimBLEAddress::isStatic() const {
|
|
|
|
return BLE_ADDR_IS_STATIC(this);
|
|
|
|
} // isStatic
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Determine if this address is a Public Address.
|
|
|
|
* @return True if the address is a Public Address.
|
|
|
|
*/
|
|
|
|
bool NimBLEAddress::isPublic() const {
|
|
|
|
return this->type == BLE_ADDR_PUBLIC;
|
|
|
|
} // isPublic
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Determine if this address is a NULL Address.
|
|
|
|
* @return True if the address is a NULL Address.
|
|
|
|
*/
|
|
|
|
bool NimBLEAddress::isNull() const {
|
|
|
|
return *this == NimBLEAddress{};
|
|
|
|
} // isNull
|
2024-06-12 09:30:16 -06:00
|
|
|
|
2020-03-29 17:44:20 -06:00
|
|
|
/**
|
|
|
|
* @brief Convert a BLE address to a string.
|
|
|
|
* @return The string representation of the address.
|
2020-07-08 19:27:26 -06:00
|
|
|
* @deprecated Use std::string() operator instead.
|
2020-03-29 17:44:20 -06:00
|
|
|
*/
|
2020-05-10 07:21:46 -06:00
|
|
|
std::string NimBLEAddress::toString() const {
|
|
|
|
return std::string(*this);
|
2020-03-29 17:44:20 -06:00
|
|
|
} // toString
|
2020-05-10 07:21:46 -06:00
|
|
|
|
2024-07-04 19:17:13 -06:00
|
|
|
/**
|
|
|
|
* @brief Reverse the byte order of the address.
|
|
|
|
* @return A reference to this address.
|
|
|
|
*/
|
|
|
|
const NimBLEAddress& NimBLEAddress::reverseByteOrder() {
|
|
|
|
std::reverse(this->val, this->val + BLE_DEV_ADDR_LEN);
|
|
|
|
return *this;
|
|
|
|
} // reverseByteOrder
|
2020-05-10 07:21:46 -06:00
|
|
|
|
2020-07-08 19:27:26 -06:00
|
|
|
/**
|
2022-07-31 11:00:12 -06:00
|
|
|
* @brief Convenience operator to check if this address is equal to another.
|
2020-07-08 19:27:26 -06:00
|
|
|
*/
|
2024-07-04 19:17:13 -06:00
|
|
|
bool NimBLEAddress::operator==(const NimBLEAddress& rhs) const {
|
|
|
|
if (this->type != rhs.type) {
|
|
|
|
return false;
|
|
|
|
}
|
2020-05-10 07:21:46 -06:00
|
|
|
|
2025-01-10 10:15:29 -05:00
|
|
|
return memcmp(rhs.val, this->val, sizeof(this->val)) == 0;
|
2024-07-04 19:17:13 -06:00
|
|
|
} // operator ==
|
2020-07-08 19:27:26 -06:00
|
|
|
|
|
|
|
/**
|
2022-07-31 11:00:12 -06:00
|
|
|
* @brief Convenience operator to check if this address is not equal to another.
|
2020-07-08 19:27:26 -06:00
|
|
|
*/
|
2024-07-04 19:17:13 -06:00
|
|
|
bool NimBLEAddress::operator!=(const NimBLEAddress& rhs) const {
|
2020-05-10 07:21:46 -06:00
|
|
|
return !this->operator==(rhs);
|
2020-07-08 19:27:26 -06:00
|
|
|
} // operator !=
|
2020-05-10 07:21:46 -06:00
|
|
|
|
2020-07-08 19:27:26 -06:00
|
|
|
/**
|
2024-07-04 19:17:13 -06:00
|
|
|
* @brief Convenience operator to convert this address to string representation.
|
|
|
|
* @details This allows passing NimBLEAddress to functions that accept std::string and/or it's methods as a parameter.
|
2020-07-08 19:27:26 -06:00
|
|
|
*/
|
2020-05-10 07:21:46 -06:00
|
|
|
NimBLEAddress::operator std::string() const {
|
2020-08-03 07:33:11 -06:00
|
|
|
char buffer[18];
|
2024-07-04 19:17:13 -06:00
|
|
|
snprintf(buffer,
|
|
|
|
sizeof(buffer),
|
2025-01-06 14:13:02 -05:00
|
|
|
NIMBLE_CPP_ADDR_FMT,
|
|
|
|
this->val[5], NIMBLE_CPP_ADDR_DELIMITER,
|
|
|
|
this->val[4], NIMBLE_CPP_ADDR_DELIMITER,
|
|
|
|
this->val[3], NIMBLE_CPP_ADDR_DELIMITER,
|
|
|
|
this->val[2], NIMBLE_CPP_ADDR_DELIMITER,
|
|
|
|
this->val[1], NIMBLE_CPP_ADDR_DELIMITER,
|
2024-07-04 19:17:13 -06:00
|
|
|
this->val[0]);
|
|
|
|
return std::string{buffer};
|
2020-07-08 19:27:26 -06:00
|
|
|
} // operator std::string
|
2020-05-10 07:21:46 -06:00
|
|
|
|
2020-07-08 19:27:26 -06:00
|
|
|
/**
|
2022-07-31 11:00:12 -06:00
|
|
|
* @brief Convenience operator to convert the native address representation to uint_64.
|
2020-07-08 19:27:26 -06:00
|
|
|
*/
|
2020-06-19 12:32:57 -06:00
|
|
|
NimBLEAddress::operator uint64_t() const {
|
|
|
|
uint64_t address = 0;
|
2025-01-10 10:15:29 -05:00
|
|
|
memcpy(&address, this->val, sizeof(this->val));
|
2020-06-19 12:32:57 -06:00
|
|
|
return address;
|
2020-07-08 19:27:26 -06:00
|
|
|
} // operator uint64_t
|
2020-06-19 12:32:57 -06:00
|
|
|
|
2020-03-29 17:44:20 -06:00
|
|
|
#endif
|