mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
@@ -15,6 +15,7 @@ cc_library(
|
||||
"exception.h",
|
||||
"input_stream.h",
|
||||
"listeners.h",
|
||||
"nsd_service_info.h",
|
||||
"output_stream.h",
|
||||
"payload_id.h",
|
||||
"prng.h",
|
||||
@@ -29,6 +30,7 @@ cc_library(
|
||||
"//platform/api:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//absl/container:flat_hash_map",
|
||||
"//absl/meta:type_traits",
|
||||
"//absl/strings",
|
||||
"//absl/strings:str_format",
|
||||
@@ -41,11 +43,13 @@ cc_library(
|
||||
srcs = [
|
||||
"base_input_stream.cc",
|
||||
"base_pipe.cc",
|
||||
"byte_utils.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"base_input_stream.h",
|
||||
"base_mutex_lock.h",
|
||||
"base_pipe.h",
|
||||
"byte_utils.h",
|
||||
],
|
||||
visibility = [
|
||||
"//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__",
|
||||
@@ -57,6 +61,7 @@ cc_library(
|
||||
":base",
|
||||
"//platform/api:types",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/strings:str_format",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -112,6 +117,18 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "platform_util_test",
|
||||
srcs = [
|
||||
"byte_utils_test.cc",
|
||||
],
|
||||
deps = [
|
||||
":base",
|
||||
":util",
|
||||
"//testing/base/public:gunit_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_with_non_compile_test(
|
||||
name = "exception_test",
|
||||
srcs = [
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "platform/base/byte_utils.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "platform/base/base_input_stream.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
std::string ByteUtils::ToFourDigitString(ByteArray& bytes) {
|
||||
int multiplier = 1;
|
||||
int hashCode = 0;
|
||||
|
||||
BaseInputStream base_input_stream{bytes};
|
||||
while (base_input_stream.IsAvailable(1)) {
|
||||
auto byte = static_cast<int>(base_input_stream.ReadUint8());
|
||||
hashCode = (hashCode + byte * multiplier) % kHashBasePrime;
|
||||
multiplier = multiplier * kHashBaseMultiplier % kHashBasePrime;
|
||||
}
|
||||
return absl::StrFormat("%04d", abs(hashCode));
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef PLATFORM_BASE_BYTE_UTILS_H_
|
||||
#define PLATFORM_BASE_BYTE_UTILS_H_
|
||||
|
||||
#include "platform/base/byte_array.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
class ByteUtils {
|
||||
public:
|
||||
static std::string ToFourDigitString(ByteArray& bytes);
|
||||
|
||||
private:
|
||||
// The biggest prime number under 10000, used as a mod base to trim integers
|
||||
// into 4 digits.
|
||||
static constexpr int kHashBasePrime = 9973;
|
||||
// The hash multiplier.
|
||||
static constexpr int kHashBaseMultiplier = 31;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_BASE_BYTE_UTILS_H_
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "platform/base/byte_utils.h"
|
||||
|
||||
#include "platform/base/byte_array.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
constexpr absl::string_view kFooBytes{"rawABCDE"};
|
||||
constexpr absl::string_view kFooFourDigitsToken{"0392"};
|
||||
constexpr absl::string_view kEmptyFourDigitsToken{"0000"};
|
||||
|
||||
TEST(ByteUtilsTest, ToFourDigitStringCorrect) {
|
||||
ByteArray bytes{std::string(kFooBytes)};
|
||||
|
||||
auto four_digit_string = ByteUtils::ToFourDigitString(bytes);
|
||||
|
||||
EXPECT_EQ(std::string(kFooFourDigitsToken), four_digit_string);
|
||||
}
|
||||
|
||||
TEST(ByteUtilsTest, TestEmptyByteArrayCorrect) {
|
||||
ByteArray bytes;
|
||||
|
||||
auto four_digit_string = ByteUtils::ToFourDigitString(bytes);
|
||||
|
||||
EXPECT_EQ(std::string(kEmptyFourDigitsToken), four_digit_string);
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -201,28 +201,32 @@ void MediumEnvironment::OnBlePeripheralStateChanged(
|
||||
}
|
||||
|
||||
void MediumEnvironment::OnWifiLanServiceStateChanged(
|
||||
WifiLanMediumContext& info, api::WifiLanService& service,
|
||||
WifiLanMediumContext& info, api::WifiLanService& wifi_lan_service,
|
||||
const std::string& service_id, bool enabled) {
|
||||
if (!enabled_) return;
|
||||
NEARBY_LOG(INFO,
|
||||
"G3 OnWifiLanServiceStateChanged [service impl=%p]; context=%p; "
|
||||
"service_id=%s; notify=%d",
|
||||
&service, &info, service_id.c_str(), enable_notifications_.load());
|
||||
NEARBY_LOG(
|
||||
INFO,
|
||||
"G3 OnWifiLanServiceStateChanged [wifi_lan_service impl=%p]; context=%p; "
|
||||
"service_id=%s; notify=%d",
|
||||
&wifi_lan_service, &info, service_id.c_str(),
|
||||
enable_notifications_.load());
|
||||
if (!enable_notifications_) return;
|
||||
RunOnMediumEnvironmentThread([&info, enabled, &service, service_id]() {
|
||||
NEARBY_LOG(INFO,
|
||||
"G3 [Run] OnWifiLanServiceStateChanged [service impl=%p]; "
|
||||
"context=%p; service_id=%s; enabled=%d",
|
||||
&service, &info, service_id.c_str(), enabled);
|
||||
RunOnMediumEnvironmentThread([&info, enabled, &wifi_lan_service,
|
||||
service_id]() {
|
||||
NEARBY_LOG(
|
||||
INFO,
|
||||
"G3 [Run] OnWifiLanServiceStateChanged [wifi_lan_service impl=%p]; "
|
||||
"context=%p; service_id=%s; enabled=%d",
|
||||
&wifi_lan_service, &info, service_id.c_str(), enabled);
|
||||
auto service_id_context = info.services.find(service_id);
|
||||
if (service_id_context == info.services.end()) return;
|
||||
|
||||
if (enabled) {
|
||||
service_id_context->second.discovery_callback.service_discovered_cb(
|
||||
service, service_id);
|
||||
wifi_lan_service, service_id);
|
||||
} else {
|
||||
service_id_context->second.discovery_callback.service_lost_cb(service,
|
||||
service_id);
|
||||
service_id_context->second.discovery_callback.service_lost_cb(
|
||||
wifi_lan_service, service_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -477,10 +481,10 @@ void MediumEnvironment::RegisterWifiLanMedium(api::WifiLanMedium& medium) {
|
||||
}
|
||||
|
||||
void MediumEnvironment::UpdateWifiLanMediumForAdvertising(
|
||||
api::WifiLanMedium& medium, api::WifiLanService& service,
|
||||
api::WifiLanMedium& medium, api::WifiLanService& wifi_lan_service,
|
||||
const std::string& service_id, bool enabled) {
|
||||
if (!enabled_) return;
|
||||
RunOnMediumEnvironmentThread([this, &medium, &service, service_id,
|
||||
RunOnMediumEnvironmentThread([this, &medium, &wifi_lan_service, service_id,
|
||||
enabled]() {
|
||||
auto item = wifi_lan_mediums_.find(&medium);
|
||||
if (item == wifi_lan_mediums_.end()) {
|
||||
@@ -490,7 +494,7 @@ void MediumEnvironment::UpdateWifiLanMediumForAdvertising(
|
||||
return;
|
||||
}
|
||||
auto& context = item->second;
|
||||
context.wifi_lan_service = &service;
|
||||
context.wifi_lan_service = &wifi_lan_service;
|
||||
auto service_id_context = context.services.find(service_id);
|
||||
if (service_id_context == context.services.end()) {
|
||||
WifiLanServiceIdContext id_context{
|
||||
@@ -500,17 +504,19 @@ void MediumEnvironment::UpdateWifiLanMediumForAdvertising(
|
||||
} else {
|
||||
service_id_context->second.advertising = enabled;
|
||||
}
|
||||
NEARBY_LOG(INFO,
|
||||
"Update WifiLan medium for advertising: this=%p; medium=%p; "
|
||||
"service_id=%s; name=%s; enabled=%d",
|
||||
this, &medium, service_id.c_str(),
|
||||
service.GetServiceName().c_str(), enabled);
|
||||
NEARBY_LOG(
|
||||
INFO,
|
||||
"Update WifiLan medium for advertising: this=%p; medium=%p; "
|
||||
"service_id=%s; wifi_lan_service=%p, service_info_name=%s; enabled=%d",
|
||||
this, &medium, service_id.c_str(), &wifi_lan_service,
|
||||
wifi_lan_service.GetServiceInfo().GetServiceInfoName().c_str(),
|
||||
enabled);
|
||||
for (auto& medium_info : wifi_lan_mediums_) {
|
||||
auto& local_medium = medium_info.first;
|
||||
auto& info = medium_info.second;
|
||||
// Do not send notification to the same medium.
|
||||
if (local_medium == &medium) continue;
|
||||
OnWifiLanServiceStateChanged(info, service, service_id, enabled);
|
||||
OnWifiLanServiceStateChanged(info, wifi_lan_service, service_id, enabled);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -620,25 +626,26 @@ void MediumEnvironment::CallWifiLanAcceptedConnectionCallback(
|
||||
});
|
||||
}
|
||||
|
||||
api::WifiLanService* MediumEnvironment::FindWifiLanService(
|
||||
api::WifiLanService* MediumEnvironment::GetWifiLanService(
|
||||
const std::string& ip_address, int port) {
|
||||
api::WifiLanService* remote_service = nullptr;
|
||||
api::WifiLanService* remote_wifi_lan_service = nullptr;
|
||||
CountDownLatch latch(1);
|
||||
RunOnMediumEnvironmentThread(
|
||||
[this, &remote_service, &ip_address, port, &latch]() {
|
||||
[this, &remote_wifi_lan_service, &ip_address, port, &latch]() {
|
||||
for (auto& item : wifi_lan_mediums_) {
|
||||
auto* service = item.second.wifi_lan_service;
|
||||
if (!service) continue;
|
||||
auto addr = remote_service->GetServiceAddress();
|
||||
auto* wifi_lan_service = item.second.wifi_lan_service;
|
||||
if (!wifi_lan_service) continue;
|
||||
auto addr =
|
||||
remote_wifi_lan_service->GetServiceInfo().GetServiceAddress();
|
||||
if (addr.first == ip_address && addr.second == port) {
|
||||
remote_service = service;
|
||||
remote_wifi_lan_service = wifi_lan_service;
|
||||
break;
|
||||
}
|
||||
}
|
||||
latch.CountDown();
|
||||
});
|
||||
latch.Await();
|
||||
return remote_service;
|
||||
return remote_wifi_lan_service;
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "platform/api/webrtc.h"
|
||||
#include "platform/base/byte_array.h"
|
||||
#include "platform/base/listeners.h"
|
||||
#include "platform/base/nsd_service_info.h"
|
||||
#include "platform/public/single_thread_executor.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
@@ -179,7 +180,7 @@ class MediumEnvironment {
|
||||
// Updates advertising info to indicate the current medium is exposing
|
||||
// advertising event.
|
||||
void UpdateWifiLanMediumForAdvertising(api::WifiLanMedium& medium,
|
||||
api::WifiLanService& service,
|
||||
api::WifiLanService& wifi_lan_service,
|
||||
const std::string& service_id,
|
||||
bool enabled);
|
||||
|
||||
@@ -212,8 +213,8 @@ class MediumEnvironment {
|
||||
const std::string& service_id);
|
||||
|
||||
// Returns WiFi LAN service matching IP address and port, or nullptr.
|
||||
api::WifiLanService* FindWifiLanService(const std::string& ip_address,
|
||||
int port);
|
||||
api::WifiLanService* GetWifiLanService(const std::string& ip_address,
|
||||
int port);
|
||||
|
||||
private:
|
||||
struct BluetoothMediumContext {
|
||||
@@ -261,7 +262,7 @@ class MediumEnvironment {
|
||||
bool fast_advertisement, bool enabled);
|
||||
|
||||
void OnWifiLanServiceStateChanged(WifiLanMediumContext& info,
|
||||
api::WifiLanService& service,
|
||||
api::WifiLanService& wifi_lan_service,
|
||||
const std::string& service_id,
|
||||
bool enabled);
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef PLATFORM_BASE_NSD_SERVICE_INFO_H_
|
||||
#define PLATFORM_BASE_NSD_SERVICE_INFO_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
// https://developer.android.com/reference/android/net/nsd/NsdServiceInfo.html.
|
||||
class NsdServiceInfo {
|
||||
public:
|
||||
NsdServiceInfo() = default;
|
||||
NsdServiceInfo(const NsdServiceInfo&) = default;
|
||||
NsdServiceInfo& operator=(const NsdServiceInfo&) = default;
|
||||
NsdServiceInfo(NsdServiceInfo&&) = default;
|
||||
NsdServiceInfo& operator=(NsdServiceInfo&&) = default;
|
||||
~NsdServiceInfo() = default;
|
||||
|
||||
// Returns the packed string of |WifiLanServiceInfo|.
|
||||
std::string GetServiceInfoName() const { return service_info_name_; }
|
||||
|
||||
// Sets the packed string of |WifiLanServiceInfo|.
|
||||
void SetServiceInfoName(std::string service_info_name) {
|
||||
service_info_name_ = std::move(service_info_name);
|
||||
}
|
||||
|
||||
// Gets the TXTRecord value of the specified TXTRecord key assigned.
|
||||
std::string GetTxtRecord(const std::string& txt_record_key) const {
|
||||
if (txt_records_.empty()) return {};
|
||||
auto record = txt_records_.find(txt_record_key);
|
||||
if (record == txt_records_.end()) return {};
|
||||
return record->second;
|
||||
}
|
||||
|
||||
// Adds the TXTRecord with a pair of key and value.
|
||||
void SetTxtRecord(const std::string& txt_record_key,
|
||||
const std::string& txt_record_value) {
|
||||
txt_records_.emplace(txt_record_key, txt_record_value);
|
||||
}
|
||||
|
||||
// Returns the advertising device's <IP address, port> as a pair.
|
||||
// IP address is in byte sequence, in network order.
|
||||
std::pair<std::string, int> GetServiceAddress() const {
|
||||
return std::make_pair(ip_address_, port_);
|
||||
}
|
||||
|
||||
// Sets the ip address and port of the local device.
|
||||
void SetServiceAddress(const std::string& ip_address, int port) {
|
||||
ip_address_ = ip_address;
|
||||
port_ = port;
|
||||
}
|
||||
|
||||
bool IsValid() const { return !service_info_name_.empty(); }
|
||||
|
||||
private:
|
||||
std::string service_info_name_;
|
||||
absl::flat_hash_map<std::string, std::string> txt_records_;
|
||||
std::string ip_address_;
|
||||
int port_;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // PLATFORM_BASE_NSD_SERVICE_INFO_H_
|
||||
Reference in New Issue
Block a user