mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-15 07:06:11 -04:00
Create MacAddress class for MAC address manipulation.
PiperOrigin-RevId: 752503841
This commit is contained in:
committed by
Copybara-Service
parent
422030f826
commit
83ec6bcece
@@ -524,6 +524,7 @@ let package = Package(
|
||||
"internal/platform/bluetooth_utils_test.cc",
|
||||
"internal/platform/credential_storage_impl_test.cc",
|
||||
"internal/platform/input_stream_test.cc",
|
||||
"internal/platform/mac_address_test.cc",
|
||||
"internal/platform/single_thread_executor_test.cc",
|
||||
"internal/platform/scheduled_executor_test.cc",
|
||||
"internal/platform/stream_reader_test.cc",
|
||||
|
||||
@@ -347,6 +347,21 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "mac_address",
|
||||
srcs = ["mac_address.cc"],
|
||||
hdrs = ["mac_address.h"],
|
||||
compatible_with = ["//buildenv/target:non_prod"],
|
||||
visibility = [
|
||||
"//:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
":logging",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/strings:str_format",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "test_util",
|
||||
testonly = True,
|
||||
@@ -570,3 +585,13 @@ cc_test(
|
||||
],
|
||||
}),
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "mac_address_test",
|
||||
srcs = ["mac_address_test.cc"],
|
||||
deps = [
|
||||
":mac_address",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -251,6 +251,7 @@ cc_library(
|
||||
"//internal/platform:base",
|
||||
"//internal/platform:cancellation_flag",
|
||||
"//internal/platform:logging",
|
||||
"//internal/platform:mac_address",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform:uuid",
|
||||
"//internal/platform/flags:platform_flags",
|
||||
|
||||
@@ -13,51 +13,26 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/platform/implementation/windows/ble_v2_peripheral.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/bluetooth_utils.h"
|
||||
#include "internal/platform/logging.h"
|
||||
#include "internal/platform/mac_address.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
namespace {
|
||||
constexpr int kMacAddressLength = 17;
|
||||
}
|
||||
|
||||
BleV2Peripheral::BleV2Peripheral(absl::string_view address) {
|
||||
if (SetAddress(address)) {
|
||||
unique_id_ = static_cast<UniqueId>(BluetoothUtils::ToNumber(address));
|
||||
if (!MacAddress::FromString(address, mac_address_)) {
|
||||
LOG(WARNING) << "Create BleV2Peripheral with invalid MAC: " << address;
|
||||
}
|
||||
}
|
||||
|
||||
bool BleV2Peripheral::SetAddress(absl::string_view address) {
|
||||
// The address must be in format "00:B0:D0:63:C2:26".
|
||||
if (address.size() != kMacAddressLength) {
|
||||
LOG(ERROR) << ": Invalid MAC address length.";
|
||||
return false;
|
||||
std::string BleV2Peripheral::GetAddress() const {
|
||||
if (mac_address_.IsSet()) {
|
||||
return mac_address_.ToString();
|
||||
}
|
||||
|
||||
for (int i = 0; i < kMacAddressLength; ++i) {
|
||||
if ((i % 3) == 0 || (i % 3) == 1) {
|
||||
if ((address[i] >= '0' && address[i] <= '9') ||
|
||||
(address[i] >= 'a' && address[i] <= 'f') ||
|
||||
(address[i] >= 'A' && address[i] <= 'F')) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (address[i] == ':') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
LOG(ERROR) << ": Invalid MAC address format.";
|
||||
return false;
|
||||
}
|
||||
|
||||
address_ = std::string(address);
|
||||
return true;
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace windows
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/platform/implementation/ble_v2.h"
|
||||
#include "internal/platform/mac_address.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
@@ -31,21 +32,17 @@ class BleV2Peripheral : public api::ble_v2::BlePeripheral {
|
||||
explicit BleV2Peripheral(absl::string_view address);
|
||||
~BleV2Peripheral() override = default;
|
||||
|
||||
// Returns the MAC address of the peripheral. The format is in
|
||||
// Returns the MAC address of the peripheral or empty string. The format is in
|
||||
// "00:B0:D0:63:C2:26".
|
||||
std::string GetAddress() const override { return address_; }
|
||||
std::string GetAddress() const override;
|
||||
|
||||
UniqueId GetUniqueId() const override { return unique_id_; }
|
||||
// Sets the MAC address of the peripheral. The address format must be in
|
||||
// pattern of "00:B0:D0:63:C2:26".
|
||||
bool SetAddress(absl::string_view address);
|
||||
UniqueId GetUniqueId() const override { return mac_address_.address(); }
|
||||
|
||||
bool Ok() const { return unique_id_ != 0; }
|
||||
bool Ok() const { return mac_address_.IsSet(); }
|
||||
explicit operator bool() const { return Ok(); }
|
||||
|
||||
private:
|
||||
std::string address_;
|
||||
UniqueId unique_id_ = 0;
|
||||
MacAddress mac_address_;
|
||||
};
|
||||
|
||||
} // namespace windows
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "internal/platform/implementation/windows/ble_v2_peripheral.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace windows {
|
||||
@@ -26,38 +27,10 @@ TEST(BleV2Peripheral, Constructor) {
|
||||
|
||||
EXPECT_TRUE(ble_peripheral);
|
||||
EXPECT_TRUE(ble_peripheral.Ok());
|
||||
EXPECT_NE(ble_peripheral.GetUniqueId(), 0);
|
||||
EXPECT_EQ(ble_peripheral.GetUniqueId(), 0xf1f2f3f4f5f6);
|
||||
EXPECT_EQ(ble_peripheral.GetAddress(), kAddress);
|
||||
}
|
||||
|
||||
TEST(BleV2Peripheral, SetMacAddress) {
|
||||
BleV2Peripheral ble_peripheral("F1:F2:F3:F4:F5:F6");
|
||||
EXPECT_TRUE(ble_peripheral.SetAddress("00:B0:D0:63:C2:26"));
|
||||
EXPECT_FALSE(ble_peripheral.SetAddress("00:B0:D0:6T:C2:26"));
|
||||
EXPECT_FALSE(ble_peripheral.SetAddress("00:B0:D0:63:C2:2"));
|
||||
EXPECT_FALSE(ble_peripheral.SetAddress("0:B0:D0:63:C2:203"));
|
||||
EXPECT_FALSE(ble_peripheral.SetAddress("0:B0:D0:6P:C2:203"));
|
||||
}
|
||||
|
||||
TEST(BleV2Peripheral, SetAndGetMacAddress) {
|
||||
constexpr absl::string_view kChangedAddress = "00:B0:D0:63:C2:26";
|
||||
BleV2Peripheral ble_peripheral("F1:F2:F3:F4:F5:F6");
|
||||
|
||||
EXPECT_TRUE(ble_peripheral.SetAddress(kChangedAddress));
|
||||
EXPECT_EQ(ble_peripheral.GetAddress(), kChangedAddress);
|
||||
}
|
||||
|
||||
TEST(BleV2Peripheral, SetAddressDoesNotChangeUniqueId) {
|
||||
constexpr absl::string_view kChangedAddress = "00:B0:D0:63:C2:26";
|
||||
BleV2Peripheral ble_peripheral("F1:F2:F3:F4:F5:F6");
|
||||
BleV2Peripheral::UniqueId unique_id = ble_peripheral.GetUniqueId();
|
||||
|
||||
EXPECT_NE(unique_id, 0);
|
||||
EXPECT_TRUE(ble_peripheral.SetAddress(kChangedAddress));
|
||||
EXPECT_EQ(ble_peripheral.GetAddress(), kChangedAddress);
|
||||
EXPECT_EQ(ble_peripheral.GetUniqueId(), unique_id);
|
||||
}
|
||||
|
||||
TEST(BleV2Peripheral, ConstructFromBadAddress) {
|
||||
BleV2Peripheral ble_peripheral("G1:F2:F3:F4:F5:F6");
|
||||
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include "internal/platform/mac_address.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
bool MacAddress::FromString(absl::string_view address,
|
||||
MacAddress& mac_address) {
|
||||
if (address.length() != 17) {
|
||||
return false;
|
||||
}
|
||||
uint64_t address_int = 0;
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
// Check for ":" separator.
|
||||
if (i < 5 && address[i * 3 + 2] != ':') {
|
||||
return false;
|
||||
}
|
||||
absl::string_view component;
|
||||
component = address.substr(i * 3, 2);
|
||||
uint64_t component_int = 0;
|
||||
if (!absl::SimpleHexAtoi(component, &component_int)) {
|
||||
return false;
|
||||
}
|
||||
address_int = (address_int << 8) | component_int;
|
||||
}
|
||||
mac_address.address_ = address_int;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MacAddress::FromUint64(uint64_t address, MacAddress& mac_address) {
|
||||
if ((address & 0xffff000000000000L) != 0) {
|
||||
return false;
|
||||
}
|
||||
mac_address.address_ = address;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string MacAddress::ToString() const {
|
||||
return absl::StrCat(absl::StrFormat("%02X", (address_ >> 40) & 0xff), ":",
|
||||
absl::StrFormat("%02X", (address_ >> 32) & 0xff), ":",
|
||||
absl::StrFormat("%02X", (address_ >> 24) & 0xff), ":",
|
||||
absl::StrFormat("%02X", (address_ >> 16) & 0xff), ":",
|
||||
absl::StrFormat("%02X", (address_ >> 8) & 0xff), ":",
|
||||
absl::StrFormat("%02X", address_ & 0xff));
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// 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.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_MAC_ADDRESS_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_MAC_ADDRESS_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
// Representation of a 48 bit MAC address.
|
||||
class MacAddress {
|
||||
public:
|
||||
// Creates an empty MAC address with all 0s.
|
||||
MacAddress() = default;
|
||||
|
||||
// Creates a MAC address from a string.
|
||||
// Returns false if the string is not a valid MAC address.
|
||||
static bool FromString(absl::string_view address, MacAddress& mac_address);
|
||||
|
||||
// Creates a MAC address from a 64-bit integer.
|
||||
// The upper 16 bits of the address must be 0.
|
||||
// Returns false if the integer is not a valid MAC address.
|
||||
static bool FromUint64(uint64_t address, MacAddress& mac_address);
|
||||
|
||||
// Packs the MAC address into the lower 48 bits of a 64-bit integer.
|
||||
uint64_t address() const { return address_; }
|
||||
|
||||
// Returns the MAC address in the format of "00:B0:D0:63:C2:26".
|
||||
std::string ToString() const;
|
||||
|
||||
// Returns true if the MAC address is set.
|
||||
bool IsSet() const { return address_ != 0; }
|
||||
|
||||
private:
|
||||
uint64_t address_ = 0;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_MAC_ADDRESS_H_
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// 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.
|
||||
|
||||
#include "internal/platform/mac_address.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
|
||||
TEST(MacAddressTest, FromStringSuccess) {
|
||||
MacAddress mac_address;
|
||||
EXPECT_TRUE(MacAddress::FromString("00:B0:D0:63:C2:26", mac_address));
|
||||
EXPECT_EQ(mac_address.address(), 0x00B0D063C226);
|
||||
EXPECT_EQ(mac_address.ToString(), "00:B0:D0:63:C2:26");
|
||||
}
|
||||
|
||||
TEST(MacAddressTest, FromStringMissingSeparator) {
|
||||
MacAddress mac_address;
|
||||
EXPECT_FALSE(MacAddress::FromString("00:B0:D0,63:C2:26", mac_address));
|
||||
EXPECT_EQ(mac_address.address(), 0);
|
||||
}
|
||||
|
||||
TEST(MacAddressTest, FromStringInvalidHex) {
|
||||
MacAddress mac_address;
|
||||
EXPECT_FALSE(MacAddress::FromString("01:BG:D0,63:C2:26", mac_address));
|
||||
EXPECT_EQ(mac_address.address(), 0);
|
||||
}
|
||||
|
||||
TEST(MacAddressTest, FromStringInvalidLength) {
|
||||
MacAddress mac_address;
|
||||
EXPECT_FALSE(MacAddress::FromString("01:BG:D0,63:C2:1", mac_address));
|
||||
EXPECT_EQ(mac_address.address(), 0);
|
||||
}
|
||||
|
||||
TEST(MacAddressTest, FromUint64Success) {
|
||||
MacAddress mac_address;
|
||||
EXPECT_TRUE(MacAddress::FromUint64(0x00B0D063C226, mac_address));
|
||||
EXPECT_EQ(mac_address.address(), 0x00B0D063C226);
|
||||
}
|
||||
|
||||
TEST(MacAddressTest, FromUint64InvalidAddresss) {
|
||||
MacAddress mac_address;
|
||||
EXPECT_FALSE(MacAddress::FromUint64(0x0100B0D063C226, mac_address));
|
||||
EXPECT_EQ(mac_address.address(), 0);
|
||||
}
|
||||
|
||||
TEST(MacAddressTest, IsSetTrue) {
|
||||
MacAddress mac_address;
|
||||
EXPECT_TRUE(MacAddress::FromUint64(0x00B0D063C226, mac_address));
|
||||
EXPECT_TRUE(mac_address.IsSet());
|
||||
}
|
||||
|
||||
|
||||
TEST(MacAddressTest, IsSetFalse) {
|
||||
MacAddress mac_address;
|
||||
EXPECT_FALSE(mac_address.IsSet());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby
|
||||
Reference in New Issue
Block a user