mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
nearby: snapshot of cl/304428753
Signed-off-by: Alexey Polyudov <apolyudov@google.com> Change-Id: I0023ac6e40456fc4a8169c3173bcbff3b5ccc476
This commit is contained in:
+39
-1
@@ -8,7 +8,7 @@ cc_library(
|
||||
"loop_runner.cc",
|
||||
"loop_runner.h",
|
||||
"offline_frames.cc",
|
||||
"offline_frames.h",
|
||||
"wifi_lan_service_info.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"bandwidth_upgrade_handler.h",
|
||||
@@ -40,6 +40,7 @@ cc_library(
|
||||
"internal_payload_factory.h",
|
||||
"medium_manager.cc",
|
||||
"medium_manager.h",
|
||||
"offline_frames.h",
|
||||
"offline_service_controller.cc",
|
||||
"offline_service_controller.h",
|
||||
"p2p_cluster_pcp_handler.cc",
|
||||
@@ -57,6 +58,7 @@ cc_library(
|
||||
"service_controller.h",
|
||||
"service_controller_router.cc",
|
||||
"service_controller_router.h",
|
||||
"wifi_lan_service_info.h",
|
||||
"wifi_lan_upgrade_handler.cc",
|
||||
"wifi_lan_upgrade_handler.h",
|
||||
],
|
||||
@@ -80,6 +82,18 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "base_endpoint_channel_test",
|
||||
srcs = ["base_endpoint_channel_test.cc"],
|
||||
deps = [
|
||||
":internal",
|
||||
"//platform:utils",
|
||||
"//platform/impl/default",
|
||||
"//proto:connections_enums_portable_proto",
|
||||
"//testing/base/public:gunit_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "bluetooth_device_name_test",
|
||||
srcs = ["bluetooth_device_name_test.cc"],
|
||||
@@ -100,3 +114,27 @@ cc_test(
|
||||
"//testing/base/public:gunit_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "wifi_lan_service_info_test",
|
||||
srcs = ["wifi_lan_service_info_test.cc"],
|
||||
deps = [
|
||||
":internal",
|
||||
"//platform:utils",
|
||||
"//platform/port:string",
|
||||
"//testing/base/public:gunit_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "offline_frames_test",
|
||||
srcs = [
|
||||
"offline_frames_test.cc",
|
||||
],
|
||||
deps = [
|
||||
":internal",
|
||||
"//proto/connections:offline_wire_formats_portable_proto",
|
||||
"//platform:types",
|
||||
"//testing/base/public:gunit_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -49,7 +49,7 @@ ExceptionOr<ConstPtr<ByteArray> > readExactly(Ptr<InputStream> reader,
|
||||
ScopedPtr<ConstPtr<ByteArray> > scoped_read_bytes(read_bytes.result());
|
||||
|
||||
// In Java, EOFException is a sub-variant of IOException.
|
||||
if (scoped_read_bytes->size() == 0) {
|
||||
if (scoped_read_bytes.isNull() || scoped_read_bytes->size() == 0) {
|
||||
return ExceptionOr<ConstPtr<ByteArray> >(Exception::IO);
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ Exception::Value writeInt(Ptr<OutputStream> writer, std::int32_t value) {
|
||||
|
||||
} // namespace
|
||||
|
||||
// TODO(b/150763574): Move implementatiopn to header or .inc file.
|
||||
template <typename Platform>
|
||||
BaseEndpointChannel<Platform>::BaseEndpointChannel(const string& channel_name,
|
||||
Ptr<InputStream> reader,
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "core/internal/base_endpoint_channel.h"
|
||||
|
||||
#include "platform/impl/default/default_platform.h"
|
||||
#include "platform/pipe.h"
|
||||
#include "proto/connections_enums.pb.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
namespace {
|
||||
|
||||
class TestPlatform : public DefaultPlatform {
|
||||
public:
|
||||
static SystemClock* createSystemClock() { return nullptr; }
|
||||
|
||||
static Ptr<AtomicBoolean> createAtomicBoolean(bool initial_value) {
|
||||
return Ptr<AtomicBoolean>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static Ptr<AtomicReference<T>> createAtomicReference(const T& initial_value) {
|
||||
return Ptr<AtomicReference<T>>();
|
||||
}
|
||||
};
|
||||
|
||||
class TestEndpointChannel : public BaseEndpointChannel<TestPlatform> {
|
||||
public:
|
||||
explicit TestEndpointChannel(Ptr<InputStream> input_stream)
|
||||
: BaseEndpointChannel("channel", input_stream, Ptr<OutputStream>()) {}
|
||||
|
||||
MOCK_METHOD(proto::connections::Medium, getMedium, (), (override));
|
||||
MOCK_METHOD(void, closeImpl, (), (override));
|
||||
};
|
||||
|
||||
using SamplePipe = Pipe<TestPlatform>;
|
||||
|
||||
TEST(BaseEndpointChannelTest, ReadAfterInputStreamClosed) {
|
||||
auto pipe = MakeRefCountedPtr(new SamplePipe());
|
||||
ScopedPtr<Ptr<InputStream>> input_stream(SamplePipe::createInputStream(pipe));
|
||||
ScopedPtr<Ptr<OutputStream>> output_stream(
|
||||
SamplePipe::createOutputStream(pipe));
|
||||
|
||||
TestEndpointChannel test_channel(input_stream.get());
|
||||
|
||||
// Close the output stream before trying to read from the input.
|
||||
output_stream->close();
|
||||
|
||||
// Trying to read should fail gracefully with an IO error.
|
||||
ExceptionOr<ConstPtr<ByteArray>> result = test_channel.read();
|
||||
|
||||
ASSERT_FALSE(result.ok());
|
||||
ASSERT_EQ(Exception::IO, result.exception());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -701,7 +701,10 @@ BasePCPHandler<Platform>::~BasePCPHandler() {
|
||||
|
||||
// Unregister ourselves from the IncomingOfflineFrameProcessors.
|
||||
endpoint_manager_->unregisterIncomingOfflineFrameProcessor(
|
||||
V1Frame::CONNECTION_RESPONSE, MakePtr(this));
|
||||
V1Frame::CONNECTION_RESPONSE,
|
||||
std::static_pointer_cast<
|
||||
typename EndpointManager<Platform>::IncomingOfflineFrameProcessor>(
|
||||
self_));
|
||||
|
||||
encryption_runner_.destroy();
|
||||
|
||||
@@ -747,7 +750,7 @@ Status::Value BasePCPHandler<Platform>::startAdvertising(
|
||||
ScopedPtr<Ptr<Future<Status::Value>>> result(
|
||||
runOnPCPHandlerThread<Status::Value>(
|
||||
MakePtr(new base_pcp_handler::StartAdvertisingCallable<Platform>(
|
||||
MakePtr(this), client_proxy, service_id, local_endpoint_name,
|
||||
self_, client_proxy, service_id, local_endpoint_name,
|
||||
advertising_options, connection_lifecycle_listener))));
|
||||
return waitForResult("startAdvertising(" + local_endpoint_name + ")",
|
||||
client_proxy->getClientId(), result.get());
|
||||
@@ -759,7 +762,7 @@ void BasePCPHandler<Platform>::stopAdvertising(
|
||||
ScopedPtr<Ptr<CountDownLatch>> latch(Platform::createCountDownLatch(1));
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::StopAdvertisingRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, latch.get())));
|
||||
self_, client_proxy, latch.get())));
|
||||
waitForLatch("stopAdvertising", latch.get());
|
||||
}
|
||||
|
||||
@@ -771,7 +774,7 @@ Status::Value BasePCPHandler<Platform>::startDiscovery(
|
||||
ScopedPtr<Ptr<Future<Status::Value>>> result(
|
||||
runOnPCPHandlerThread<Status::Value>(
|
||||
MakePtr(new base_pcp_handler::StartDiscoveryCallable<Platform>(
|
||||
MakePtr(this), client_proxy, service_id, discovery_options,
|
||||
self_, client_proxy, service_id, discovery_options,
|
||||
discovery_listener))));
|
||||
return waitForResult("startDiscovery(" + service_id + ")",
|
||||
client_proxy->getClientId(), result.get());
|
||||
@@ -783,7 +786,7 @@ void BasePCPHandler<Platform>::stopDiscovery(
|
||||
ScopedPtr<Ptr<CountDownLatch>> latch(Platform::createCountDownLatch(1));
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::StopDiscoveryRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, latch.get())));
|
||||
self_, client_proxy, latch.get())));
|
||||
waitForLatch("stopDiscovery", latch.get());
|
||||
}
|
||||
|
||||
@@ -796,7 +799,7 @@ Status::Value BasePCPHandler<Platform>::requestConnection(
|
||||
Platform::template createSettableFuture<Status::Value>());
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::RequestConnectionRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, local_endpoint_name, endpoint_id,
|
||||
self_, client_proxy, local_endpoint_name, endpoint_id,
|
||||
connection_lifecycle_listener, result.get())));
|
||||
return waitForResult("requestConnection(" + endpoint_id + ")",
|
||||
client_proxy->getClientId(), result.get());
|
||||
@@ -809,7 +812,7 @@ Status::Value BasePCPHandler<Platform>::acceptConnection(
|
||||
ScopedPtr<Ptr<Future<Status::Value>>> result(
|
||||
runOnPCPHandlerThread<Status::Value>(
|
||||
MakePtr(new base_pcp_handler::AcceptConnectionCallable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, payload_listener))));
|
||||
self_, client_proxy, endpoint_id, payload_listener))));
|
||||
return waitForResult("acceptConnection(" + endpoint_id + ")",
|
||||
client_proxy->getClientId(), result.get());
|
||||
}
|
||||
@@ -820,7 +823,7 @@ Status::Value BasePCPHandler<Platform>::rejectConnection(
|
||||
ScopedPtr<Ptr<Future<Status::Value>>> result(
|
||||
runOnPCPHandlerThread<Status::Value>(
|
||||
MakePtr(new base_pcp_handler::RejectConnectionCallable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id))));
|
||||
self_, client_proxy, endpoint_id))));
|
||||
return waitForResult("rejectConnection(" + endpoint_id + ")",
|
||||
client_proxy->getClientId(), result.get());
|
||||
}
|
||||
@@ -845,8 +848,7 @@ void BasePCPHandler<Platform>::processEndpointDisconnection(
|
||||
Ptr<CountDownLatch> process_disconnection_barrier) {
|
||||
runOnPCPHandlerThread(MakePtr(
|
||||
new base_pcp_handler::ProcessEndpointDisconnectionRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id,
|
||||
process_disconnection_barrier)));
|
||||
self_, client_proxy, endpoint_id, process_disconnection_barrier)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -856,7 +858,7 @@ void BasePCPHandler<Platform>::onEncryptionSuccessImpl(
|
||||
ConstPtr<ByteArray> raw_authentication_token) {
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::OnEncryptionSuccessRunnable<Platform>(
|
||||
MakePtr(this), endpoint_id, ukey2_handshake, authentication_token,
|
||||
self_, endpoint_id, ukey2_handshake, authentication_token,
|
||||
raw_authentication_token)));
|
||||
}
|
||||
|
||||
@@ -865,7 +867,7 @@ void BasePCPHandler<Platform>::onEncryptionFailureImpl(
|
||||
const string& endpoint_id, Ptr<EndpointChannel> channel) {
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::OnEncryptionFailureRunnable<Platform>(
|
||||
MakePtr(this), endpoint_id, channel)));
|
||||
self_, endpoint_id, channel)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -1025,8 +1027,8 @@ void BasePCPHandler<Platform>::onConnectionResponse(
|
||||
ScopedPtr<Ptr<CountDownLatch>> latch(Platform::createCountDownLatch(1));
|
||||
runOnPCPHandlerThread(
|
||||
MakePtr(new base_pcp_handler::OnConnectionResponseRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id,
|
||||
connection_response_offline_frame, latch.get())));
|
||||
self_, client_proxy, endpoint_id, connection_response_offline_frame,
|
||||
latch.get())));
|
||||
waitForLatch("onConnectionResponse()", latch.get());
|
||||
}
|
||||
|
||||
@@ -1154,8 +1156,8 @@ Exception::Value BasePCPHandler<Platform>::onIncomingConnection(
|
||||
// Next, we'll set up encryption.
|
||||
encryption_runner_->startServer(
|
||||
client_proxy, connection_request.endpoint_id(), endpoint_channel,
|
||||
MakePtr(new typename BasePCPHandler<Platform>::ResultListenerFacade(
|
||||
MakePtr(this))));
|
||||
MakePtr(new
|
||||
typename BasePCPHandler<Platform>::ResultListenerFacade(self_)));
|
||||
return Exception::NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -496,6 +496,7 @@ class BasePCPHandler
|
||||
// This should have been a ScopedPtr, but we are making this a Ptr to manually
|
||||
// control the order of destruction.
|
||||
Ptr<EncryptionRunner<Platform> > encryption_runner_;
|
||||
std::shared_ptr<BasePCPHandler> self_{this, [](void*){}};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -290,9 +290,14 @@ TEST(BLEAdvertisementTest, DeserializationPassesWithLongLength) {
|
||||
endpoint_name, bluetooth_mac_address));
|
||||
|
||||
// Add bytes to the end of the valid BLE advertisement.
|
||||
auto new_array =
|
||||
new ByteArray(BLEAdvertisement::kMinAdvertisementLength + 1000);
|
||||
ASSERT_LE(scoped_ble_advertisement_bytes->size(), new_array->size());
|
||||
memcpy(new_array->getData(),
|
||||
scoped_ble_advertisement_bytes->getData(),
|
||||
scoped_ble_advertisement_bytes->size());
|
||||
ScopedPtr<ConstPtr<ByteArray> > long_ble_advertisement_bytes(MakeConstPtr(
|
||||
new ByteArray(scoped_ble_advertisement_bytes.get()->getData(),
|
||||
BLEAdvertisement::kMinAdvertisementLength + 1000)));
|
||||
new_array));
|
||||
|
||||
// Deserialize the long BLE advertisement.
|
||||
ScopedPtr<Ptr<BLEAdvertisement> > scoped_long_ble_advertisement(
|
||||
@@ -327,9 +332,14 @@ TEST(BLEAdvertisementTest, DeserializationWorksWithLongEndpointName) {
|
||||
corrupt_ble_advertisement_bytes.size())));
|
||||
// Increase the size of the advertisement so that there's enough data for the
|
||||
// now-longer endpoint name.
|
||||
auto new_array =
|
||||
new ByteArray(BLEAdvertisement::kMinAdvertisementLength + 1000);
|
||||
ASSERT_LE(scoped_ble_advertisement_bytes->size(), new_array->size());
|
||||
memcpy(new_array->getData(),
|
||||
scoped_ble_advertisement_bytes->getData(),
|
||||
scoped_ble_advertisement_bytes->size());
|
||||
ScopedPtr<ConstPtr<ByteArray> > long_ble_advertisement_bytes(MakeConstPtr(
|
||||
new ByteArray(scoped_corrupt_ble_advertisement_bytes.get()->getData(),
|
||||
BLEAdvertisement::kMinAdvertisementLength + 1000)));
|
||||
new_array));
|
||||
|
||||
// And deserialize the changed BLE Advertisement.
|
||||
ScopedPtr<Ptr<BLEAdvertisement> > scoped_ble_advertisement(
|
||||
|
||||
@@ -201,10 +201,7 @@ EndpointChannelManager<Platform>::ChannelState::updateChannelForEndpoint(
|
||||
ScopedPtr<Ptr<EndpointChannel> > scoped_previous_endpoint_channel(
|
||||
previous_endpoint_channel);
|
||||
|
||||
// Upgrade endpoint_channel to be reference-counted before starting to track
|
||||
// it (and make it clear that endpoint_channel no longer owns the raw
|
||||
// pointer).
|
||||
endpoint_metadata->endpoint_channel = MakeRefCountedPtr(&(*endpoint_channel));
|
||||
endpoint_metadata->endpoint_channel = endpoint_channel;
|
||||
endpoint_channel.clear();
|
||||
endpoint_id_to_metadata_[endpoint_id] = endpoint_metadata;
|
||||
|
||||
|
||||
@@ -497,7 +497,7 @@ void EndpointManager<Platform>::registerIncomingOfflineFrameProcessor(
|
||||
processor) {
|
||||
runOnEndpointManagerThread(MakePtr(
|
||||
new endpoint_manager::RegisterIncomingOfflineFrameProcessorRunnable<
|
||||
Platform>(MakePtr(this), frame_type, processor)));
|
||||
Platform>(self_, frame_type, processor)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -507,7 +507,7 @@ void EndpointManager<Platform>::unregisterIncomingOfflineFrameProcessor(
|
||||
processor) {
|
||||
runOnEndpointManagerThread(MakePtr(
|
||||
new endpoint_manager::UnregisterIncomingOfflineFrameProcessorRunnable<
|
||||
Platform>(MakePtr(this), frame_type, processor)));
|
||||
Platform>(self_, frame_type, processor)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -521,7 +521,7 @@ EndpointManager<Platform>::getOfflineFrameProcessor(
|
||||
ScopedPtr<ResultType> future_result(
|
||||
runOnEndpointManagerThread<PtrIncomingOfflineFrameProcessor>(MakePtr(
|
||||
new endpoint_manager::GetOfflineFrameProcessorCallable<Platform>(
|
||||
MakePtr(this), frame_type))));
|
||||
self_, frame_type))));
|
||||
|
||||
return waitForResult("getOfflineFrameProcessor", future_result.get());
|
||||
}
|
||||
@@ -536,7 +536,7 @@ void EndpointManager<Platform>::registerEndpoint(
|
||||
ScopedPtr<Ptr<CountDownLatch>> latch(Platform::createCountDownLatch(1));
|
||||
runOnEndpointManagerThread(
|
||||
MakePtr(new endpoint_manager::RegisterEndpointRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, endpoint_name,
|
||||
self_, client_proxy, endpoint_id, endpoint_name,
|
||||
authentication_token, raw_authentication_token, is_incoming,
|
||||
endpoint_channel, connection_lifecycle_listener, latch.get())));
|
||||
waitForLatch("registerEndpoint", latch.get());
|
||||
@@ -548,7 +548,7 @@ void EndpointManager<Platform>::unregisterEndpoint(
|
||||
ScopedPtr<Ptr<CountDownLatch>> latch(Platform::createCountDownLatch(1));
|
||||
runOnEndpointManagerThread(
|
||||
MakePtr(new endpoint_manager::UnregisterEndpointRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, latch.get())));
|
||||
self_, client_proxy, endpoint_id, latch.get())));
|
||||
waitForLatch("unregisterEndpoint", latch.get());
|
||||
}
|
||||
|
||||
@@ -557,7 +557,7 @@ void EndpointManager<Platform>::discardEndpoint(
|
||||
Ptr<ClientProxy<Platform>> client_proxy, const string& endpoint_id) {
|
||||
runOnEndpointManagerThread(
|
||||
MakePtr(new endpoint_manager::DiscardEndpointRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id)));
|
||||
self_, client_proxy, endpoint_id)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define CORE_INTERNAL_ENDPOINT_MANAGER_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "core/internal/client_proxy.h"
|
||||
#include "core/internal/endpoint_channel.h"
|
||||
@@ -221,6 +222,7 @@ class EndpointManager {
|
||||
ScopedPtr<Ptr<typename Platform::MultiThreadExecutorType> >
|
||||
endpoint_readers_thread_pool_;
|
||||
ScopedPtr<Ptr<typename Platform::SingleThreadExecutorType> > serial_executor_;
|
||||
std::shared_ptr<EndpointManager<Platform>> self_{this, [](void*){}};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace nearby {
|
||||
namespace connections {
|
||||
namespace mediums {
|
||||
|
||||
namespace {
|
||||
|
||||
class SampleSystemClock : public SystemClock {
|
||||
public:
|
||||
SampleSystemClock() {}
|
||||
@@ -30,13 +28,24 @@ class SamplePlatform {
|
||||
}
|
||||
};
|
||||
|
||||
// We keep a copy of these constants because this is an old-school test (so we
|
||||
// can't delare it as a friend class of AdvertisementReadResult).
|
||||
constexpr char kAdvertisementBytes[] = {0x0A, 0x0B, 0x0C};
|
||||
|
||||
// Default values may be too big and impractical to wait for in the test.
|
||||
// For the test platform, we redefine them to some reasonable values.
|
||||
const absl::Duration kAdvertisementBaseBackoffDuration =
|
||||
absl::Milliseconds(1000); // 1 second
|
||||
const absl::Duration kAdvertisementMaxBackoffDuration =
|
||||
absl::Milliseconds(6000); // 6 seconds
|
||||
const char kAdvertisementBytes[] = {0x0A, 0x0B, 0x0C};
|
||||
|
||||
template <>
|
||||
const std::int64_t AdvertisementReadResult<
|
||||
SamplePlatform>::kAdvertisementMaxBackoffDurationMillis =
|
||||
ToInt64Milliseconds(kAdvertisementMaxBackoffDuration);
|
||||
template <>
|
||||
const std::int64_t
|
||||
AdvertisementReadResult<
|
||||
SamplePlatform>::kAdvertisementBaseBackoffDurationMillis =
|
||||
ToInt64Milliseconds(kAdvertisementBaseBackoffDuration);
|
||||
|
||||
TEST(AdvertisementReadResultTest, AdvertisementExists) {
|
||||
AdvertisementReadResult<SamplePlatform> advertisement_read_result;
|
||||
@@ -141,7 +150,6 @@ TEST(AdvertisementReadResultTest, GetDurationSinceRead) {
|
||||
ASSERT_GE(advertisement_read_result.getDurationSinceReadMillis(), sleepTime);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mediums
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "core/internal/mediums/ble_advertisement.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location {
|
||||
@@ -224,9 +226,10 @@ TEST(BLEAdvertisementTest, DeserializationWorksWithExtraBytes) {
|
||||
|
||||
// Copy the bytes into a new array with extra bytes. We must explicitly
|
||||
// define how long our array is because we can't use variable length arrays.
|
||||
char raw_ble_advertisement_bytes[kLongAdvertisementLength];
|
||||
char raw_ble_advertisement_bytes[kLongAdvertisementLength] {};
|
||||
memcpy(raw_ble_advertisement_bytes, scoped_ble_advertisement_bytes->getData(),
|
||||
kLongAdvertisementLength);
|
||||
std::min(sizeof(raw_ble_advertisement_bytes),
|
||||
scoped_ble_advertisement_bytes->size()));
|
||||
|
||||
// Re-parse the BLE advertisement using our extra long advertisement bytes.
|
||||
ScopedPtr<ConstPtr<ByteArray> > scoped_long_ble_advertisement_bytes(
|
||||
|
||||
@@ -41,6 +41,38 @@ class BLEPacket {
|
||||
ScopedPtr<ConstPtr<ByteArray> > data_;
|
||||
};
|
||||
|
||||
// Represents the format of data sent over BLE sockets.
|
||||
//
|
||||
// [SERVICE_ID_HASH][DATA]
|
||||
//
|
||||
// See go/nearby-ble-design for more information.
|
||||
class BlePacket {
|
||||
public:
|
||||
static BlePacket FromBytes(const ByteArray& bytes);
|
||||
|
||||
static ByteArray ToBytes(const ByteArray& service_id_hash,
|
||||
const ByteArray& data);
|
||||
|
||||
static const uint32_t kServiceIdHashLength;
|
||||
|
||||
~BlePacket();
|
||||
|
||||
ByteArray GetServiceIdHash() const;
|
||||
ByteArray GetData() const;
|
||||
|
||||
private:
|
||||
static size_t ComputeDataSize(const ByteArray& ble_packet_bytes);
|
||||
static size_t ComputePacketLength(const ByteArray& data);
|
||||
|
||||
static const uint32_t kMinPacketLength;
|
||||
static const uint32_t kMaxDataSize;
|
||||
|
||||
BlePacket(const ByteArray& service_id_hash, const ByteArray& data);
|
||||
|
||||
ByteArray service_id_hash_;
|
||||
ByteArray data_;
|
||||
};
|
||||
|
||||
} // namespace mediums
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
@@ -22,6 +22,21 @@ class BLEPeripheral {
|
||||
ScopedPtr<ConstPtr<ByteArray>> id_;
|
||||
};
|
||||
|
||||
|
||||
// Represents BLE peripheral for testing.
|
||||
class BlePeripheral {
|
||||
public:
|
||||
explicit BlePeripheral(const ByteArray& id) : id_(id) {}
|
||||
~BlePeripheral() = default;
|
||||
|
||||
const ByteArray& GetId() const { return id_; }
|
||||
|
||||
private:
|
||||
// A unique identifier for this peripheral. It can be the BLE advertisement it
|
||||
// was found on, or even simply the BLE MAC address.
|
||||
const ByteArray id_;
|
||||
};
|
||||
|
||||
} // namespace mediums
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
@@ -405,7 +405,7 @@ bool BLEV2<Platform>::startScanning(
|
||||
fast_advertisement_service_uuid);
|
||||
// Avoid leaks.
|
||||
ScopedPtr<Ptr<ScanCallbackFacade>> scan_callback_facade(
|
||||
new ScanCallbackFacade(MakePtr(this)));
|
||||
new ScanCallbackFacade(self_));
|
||||
std::set<string> service_uuids;
|
||||
service_uuids.insert(kCopresenceServiceUuid);
|
||||
if (!ble_medium_->startScanning(service_uuids, power_mode,
|
||||
@@ -427,7 +427,7 @@ void BLEV2<Platform>::onAdvertisementFoundImpl(
|
||||
ConstPtr<BLEAdvertisementData> advertisement_data) {
|
||||
offloadFromPlatformThread(
|
||||
MakePtr(new ble_v2::OnAdvertisementFoundRunnable<Platform>(
|
||||
MakePtr(this), ble_peripheral, advertisement_data)));
|
||||
self_, ble_peripheral, advertisement_data)));
|
||||
}
|
||||
|
||||
// This method is synchronized because it affects class state, but is called
|
||||
@@ -461,11 +461,6 @@ void BLEV2<Platform>::stopScanning() {
|
||||
// TODO(b/112199086) Change to RecurringCancelableAlarm
|
||||
template <typename Platform>
|
||||
Ptr<CancelableAlarm<Platform>> BLEV2<Platform>::createOnLostAlarm() {
|
||||
// return MakePtr(new CancelableAlarm<Platform>(
|
||||
// "BluetoothLowEnergy.startScanning() onLost",
|
||||
// MakePtr(new
|
||||
// ble_v2::ProcessOnLostRunnable<Platform>(MakePtr(this))),
|
||||
// kOnLostTimeoutMillis, on_lost_executor_.get()));
|
||||
return Ptr<CancelableAlarm<Platform>>();
|
||||
}
|
||||
|
||||
@@ -606,7 +601,7 @@ bool BLEV2<Platform>::internalStartAdvertisementGattServer(
|
||||
|
||||
ScopedPtr<Ptr<ServerGATTConnectionLifecycleCallbackFacade>>
|
||||
connection_lifecycle_callback(
|
||||
new ServerGATTConnectionLifecycleCallbackFacade(MakePtr(this)));
|
||||
new ServerGATTConnectionLifecycleCallbackFacade(self_));
|
||||
ScopedPtr<Ptr<GATTServer>> gatt_server(
|
||||
ble_medium_->startGATTServer(connection_lifecycle_callback.get()));
|
||||
if (gatt_server.isNull()) {
|
||||
@@ -737,7 +732,7 @@ BLEV2<Platform>::internalReadFromAdvertisementGattServer(
|
||||
|
||||
ScopedPtr<Ptr<ClientGATTConnectionLifecycleCallbackFacade>>
|
||||
connection_lifecycle_callback(
|
||||
new ClientGATTConnectionLifecycleCallbackFacade(MakePtr(this)));
|
||||
new ClientGATTConnectionLifecycleCallbackFacade(self_));
|
||||
ScopedPtr<Ptr<ClientGATTConnection>> gatt_connection(
|
||||
ble_medium_->connectToGATTServer(peripheral, kDefaultMtu,
|
||||
BLEMediumV2::PowerMode::HIGH,
|
||||
|
||||
@@ -300,6 +300,7 @@ class BLEV2 {
|
||||
Ptr<AdvertisingInfo> advertising_info_;
|
||||
Ptr<GATTServerInfo> gatt_server_info_;
|
||||
Ptr<AcceptingConnectionsInfo> accepting_connections_info_;
|
||||
std::shared_ptr<BLEV2> self_{this, [](void*){}};
|
||||
};
|
||||
|
||||
} // namespace mediums
|
||||
|
||||
@@ -71,8 +71,7 @@ TEST(BloomFilterTest, AddMultipleArgsReturnsNonemptyArray) {
|
||||
ScopedPtr<ConstPtr<ByteArray>> scoped_bloom_filter_bytes(
|
||||
scoped_bloom_filter->asBytes());
|
||||
std::string empty_string(kByteArrayLength, '\0');
|
||||
ASSERT_NE(0, memcmp(scoped_bloom_filter_bytes->getData(), empty_string.data(),
|
||||
empty_string.size()));
|
||||
ASSERT_NE(scoped_bloom_filter_bytes->asString(), empty_string);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,85 +1,71 @@
|
||||
#include "core/internal/offline_frames.h"
|
||||
|
||||
#include "platform/port/down_cast.h"
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "platform/byte_array.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
using ExceptionOrOfflineFrame = ExceptionOr<ConstPtr<OfflineFrame>>;
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
T *downcastToRaw(Ptr<proto_ns::MessageLite> message) {
|
||||
return DOWN_CAST<T *>(message.operator->());
|
||||
}
|
||||
|
||||
// This method takes ownership of the passed-in 'message'.
|
||||
//
|
||||
// This can be implemented more efficiently by taking in a reference to an
|
||||
// OfflineFrame object created on the caller's stack, but we instead create it
|
||||
// on the heap and return a Ptr to it for the sake of consistency.
|
||||
ConstPtr<OfflineFrame> newOfflineFrame(V1Frame::FrameType frame_type,
|
||||
Ptr<proto_ns::MessageLite> message) {
|
||||
std::unique_ptr<OfflineFrame> NewOfflineFrame(
|
||||
V1Frame::FrameType frame_type,
|
||||
std::unique_ptr<proto_ns::MessageLite> message) {
|
||||
V1Frame *v1_frame = new V1Frame();
|
||||
v1_frame->set_type(frame_type);
|
||||
|
||||
switch (frame_type) {
|
||||
case V1Frame::CONNECTION_REQUEST:
|
||||
v1_frame->set_allocated_connection_request(
|
||||
downcastToRaw<ConnectionRequestFrame>(message));
|
||||
static_cast<ConnectionRequestFrame *>(message.release()));
|
||||
break;
|
||||
case V1Frame::CONNECTION_RESPONSE:
|
||||
v1_frame->set_allocated_connection_response(
|
||||
downcastToRaw<ConnectionResponseFrame>(message));
|
||||
static_cast<ConnectionResponseFrame *>(message.release()));
|
||||
break;
|
||||
case V1Frame::PAYLOAD_TRANSFER:
|
||||
v1_frame->set_allocated_payload_transfer(
|
||||
downcastToRaw<PayloadTransferFrame>(message));
|
||||
static_cast<PayloadTransferFrame *>(message.release()));
|
||||
break;
|
||||
case V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION:
|
||||
v1_frame->set_allocated_bandwidth_upgrade_negotiation(
|
||||
downcastToRaw<BandwidthUpgradeNegotiationFrame>(message));
|
||||
static_cast<BandwidthUpgradeNegotiationFrame *>(message.release()));
|
||||
break;
|
||||
case V1Frame::KEEP_ALIVE:
|
||||
v1_frame->set_allocated_keep_alive(
|
||||
downcastToRaw<KeepAliveFrame>(message));
|
||||
static_cast<KeepAliveFrame *>(message.release()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Ptr<OfflineFrame> offline_frame(new OfflineFrame());
|
||||
auto offline_frame = std::make_unique<OfflineFrame>();
|
||||
offline_frame->set_version(OfflineFrame::V1);
|
||||
offline_frame->set_allocated_v1(v1_frame);
|
||||
return ConstifyPtr(offline_frame);
|
||||
return offline_frame;
|
||||
}
|
||||
|
||||
// This method takes ownership of the passed-in 'offline_frame' and destroys it
|
||||
// before returning.
|
||||
ConstPtr<ByteArray> toBytes(ConstPtr<OfflineFrame> offline_frame) {
|
||||
ScopedPtr<ConstPtr<OfflineFrame> > scoped_offline_frame(offline_frame);
|
||||
|
||||
size_t serialized_size = offline_frame->ByteSizeLong();
|
||||
Ptr<ByteArray> bytes{new ByteArray{serialized_size}};
|
||||
|
||||
offline_frame->SerializeToArray(bytes->getData(), serialized_size);
|
||||
return ConstifyPtr(bytes);
|
||||
ConstPtr<ByteArray> toBytes(std::unique_ptr<OfflineFrame> offline_frame) {
|
||||
auto *bytes = new ByteArray{offline_frame->ByteSizeLong()};
|
||||
offline_frame->SerializeToArray(bytes->getData(), bytes->size());
|
||||
return MakeConstPtr(bytes);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ExceptionOr<ConstPtr<OfflineFrame> > OfflineFrames::fromBytes(
|
||||
ExceptionOrOfflineFrame OfflineFrames::fromBytes(
|
||||
ConstPtr<ByteArray> offline_frame_bytes) {
|
||||
ScopedPtr<Ptr<OfflineFrame> > offline_frame(new OfflineFrame());
|
||||
auto offline_frame = std::make_unique<OfflineFrame>();
|
||||
|
||||
if (!offline_frame->ParseFromArray(offline_frame_bytes->getData(),
|
||||
offline_frame_bytes->size())) {
|
||||
return ExceptionOr<ConstPtr<OfflineFrame> >(
|
||||
Exception::INVALID_PROTOCOL_BUFFER);
|
||||
if (!offline_frame->ParseFromString(offline_frame_bytes->asString())) {
|
||||
return ExceptionOrOfflineFrame(Exception::INVALID_PROTOCOL_BUFFER);
|
||||
}
|
||||
|
||||
return ExceptionOr<ConstPtr<OfflineFrame> >(
|
||||
ConstifyPtr(offline_frame.release()));
|
||||
return ExceptionOrOfflineFrame(MakeConstPtr(offline_frame.release()));
|
||||
}
|
||||
|
||||
V1Frame::FrameType OfflineFrames::getFrameType(
|
||||
@@ -96,7 +82,7 @@ ConstPtr<ByteArray> OfflineFrames::forConnectionRequest(
|
||||
const std::string &endpoint_id, const std::string &endpoint_name,
|
||||
std::int32_t nonce,
|
||||
const std::vector<proto::connections::Medium> &mediums) {
|
||||
Ptr<ConnectionRequestFrame> connection_request(new ConnectionRequestFrame());
|
||||
auto connection_request = std::make_unique<ConnectionRequestFrame>();
|
||||
connection_request->set_endpoint_id(endpoint_id);
|
||||
connection_request->set_endpoint_name(endpoint_name);
|
||||
connection_request->set_nonce(nonce);
|
||||
@@ -107,113 +93,113 @@ ConstPtr<ByteArray> OfflineFrames::forConnectionRequest(
|
||||
connection_request->add_mediums(mediumToConnectionRequestMedium(*it));
|
||||
}
|
||||
|
||||
return toBytes(
|
||||
newOfflineFrame(V1Frame::CONNECTION_REQUEST, connection_request));
|
||||
return toBytes(NewOfflineFrame(V1Frame::CONNECTION_REQUEST,
|
||||
std::move(connection_request)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray> OfflineFrames::forConnectionResponse(std::int32_t status) {
|
||||
Ptr<ConnectionResponseFrame> connection_response(
|
||||
new ConnectionResponseFrame());
|
||||
auto connection_response = std::make_unique<ConnectionResponseFrame>();
|
||||
connection_response->set_status(status);
|
||||
|
||||
return toBytes(
|
||||
newOfflineFrame(V1Frame::CONNECTION_RESPONSE, connection_response));
|
||||
return toBytes(NewOfflineFrame(V1Frame::CONNECTION_RESPONSE,
|
||||
std::move(connection_response)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray> OfflineFrames::forDataPayloadTransferFrame(
|
||||
const PayloadTransferFrame::PayloadHeader &header,
|
||||
const PayloadTransferFrame::PayloadChunk &chunk) {
|
||||
Ptr<PayloadTransferFrame> payload_transfer(new PayloadTransferFrame());
|
||||
auto payload_transfer = std::make_unique<PayloadTransferFrame>();
|
||||
payload_transfer->set_packet_type(PayloadTransferFrame::DATA);
|
||||
*payload_transfer->mutable_payload_header() = header;
|
||||
*payload_transfer->mutable_payload_chunk() = chunk;
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::PAYLOAD_TRANSFER, payload_transfer));
|
||||
return toBytes(
|
||||
NewOfflineFrame(V1Frame::PAYLOAD_TRANSFER, std::move(payload_transfer)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray> OfflineFrames::forControlPayloadTransferFrame(
|
||||
const PayloadTransferFrame::PayloadHeader &header,
|
||||
const PayloadTransferFrame::ControlMessage &control) {
|
||||
Ptr<PayloadTransferFrame> payload_transfer(new PayloadTransferFrame());
|
||||
auto payload_transfer = std::make_unique<PayloadTransferFrame>();
|
||||
payload_transfer->set_packet_type(PayloadTransferFrame::CONTROL);
|
||||
*payload_transfer->mutable_payload_header() = header;
|
||||
*payload_transfer->mutable_control_message() = control;
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::PAYLOAD_TRANSFER, payload_transfer));
|
||||
return toBytes(
|
||||
NewOfflineFrame(V1Frame::PAYLOAD_TRANSFER, std::move(payload_transfer)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray> OfflineFrames::
|
||||
forWifiHotspotUpgradePathAvailableBandwidthUpgradeNegotiationEvent(
|
||||
const std::string &ssid, const std::string &password,
|
||||
std::int32_t port) {
|
||||
BandwidthUpgradeNegotiationFrame::UpgradePathInfo::WifiHotspotCredentials
|
||||
*wifi_hotspot_credentials = new BandwidthUpgradeNegotiationFrame::
|
||||
UpgradePathInfo::WifiHotspotCredentials();
|
||||
auto *wifi_hotspot_credentials = new BandwidthUpgradeNegotiationFrame::
|
||||
UpgradePathInfo::WifiHotspotCredentials();
|
||||
wifi_hotspot_credentials->set_ssid(ssid);
|
||||
wifi_hotspot_credentials->set_password(password);
|
||||
wifi_hotspot_credentials->set_port(port);
|
||||
|
||||
BandwidthUpgradeNegotiationFrame::UpgradePathInfo *upgrade_path_info =
|
||||
auto *upgrade_path_info =
|
||||
new BandwidthUpgradeNegotiationFrame::UpgradePathInfo();
|
||||
upgrade_path_info->set_medium(
|
||||
BandwidthUpgradeNegotiationFrame::UpgradePathInfo::WIFI_HOTSPOT);
|
||||
upgrade_path_info->set_allocated_wifi_hotspot_credentials(
|
||||
wifi_hotspot_credentials);
|
||||
|
||||
Ptr<BandwidthUpgradeNegotiationFrame> bandwidth_upgrade_negotiation(
|
||||
new BandwidthUpgradeNegotiationFrame());
|
||||
auto bandwidth_upgrade_negotiation =
|
||||
std::make_unique<BandwidthUpgradeNegotiationFrame>();
|
||||
bandwidth_upgrade_negotiation->set_event_type(
|
||||
BandwidthUpgradeNegotiationFrame::UPGRADE_PATH_AVAILABLE);
|
||||
bandwidth_upgrade_negotiation->set_allocated_upgrade_path_info(
|
||||
upgrade_path_info);
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
bandwidth_upgrade_negotiation));
|
||||
return toBytes(NewOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
std::move(bandwidth_upgrade_negotiation)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray>
|
||||
OfflineFrames::forLastWriteToPriorChannelBandwidthUpgradeNegotiationEvent() {
|
||||
Ptr<BandwidthUpgradeNegotiationFrame> bandwidth_upgrade_negotiation(
|
||||
new BandwidthUpgradeNegotiationFrame());
|
||||
auto bandwidth_upgrade_negotiation =
|
||||
std::make_unique<BandwidthUpgradeNegotiationFrame>();
|
||||
bandwidth_upgrade_negotiation->set_event_type(
|
||||
BandwidthUpgradeNegotiationFrame::LAST_WRITE_TO_PRIOR_CHANNEL);
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
bandwidth_upgrade_negotiation));
|
||||
return toBytes(NewOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
std::move(bandwidth_upgrade_negotiation)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray>
|
||||
OfflineFrames::forSafeToClosePriorChannelBandwidthUpgradeNegotiationEvent() {
|
||||
Ptr<BandwidthUpgradeNegotiationFrame> bandwidth_upgrade_negotiation(
|
||||
new BandwidthUpgradeNegotiationFrame());
|
||||
auto bandwidth_upgrade_negotiation =
|
||||
std::make_unique<BandwidthUpgradeNegotiationFrame>();
|
||||
bandwidth_upgrade_negotiation->set_event_type(
|
||||
BandwidthUpgradeNegotiationFrame::SAFE_TO_CLOSE_PRIOR_CHANNEL);
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
bandwidth_upgrade_negotiation));
|
||||
return toBytes(NewOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
std::move(bandwidth_upgrade_negotiation)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray>
|
||||
OfflineFrames::forClientIntroductionBandwidthUpgradeNegotiationEvent(
|
||||
const std::string &endpoint_id) {
|
||||
BandwidthUpgradeNegotiationFrame::ClientIntroduction *client_introduction =
|
||||
auto *client_introduction =
|
||||
new BandwidthUpgradeNegotiationFrame::ClientIntroduction();
|
||||
client_introduction->set_endpoint_id(endpoint_id);
|
||||
|
||||
Ptr<BandwidthUpgradeNegotiationFrame> bandwidth_upgrade_negotiation(
|
||||
new BandwidthUpgradeNegotiationFrame());
|
||||
auto bandwidth_upgrade_negotiation =
|
||||
std::make_unique<BandwidthUpgradeNegotiationFrame>();
|
||||
bandwidth_upgrade_negotiation->set_event_type(
|
||||
BandwidthUpgradeNegotiationFrame::CLIENT_INTRODUCTION);
|
||||
bandwidth_upgrade_negotiation->set_allocated_client_introduction(
|
||||
client_introduction);
|
||||
|
||||
return toBytes(newOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
bandwidth_upgrade_negotiation));
|
||||
return toBytes(NewOfflineFrame(V1Frame::BANDWIDTH_UPGRADE_NEGOTIATION,
|
||||
std::move(bandwidth_upgrade_negotiation)));
|
||||
}
|
||||
|
||||
ConstPtr<ByteArray> OfflineFrames::forKeepAlive() {
|
||||
Ptr<KeepAliveFrame> keep_alive_frame(new KeepAliveFrame());
|
||||
return toBytes(newOfflineFrame(V1Frame::KEEP_ALIVE, keep_alive_frame));
|
||||
return toBytes(
|
||||
NewOfflineFrame(V1Frame::KEEP_ALIVE, std::make_unique<KeepAliveFrame>()));
|
||||
}
|
||||
|
||||
ConnectionRequestFrame::Medium OfflineFrames::mediumToConnectionRequestMedium(
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "core/internal/offline_frames.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "proto/connections/offline_wire_formats.pb.h"
|
||||
#include "platform/byte_array.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location::nearby::connections {
|
||||
|
||||
namespace {
|
||||
using Medium = proto::connections::Medium;
|
||||
|
||||
std::unique_ptr<OfflineFrame> MakeFrame(V1Frame* sub_frame) {
|
||||
auto frame = std::make_unique<OfflineFrame>();
|
||||
frame->set_version(OfflineFrame::V1);
|
||||
frame->set_allocated_v1(sub_frame);
|
||||
return frame;
|
||||
}
|
||||
|
||||
void SetSubframe(V1Frame* frame, ConnectionRequestFrame* sub_frame) {
|
||||
frame->set_type(V1Frame::CONNECTION_REQUEST);
|
||||
frame->set_allocated_connection_request(sub_frame);
|
||||
}
|
||||
|
||||
constexpr ConnectionRequestFrame::Medium ToConnectionRequestMedium(
|
||||
proto::connections::Medium medium) {
|
||||
switch (medium) {
|
||||
case proto::connections::MDNS:
|
||||
return ConnectionRequestFrame::MDNS;
|
||||
case proto::connections::BLUETOOTH:
|
||||
return ConnectionRequestFrame::BLUETOOTH;
|
||||
case proto::connections::WIFI_HOTSPOT:
|
||||
return ConnectionRequestFrame::WIFI_HOTSPOT;
|
||||
case proto::connections::BLE:
|
||||
return ConnectionRequestFrame::BLE;
|
||||
case proto::connections::WIFI_LAN:
|
||||
return ConnectionRequestFrame::WIFI_LAN;
|
||||
default:
|
||||
return ConnectionRequestFrame::UNKNOWN_MEDIUM;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(OfflineFramesTest, CanParseMessageFromBytes) {
|
||||
const string endpoint_id{"ABC"};
|
||||
const string endpoint_name{"XYZ"};
|
||||
const int32 nonce{1234};
|
||||
const std::vector<proto::connections::Medium> mediums{Medium::BLE,
|
||||
Medium::BLUETOOTH};
|
||||
|
||||
auto* v1_frame = new V1Frame{};
|
||||
auto* sub_frame = new ConnectionRequestFrame{};
|
||||
sub_frame->set_endpoint_id(endpoint_id);
|
||||
sub_frame->set_endpoint_name(endpoint_name);
|
||||
sub_frame->set_nonce(nonce);
|
||||
|
||||
for (auto& medium : mediums) {
|
||||
sub_frame->add_mediums(ToConnectionRequestMedium(medium));
|
||||
}
|
||||
|
||||
SetSubframe(v1_frame, sub_frame);
|
||||
auto frame = MakeFrame(v1_frame);
|
||||
|
||||
auto bytes = MakeConstPtr(new ByteArray(frame->SerializeAsString()));
|
||||
|
||||
auto ret_value = OfflineFrames::fromBytes(bytes);
|
||||
ASSERT_TRUE(ret_value.ok());
|
||||
const auto& rx_message = ret_value.result();
|
||||
ASSERT_TRUE(rx_message->has_version());
|
||||
ASSERT_EQ(rx_message->version(), OfflineFrame::V1);
|
||||
ASSERT_TRUE(rx_message->has_v1());
|
||||
const auto& rx_frame = rx_message->v1();
|
||||
ASSERT_EQ(rx_frame.type(), V1Frame::CONNECTION_REQUEST);
|
||||
ASSERT_TRUE(rx_frame.has_connection_request());
|
||||
const auto& req = rx_frame.connection_request();
|
||||
ASSERT_TRUE(req.has_endpoint_id());
|
||||
ASSERT_TRUE(req.has_endpoint_name());
|
||||
ASSERT_TRUE(req.has_nonce());
|
||||
ASSERT_EQ(req.endpoint_id(), endpoint_id);
|
||||
ASSERT_EQ(req.endpoint_name(), endpoint_name);
|
||||
ASSERT_EQ(req.nonce(), nonce);
|
||||
ASSERT_EQ(req.mediums_size(), mediums.size());
|
||||
}
|
||||
|
||||
} // namespace location::nearby::connections
|
||||
@@ -134,14 +134,14 @@ P2PClusterPCPHandler<Platform>::startDiscoveryImpl(
|
||||
|
||||
proto::connections::Medium bluetooth_medium =
|
||||
startBluetoothDiscovery(MakePtr(new FoundBluetoothAdvertisementProcessor(
|
||||
MakePtr(this), client_proxy, service_id)),
|
||||
self_, client_proxy, service_id)),
|
||||
client_proxy, service_id);
|
||||
if (proto::connections::UNKNOWN_MEDIUM != bluetooth_medium) {
|
||||
mediums_started_successfully.push_back(bluetooth_medium);
|
||||
}
|
||||
|
||||
proto::connections::Medium ble_medium = startBleDiscovery(
|
||||
MakePtr(new FoundBleAdvertisementProcessor(MakePtr(this), client_proxy)),
|
||||
MakePtr(new FoundBleAdvertisementProcessor(self_, client_proxy)),
|
||||
client_proxy, service_id);
|
||||
if (proto::connections::UNKNOWN_MEDIUM != ble_medium) {
|
||||
mediums_started_successfully.push_back(ble_medium);
|
||||
@@ -312,7 +312,7 @@ void P2PClusterPCPHandler<Platform>::FoundBluetoothAdvertisementProcessor::
|
||||
onFoundBluetoothDevice(Ptr<BluetoothDevice> bluetooth_device) {
|
||||
pcp_handler_->runOnPCPHandlerThread(
|
||||
MakePtr(new OnFoundBluetoothDeviceRunnable(pcp_handler_, client_proxy_,
|
||||
MakePtr(this), service_id_,
|
||||
self_, service_id_,
|
||||
bluetooth_device)));
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ template <typename Platform>
|
||||
void P2PClusterPCPHandler<Platform>::FoundBluetoothAdvertisementProcessor::
|
||||
onLostBluetoothDevice(Ptr<BluetoothDevice> bluetooth_device) {
|
||||
pcp_handler_->runOnPCPHandlerThread(MakePtr(new OnLostBluetoothDeviceRunnable(
|
||||
pcp_handler_, client_proxy_, MakePtr(this), service_id_,
|
||||
pcp_handler_, client_proxy_, self_, service_id_,
|
||||
bluetooth_device)));
|
||||
}
|
||||
|
||||
@@ -450,7 +450,7 @@ void P2PClusterPCPHandler<Platform>::FoundBleAdvertisementProcessor::
|
||||
const string& service_id,
|
||||
ConstPtr<ByteArray> advertisement_bytes) {
|
||||
pcp_handler_->runOnPCPHandlerThread(MakePtr(new OnFoundBlePeripheralRunnable(
|
||||
pcp_handler_, client_proxy_, MakePtr(this), service_id, ble_peripheral,
|
||||
pcp_handler_, client_proxy_, self_, service_id, ble_peripheral,
|
||||
advertisement_bytes)));
|
||||
}
|
||||
|
||||
@@ -532,7 +532,7 @@ void P2PClusterPCPHandler<Platform>::FoundBleAdvertisementProcessor::
|
||||
onLostBlePeripheral(Ptr<BLE_PERIPHERAL> ble_peripheral,
|
||||
const string& service_id) {
|
||||
pcp_handler_->runOnPCPHandlerThread(MakePtr(new OnLostBlePeripheralRunnable(
|
||||
pcp_handler_, client_proxy_, MakePtr(this), service_id, ble_peripheral)));
|
||||
pcp_handler_, client_proxy_, self_, service_id, ble_peripheral)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -597,7 +597,7 @@ P2PClusterPCPHandler<Platform>::startBluetoothAdvertising(
|
||||
if (!medium_manager_->startListeningForIncomingBluetoothConnections(
|
||||
service_id,
|
||||
MakePtr(new IncomingBluetoothConnectionProcessor(
|
||||
MakePtr(this), client_proxy, local_endpoint_name)))) {
|
||||
self_, client_proxy, local_endpoint_name)))) {
|
||||
// TODO(tracyzhou): Add logging.
|
||||
return proto::connections::UNKNOWN_MEDIUM;
|
||||
}
|
||||
@@ -654,7 +654,7 @@ proto::connections::Medium P2PClusterPCPHandler<Platform>::startBleAdvertising(
|
||||
if (!medium_manager_->startListeningForIncomingBleConnections(
|
||||
service_id,
|
||||
MakePtr(new IncomingBleConnectionProcessor(
|
||||
MakePtr(this), client_proxy, local_endpoint_name)))) {
|
||||
self_, client_proxy, local_endpoint_name)))) {
|
||||
// TODO(ahlee): logger.atWarning().log("In startBleAdvertising(%s), client
|
||||
// %d failed to start listening for incoming BLE connections to ServiceId
|
||||
// %s", local_endpoint_name, clientProxy.getClientId(), service_id);
|
||||
|
||||
@@ -208,6 +208,8 @@ class P2PClusterPCPHandler : public BasePCPHandler<Platform> {
|
||||
Ptr<ClientProxy<Platform> > client_proxy_;
|
||||
const string service_id_;
|
||||
ScopedPtr<ConstPtr<ByteArray> > expected_service_id_hash_;
|
||||
std::shared_ptr<FoundBluetoothAdvertisementProcessor> self_{this,
|
||||
[](void*) {}};
|
||||
};
|
||||
|
||||
class FoundBleAdvertisementProcessor
|
||||
@@ -281,6 +283,7 @@ class P2PClusterPCPHandler : public BasePCPHandler<Platform> {
|
||||
// Maps a BLEPeripheral to its corresponding BLEEndpointState.
|
||||
typedef std::map<string, BLEEndpointState> FoundBLEEndpointsMap;
|
||||
FoundBLEEndpointsMap found_ble_endpoints_;
|
||||
std::shared_ptr<FoundBleAdvertisementProcessor> self_{this, [](void*) {}};
|
||||
};
|
||||
|
||||
class BluetoothEndpoint
|
||||
@@ -367,6 +370,7 @@ class P2PClusterPCPHandler : public BasePCPHandler<Platform> {
|
||||
Ptr<ClientProxy<Platform> > client_proxy, Ptr<BLEEndpoint> ble_endpoint);
|
||||
|
||||
Ptr<MediumManager<Platform> > medium_manager_;
|
||||
std::shared_ptr<P2PClusterPCPHandler> self_{this, [](void*) {}};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -581,7 +581,9 @@ PayloadManager<Platform>::PayloadManager(
|
||||
payload_status_update_executor_(Platform::createSingleThreadExecutor()),
|
||||
endpoint_manager_(endpoint_manager) {
|
||||
endpoint_manager_->registerIncomingOfflineFrameProcessor(
|
||||
V1Frame::PAYLOAD_TRANSFER, MakePtr(this));
|
||||
V1Frame::PAYLOAD_TRANSFER, std::static_pointer_cast<
|
||||
typename EndpointManager<Platform>::IncomingOfflineFrameProcessor>(
|
||||
self_));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -591,7 +593,9 @@ PayloadManager<Platform>::~PayloadManager() {
|
||||
|
||||
// Unregister ourselves from the IncomingOfflineFrameProcessors.
|
||||
endpoint_manager_->unregisterIncomingOfflineFrameProcessor(
|
||||
V1Frame::CONNECTION_RESPONSE, MakePtr(this));
|
||||
V1Frame::CONNECTION_RESPONSE, std::static_pointer_cast<
|
||||
typename EndpointManager<Platform>::IncomingOfflineFrameProcessor>(
|
||||
self_));
|
||||
|
||||
// Stop all the ongoing Runnables (as gracefully as possible).
|
||||
payload_status_update_executor_->shutdown();
|
||||
@@ -640,7 +644,7 @@ void PayloadManager<Platform>::sendPayload(
|
||||
enqueueOutgoingPayload(
|
||||
send_payload_executor,
|
||||
MakePtr(new payload_manager::SendPayloadRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_ids,
|
||||
self_, client_proxy, endpoint_ids,
|
||||
scoped_payload.release())));
|
||||
// TODO(tracyzhou): Add logging.
|
||||
}
|
||||
@@ -694,7 +698,7 @@ void PayloadManager<Platform>::processEndpointDisconnection(
|
||||
Ptr<CountDownLatch> process_disconnection_barrier) {
|
||||
payload_status_update_executor_->execute(MakePtr(
|
||||
new payload_manager::ProcessEndpointDisconnectionRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id,
|
||||
self_, client_proxy, endpoint_id,
|
||||
process_disconnection_barrier)));
|
||||
}
|
||||
|
||||
@@ -830,7 +834,7 @@ void PayloadManager<Platform>::sendClientCallbacksForFinishedOutgoingPayload(
|
||||
payload_status_update_executor_->execute(MakePtr(
|
||||
new payload_manager::
|
||||
SendClientCallbacksForFinishedOutgoingPayloadRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, finished_endpoint_ids,
|
||||
self_, client_proxy, finished_endpoint_ids,
|
||||
payload_header, num_bytes_successfully_transferred, status)));
|
||||
}
|
||||
|
||||
@@ -842,7 +846,7 @@ void PayloadManager<Platform>::sendClientCallbacksForFinishedIncomingPayload(
|
||||
payload_status_update_executor_->execute(MakePtr(
|
||||
new payload_manager::
|
||||
SendClientCallbacksForFinishedIncomingPayloadRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, payload_header,
|
||||
self_, client_proxy, endpoint_id, payload_header,
|
||||
offset_bytes, status)));
|
||||
}
|
||||
|
||||
@@ -935,7 +939,7 @@ void PayloadManager<Platform>::handleSuccessfulOutgoingChunk(
|
||||
std::int64_t payload_chunk_body_size) {
|
||||
payload_status_update_executor_->execute(MakePtr(
|
||||
new payload_manager::HandleSuccessfulOutgoingChunkRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, payload_header,
|
||||
self_, client_proxy, endpoint_id, payload_header,
|
||||
payload_chunk_flags, payload_chunk_offset, payload_chunk_body_size)));
|
||||
}
|
||||
|
||||
@@ -947,7 +951,7 @@ void PayloadManager<Platform>::handleSuccessfulIncomingChunk(
|
||||
std::int64_t payload_chunk_body_size) {
|
||||
payload_status_update_executor_->execute(MakePtr(
|
||||
new payload_manager::HandleSuccessfulIncomingChunkRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, endpoint_id, payload_header,
|
||||
self_, client_proxy, endpoint_id, payload_header,
|
||||
payload_chunk_flags, payload_chunk_offset, payload_chunk_body_size)));
|
||||
}
|
||||
|
||||
|
||||
@@ -277,6 +277,7 @@ class PayloadManager
|
||||
payload_status_update_executor_;
|
||||
|
||||
Ptr<EndpointManager<Platform> > endpoint_manager_;
|
||||
std::shared_ptr<PayloadManager> self_{this, [](void*){}};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -497,7 +497,7 @@ void ServiceControllerRouter<Platform>::startAdvertising(
|
||||
ConstPtr<StartAdvertisingParams> start_advertising_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::StartAdvertisingRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, start_advertising_params)));
|
||||
self_, client_proxy, start_advertising_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -506,7 +506,7 @@ void ServiceControllerRouter<Platform>::stopAdvertising(
|
||||
ConstPtr<StopAdvertisingParams> stop_advertising_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::StopAdvertisingRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, stop_advertising_params)));
|
||||
self_, client_proxy, stop_advertising_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -515,7 +515,7 @@ void ServiceControllerRouter<Platform>::startDiscovery(
|
||||
ConstPtr<StartDiscoveryParams> start_discovery_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::StartDiscoveryRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, start_discovery_params)));
|
||||
self_, client_proxy, start_discovery_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -524,7 +524,7 @@ void ServiceControllerRouter<Platform>::stopDiscovery(
|
||||
ConstPtr<StopDiscoveryParams> stop_discovery_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::StopDiscoveryRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, stop_discovery_params)));
|
||||
self_, client_proxy, stop_discovery_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -533,7 +533,7 @@ void ServiceControllerRouter<Platform>::requestConnection(
|
||||
ConstPtr<RequestConnectionParams> request_connection_params) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::SendConnectionRequestRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, request_connection_params)));
|
||||
self_, client_proxy, request_connection_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -542,7 +542,7 @@ void ServiceControllerRouter<Platform>::acceptConnection(
|
||||
ConstPtr<AcceptConnectionParams> accept_connection_params) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::AcceptConnectionRequestRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, accept_connection_params)));
|
||||
self_, client_proxy, accept_connection_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -551,7 +551,7 @@ void ServiceControllerRouter<Platform>::rejectConnection(
|
||||
ConstPtr<RejectConnectionParams> reject_connection_params) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::RejectConnectionRequestRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, reject_connection_params)));
|
||||
self_, client_proxy, reject_connection_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -561,7 +561,7 @@ void ServiceControllerRouter<Platform>::initiateBandwidthUpgrade(
|
||||
initiate_bandwidth_upgrade_params) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::InitiateBandwidthUpgradeRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, initiate_bandwidth_upgrade_params)));
|
||||
self_, client_proxy, initiate_bandwidth_upgrade_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -570,7 +570,7 @@ void ServiceControllerRouter<Platform>::sendPayload(
|
||||
ConstPtr<SendPayloadParams> send_payload_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::SendPayloadRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, send_payload_params)));
|
||||
self_, client_proxy, send_payload_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -579,7 +579,7 @@ void ServiceControllerRouter<Platform>::cancelPayload(
|
||||
ConstPtr<CancelPayloadParams> cancel_payload_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::CancelPayloadRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, cancel_payload_params)));
|
||||
self_, client_proxy, cancel_payload_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -588,7 +588,7 @@ void ServiceControllerRouter<Platform>::disconnectFromEndpoint(
|
||||
ConstPtr<DisconnectFromEndpointParams> disconnect_from_endpoint_params) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::DisconnectFromEndpointRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, disconnect_from_endpoint_params)));
|
||||
self_, client_proxy, disconnect_from_endpoint_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -597,7 +597,7 @@ void ServiceControllerRouter<Platform>::stopAllEndpoints(
|
||||
ConstPtr<StopAllEndpointsParams> stop_all_endpoint_params) {
|
||||
routeToServiceController(
|
||||
MakePtr(new service_controller_router::StopAllEndpointsRunnable<Platform>(
|
||||
MakePtr(this), client_proxy, stop_all_endpoint_params)));
|
||||
self_, client_proxy, stop_all_endpoint_params)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
@@ -605,7 +605,7 @@ void ServiceControllerRouter<Platform>::clientDisconnecting(
|
||||
Ptr<ClientProxy<Platform>> client_proxy) {
|
||||
routeToServiceController(MakePtr(
|
||||
new service_controller_router::ClientDisconnectingRunnable<Platform>(
|
||||
MakePtr(this), client_proxy)));
|
||||
self_, client_proxy)));
|
||||
}
|
||||
|
||||
template <typename Platform>
|
||||
|
||||
@@ -140,6 +140,7 @@ class ServiceControllerRouter {
|
||||
Ptr<ServiceController<Platform> > current_service_controller_;
|
||||
Ptr<Strategy> current_strategy_;
|
||||
ScopedPtr<Ptr<typename Platform::SingleThreadExecutorType> > serializer_;
|
||||
std::shared_ptr<ServiceControllerRouter<Platform>> self_{this, [](void*){}};
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
#include "core/internal/wifi_lan_service_info.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "platform/base64_utils.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
Ptr<WifiLanServiceInfo> WifiLanServiceInfo::FromString(
|
||||
absl::string_view wifi_lan_service_info_string) {
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_wifi_lan_service_info_name_bytes(
|
||||
Base64Utils::decode(wifi_lan_service_info_string));
|
||||
if (scoped_wifi_lan_service_info_name_bytes.isNull()) {
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot deserialize
|
||||
// WifiLanServiceInfo: failed Base64 decoding of %s",
|
||||
// WifiLanServiceInfoString);
|
||||
return Ptr<WifiLanServiceInfo>();
|
||||
}
|
||||
|
||||
if (scoped_wifi_lan_service_info_name_bytes->size() >
|
||||
kMaxLanServiceNameLength) {
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot deserialize
|
||||
// WifiLanServiceInfo: expecting max %d raw bytes, got %d",
|
||||
// MAX_WIFILAN_SERVICE_INFO_LENGTH, wifiLanServiceInfoNameBytes.length);
|
||||
return Ptr<WifiLanServiceInfo>();
|
||||
}
|
||||
|
||||
if (scoped_wifi_lan_service_info_name_bytes->size() <
|
||||
kMinLanServiceNameLength) {
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot deserialize
|
||||
// WifiLanServiceInfo: expecting min %d raw bytes, got %d",
|
||||
// MIN_WIFILAN_SERVICE_INFO_LENGTH, wifiLanServiceInfoNameBytes.length);
|
||||
return Ptr<WifiLanServiceInfo>();
|
||||
}
|
||||
|
||||
// The upper 3 bits are supposed to be the version.
|
||||
Version version = static_cast<Version>(
|
||||
(scoped_wifi_lan_service_info_name_bytes->getData()[0] &
|
||||
kVersionBitmask) >>
|
||||
kVersionShift);
|
||||
|
||||
switch (version) {
|
||||
case Version::kV1:
|
||||
return CreateV1WifiLanServiceInfo(
|
||||
ConstifyPtr(scoped_wifi_lan_service_info_name_bytes.get()));
|
||||
|
||||
default:
|
||||
// TODO(b/149806065): [ANALYTICIZE] This either represents corruption over
|
||||
// the air, or older versions of GmsCore intermingling with newer ones.
|
||||
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot deserialize
|
||||
// WifiLanServiceInfo: unsupported Version %d", version);
|
||||
return Ptr<WifiLanServiceInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
std::string WifiLanServiceInfo::AsString(Version version, PCP::Value pcp,
|
||||
absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash) {
|
||||
Ptr<ByteArray> wifi_lan_service_info_name_bytes;
|
||||
switch (version) {
|
||||
case Version::kV1:
|
||||
wifi_lan_service_info_name_bytes =
|
||||
CreateV1Bytes(pcp, endpoint_id, service_id_hash);
|
||||
if (wifi_lan_service_info_name_bytes.isNull()) {
|
||||
return "";
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot serialize
|
||||
// WifiLanServiceInfo: unsupported Version %d", version);
|
||||
return "";
|
||||
}
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_wifi_lan_service_info_name_bytes(
|
||||
wifi_lan_service_info_name_bytes);
|
||||
|
||||
// WifiLanServiceInfo needs to be binary safe, so apply a Base64 encoding
|
||||
// over the raw bytes.
|
||||
return Base64Utils::encode(
|
||||
ConstifyPtr(scoped_wifi_lan_service_info_name_bytes.get()));
|
||||
}
|
||||
|
||||
Ptr<WifiLanServiceInfo> WifiLanServiceInfo::CreateV1WifiLanServiceInfo(
|
||||
ConstPtr<ByteArray> wifi_lan_service_info_name_bytes) {
|
||||
const char* wifi_lan_service_info_name_bytes_read_ptr =
|
||||
wifi_lan_service_info_name_bytes->getData();
|
||||
|
||||
// The lower 5 bits of the V1 payload are supposed to be the PCP.
|
||||
PCP::Value pcp = static_cast<PCP::Value>(
|
||||
*wifi_lan_service_info_name_bytes_read_ptr & kPcpBitmask);
|
||||
wifi_lan_service_info_name_bytes_read_ptr++;
|
||||
|
||||
switch (pcp) {
|
||||
case PCP::P2P_CLUSTER: // Fall through
|
||||
case PCP::P2P_STAR: // Fall through
|
||||
case PCP::P2P_POINT_TO_POINT: {
|
||||
// The next 32 bits are supposed to be the endpoint_id.
|
||||
std::string endpoint_id(wifi_lan_service_info_name_bytes_read_ptr,
|
||||
kEndpointIdLength);
|
||||
wifi_lan_service_info_name_bytes_read_ptr += kEndpointIdLength;
|
||||
|
||||
// The next 24 bits are supposed to be the scoped_service_id_hash.
|
||||
ScopedPtr<ConstPtr<ByteArray> > scoped_service_id_hash(
|
||||
MakeConstPtr(new ByteArray(wifi_lan_service_info_name_bytes_read_ptr,
|
||||
kServiceIdHashLength)));
|
||||
wifi_lan_service_info_name_bytes_read_ptr += kServiceIdHashLength;
|
||||
|
||||
// The next bits are supposed to be endpoint_name.
|
||||
// TODO(b/149806065): Implements it. Temp to set "found_device".
|
||||
std::string endpoint_name("found_device");
|
||||
|
||||
return MakePtr(new WifiLanServiceInfo(Version::kV1, pcp, endpoint_id,
|
||||
scoped_service_id_hash.release(),
|
||||
endpoint_name));
|
||||
}
|
||||
default:
|
||||
// TODO(b/149806065): [ANALYTICIZE] This either represents corruption over
|
||||
// the air, or older versions of GmsCore intermingling with newer ones.
|
||||
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot deserialize
|
||||
// WifiLanServiceInfo: unsupported V1 PCP %d", pcp);
|
||||
return Ptr<WifiLanServiceInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
std::uint32_t WifiLanServiceInfo::ComputeEndpointNameLength(
|
||||
ConstPtr<ByteArray> wifi_lan_service_info_name_bytes) {
|
||||
return kMaxEndpointNameLength -
|
||||
(kMaxLanServiceNameLength - wifi_lan_service_info_name_bytes->size());
|
||||
}
|
||||
|
||||
Ptr<ByteArray> WifiLanServiceInfo::CreateV1Bytes(
|
||||
PCP::Value pcp, absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash) {
|
||||
Ptr<ByteArray> wifi_lan_service_info_name_bytes{
|
||||
new ByteArray{kMinLanServiceNameLength}};
|
||||
|
||||
char* wifi_lan_service_info_name_bytes_write_ptr =
|
||||
wifi_lan_service_info_name_bytes->getData();
|
||||
|
||||
// The upper 3 bits are the Version.
|
||||
char version_and_pcp_byte = static_cast<char>(
|
||||
(static_cast<uint32_t>(Version::kV1) << 5) & kVersionBitmask);
|
||||
// The lower 5 bits are the PCP.
|
||||
version_and_pcp_byte |= static_cast<char>(pcp & kPcpBitmask);
|
||||
*wifi_lan_service_info_name_bytes_write_ptr = version_and_pcp_byte;
|
||||
wifi_lan_service_info_name_bytes_write_ptr++;
|
||||
|
||||
switch (pcp) {
|
||||
case PCP::P2P_CLUSTER: // Fall through
|
||||
case PCP::P2P_STAR: // Fall through
|
||||
case PCP::P2P_POINT_TO_POINT:
|
||||
// The next 32 bits are the endpoint_id.
|
||||
if (endpoint_id.size() != kEndpointIdLength) {
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot serialize
|
||||
// WifiLanServiceInfo: V1 Endpoint ID %s (%d bytes) should be exactly
|
||||
// %d bytes", endpointId, endpointId.length(), ENDPOINT_ID_LENGTH);
|
||||
return Ptr<ByteArray>();
|
||||
}
|
||||
memcpy(wifi_lan_service_info_name_bytes_write_ptr, endpoint_id.data(),
|
||||
kEndpointIdLength);
|
||||
wifi_lan_service_info_name_bytes_write_ptr += kEndpointIdLength;
|
||||
|
||||
// The next 24 bits are the service_id_hash.
|
||||
if (service_id_hash->size() != kServiceIdHashLength) {
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot serialize
|
||||
// WifiLanServiceInfo: V1 ServiceID hash (%d bytes) should be exactly
|
||||
// %d bytes", serviceIdHash.length, SERVICE_ID_HASH_LENGTH);
|
||||
return Ptr<ByteArray>();
|
||||
}
|
||||
memcpy(wifi_lan_service_info_name_bytes_write_ptr,
|
||||
service_id_hash->getData(), kServiceIdHashLength);
|
||||
wifi_lan_service_info_name_bytes_write_ptr += kServiceIdHashLength;
|
||||
|
||||
// The next bits are the endpoint_name.
|
||||
// TODO(b/149806065): Implements to parse endpoint_name.
|
||||
break;
|
||||
default:
|
||||
// TODO(b/149806065): logger.atDebug().log("Cannot serialize
|
||||
// WifiLanServiceInfo: unsupported V1 PCP %d", pcp);
|
||||
return Ptr<ByteArray>();
|
||||
}
|
||||
|
||||
return wifi_lan_service_info_name_bytes;
|
||||
}
|
||||
|
||||
WifiLanServiceInfo::WifiLanServiceInfo(Version version, PCP::Value pcp,
|
||||
absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash,
|
||||
absl::string_view endpoint_name)
|
||||
: version_(version),
|
||||
pcp_(pcp),
|
||||
endpoint_id_(endpoint_id),
|
||||
service_id_hash_(service_id_hash),
|
||||
endpoint_name_(endpoint_name) {}
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
@@ -0,0 +1,96 @@
|
||||
#ifndef CORE_INTERNAL_WIFI_LAN_SERVICE_INFO_H_
|
||||
#define CORE_INTERNAL_WIFI_LAN_SERVICE_INFO_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "core/internal/pcp.h"
|
||||
#include "platform/byte_array.h"
|
||||
#include "platform/port/string.h"
|
||||
#include "platform/ptr.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
|
||||
// Represents the format of the WifiLan service info used in Advertising +
|
||||
// Discovery.
|
||||
//
|
||||
// See go/nearby-offline-data-interchange-formats for the specification.
|
||||
class WifiLanServiceInfo {
|
||||
public:
|
||||
// Versions of the WifiLanServiceInfo.
|
||||
enum class Version {
|
||||
kV1 = 1,
|
||||
};
|
||||
|
||||
// Static method to deserialize from the encrypted string to
|
||||
// WifiLanServiceInfo object.
|
||||
// TODO(b/149762166): Ptr is deprectaed. Uses shrared_ptr<T> or unique_ptr<T>.
|
||||
static Ptr<WifiLanServiceInfo> FromString(
|
||||
absl::string_view wifi_lan_service_info_string);
|
||||
|
||||
// Static method to serialize to encrypted string from WifiLanServiceInfo
|
||||
// object.
|
||||
static std::string AsString(Version version, PCP::Value pcp,
|
||||
absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash);
|
||||
|
||||
static constexpr std::uint32_t kServiceIdHashLength = 3;
|
||||
|
||||
~WifiLanServiceInfo() = default;
|
||||
|
||||
inline Version GetVersion() const { return version_; }
|
||||
inline PCP::Value GetPcp() const { return pcp_; }
|
||||
inline std::string GetEndpointId() const { return endpoint_id_; }
|
||||
inline ConstPtr<ByteArray> GetServiceIdHash() const {
|
||||
return service_id_hash_.get();
|
||||
}
|
||||
inline std::string GetEndpointName() const { return endpoint_name_; }
|
||||
|
||||
private:
|
||||
static Ptr<WifiLanServiceInfo> CreateV1WifiLanServiceInfo(
|
||||
ConstPtr<ByteArray> wifi_lan_service_info_name_bytes);
|
||||
static std::uint32_t ComputeEndpointNameLength(
|
||||
ConstPtr<ByteArray> wifi_lan_service_info_name_bytes);
|
||||
static Ptr<ByteArray> CreateV1Bytes(PCP::Value pcp,
|
||||
absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash);
|
||||
|
||||
// The maximum length of encrypted WifiLanServiceInfo string.
|
||||
static constexpr int kMaxLanServiceNameLength = 47;
|
||||
// The minimum length of encrypted WifiLanServiceInfo string.
|
||||
static constexpr int kMinLanServiceNameLength = 9;
|
||||
// The length for endpoint id in encrypted WifiLanServiceInfo string.
|
||||
static constexpr int kEndpointIdLength = 4;
|
||||
// The maximum length for endpoint id in encrypted WifiLanServiceInfo string.
|
||||
static constexpr int kMaxEndpointNameLength = 131;
|
||||
|
||||
static constexpr uint16 kVersionBitmask = 0x0E0;
|
||||
static constexpr uint16 kPcpBitmask = 0x01F;
|
||||
static constexpr uint16 kVersionShift = 5;
|
||||
|
||||
WifiLanServiceInfo(Version version, PCP::Value pcp,
|
||||
absl::string_view endpoint_id,
|
||||
ConstPtr<ByteArray> service_id_hash,
|
||||
absl::string_view endpoint_name);
|
||||
|
||||
// WifiLanServiceInfo version.
|
||||
const Version version_;
|
||||
// Pre-Connection Protocols version.
|
||||
const PCP::Value pcp_;
|
||||
// Connected endpoint id.
|
||||
const std::string endpoint_id_;
|
||||
// Connected hash service id.
|
||||
ScopedPtr<ConstPtr<ByteArray> > service_id_hash_;
|
||||
// TODO(b/149806065): Replaces endpointName as endPointInfo eventually;
|
||||
// it is not in this version yet for endpointName.
|
||||
// Connected endpoint name.
|
||||
const std::string endpoint_name_;
|
||||
};
|
||||
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
|
||||
#endif // CORE_INTERNAL_WIFI_LAN_SERVICE_INFO_H_
|
||||
@@ -0,0 +1,151 @@
|
||||
#include "core/internal/wifi_lan_service_info.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "platform/base64_utils.h"
|
||||
#include "platform/port/string.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
namespace connections {
|
||||
namespace {
|
||||
|
||||
const WifiLanServiceInfo::Version kVersion = WifiLanServiceInfo::Version::kV1;
|
||||
const PCP::Value kPcp = PCP::P2P_CLUSTER;
|
||||
const char kEndPointID[] = "AB12";
|
||||
const char kServiceIDHashBytes[] = {0x0A, 0x0B, 0x0C};
|
||||
// TODO(b/149806065): Implements test endpoint_name.
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationDeserializationWorks) {
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string = WifiLanServiceInfo::AsString(
|
||||
kVersion, kPcp, kEndPointID, ConstifyPtr(scoped_service_id_hash.get()));
|
||||
ScopedPtr<Ptr<WifiLanServiceInfo> > scoped_wifi_lan_service_info(
|
||||
WifiLanServiceInfo::FromString(wifi_lan_service_info_string));
|
||||
|
||||
EXPECT_EQ(kPcp, scoped_wifi_lan_service_info->GetPcp());
|
||||
EXPECT_EQ(kVersion, scoped_wifi_lan_service_info->GetVersion());
|
||||
EXPECT_EQ(kEndPointID, scoped_wifi_lan_service_info->GetEndpointId());
|
||||
EXPECT_EQ(*scoped_service_id_hash,
|
||||
*(scoped_wifi_lan_service_info->GetServiceIdHash()));
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest,
|
||||
SerializationDeserializationWorksWithEmptyEndpointName) {
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string = WifiLanServiceInfo::AsString(
|
||||
kVersion, kPcp, kEndPointID, ConstifyPtr(scoped_service_id_hash.get()));
|
||||
ScopedPtr<Ptr<WifiLanServiceInfo> > scoped_wifi_lan_service_info(
|
||||
WifiLanServiceInfo::FromString(wifi_lan_service_info_string));
|
||||
|
||||
EXPECT_EQ(kPcp, scoped_wifi_lan_service_info->GetPcp());
|
||||
EXPECT_EQ(kVersion, scoped_wifi_lan_service_info->GetVersion());
|
||||
EXPECT_EQ(kEndPointID, scoped_wifi_lan_service_info->GetEndpointId());
|
||||
EXPECT_EQ(*scoped_service_id_hash,
|
||||
*(scoped_wifi_lan_service_info->GetServiceIdHash()));
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithBadVersion) {
|
||||
WifiLanServiceInfo::Version bad_version =
|
||||
static_cast<WifiLanServiceInfo::Version>(666);
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string =
|
||||
WifiLanServiceInfo::AsString(bad_version, kPcp, kEndPointID,
|
||||
ConstifyPtr(scoped_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithBadPCP) {
|
||||
PCP::Value bad_pcp = static_cast<PCP::Value>(666);
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string =
|
||||
WifiLanServiceInfo::AsString(kVersion, bad_pcp, kEndPointID,
|
||||
ConstifyPtr(scoped_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithShortEndpointId) {
|
||||
std::string short_endpoint_id("AB1");
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string =
|
||||
WifiLanServiceInfo::AsString(kVersion, kPcp, short_endpoint_id,
|
||||
ConstifyPtr(scoped_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithLongEndpointId) {
|
||||
std::string long_endpoint_id("AB12X");
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_service_id_hash(new ByteArray(
|
||||
kServiceIDHashBytes, sizeof(kServiceIDHashBytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string =
|
||||
WifiLanServiceInfo::AsString(kVersion, kPcp, long_endpoint_id,
|
||||
ConstifyPtr(scoped_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithShortServiceIdHash) {
|
||||
char short_service_id_hash_bytes[] = {0x0A, 0x0B};
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_short_service_id_hash(
|
||||
new ByteArray(short_service_id_hash_bytes,
|
||||
sizeof(short_service_id_hash_bytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string = WifiLanServiceInfo::AsString(
|
||||
kVersion, kPcp, kEndPointID,
|
||||
ConstifyPtr(scoped_short_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, SerializationFailsWithLongServiceIdHash) {
|
||||
char long_service_id_hash_bytes[] = {0x0A, 0x0B, 0x0C, 0x0D};
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_long_service_id_hash(
|
||||
new ByteArray(long_service_id_hash_bytes,
|
||||
sizeof(long_service_id_hash_bytes) / sizeof(char)));
|
||||
|
||||
std::string wifi_lan_service_info_string = WifiLanServiceInfo::AsString(
|
||||
kVersion, kPcp, kEndPointID,
|
||||
ConstifyPtr(scoped_long_service_id_hash.get()));
|
||||
|
||||
EXPECT_TRUE(wifi_lan_service_info_string.empty());
|
||||
}
|
||||
|
||||
TEST(WifiLanServiceInfoTest, DeserializationFailsWithShortLength) {
|
||||
char wifi_lan_service_info_bytes[] = {'X'};
|
||||
|
||||
ScopedPtr<Ptr<ByteArray> > scoped_wifi_lan_service_info_bytes(
|
||||
new ByteArray(wifi_lan_service_info_bytes,
|
||||
sizeof(wifi_lan_service_info_bytes) / sizeof(char)));
|
||||
|
||||
ScopedPtr<Ptr<WifiLanServiceInfo> > scoped_wifi_lan_service_info(
|
||||
WifiLanServiceInfo::FromString(Base64Utils::encode(
|
||||
ConstifyPtr(scoped_wifi_lan_service_info_bytes.get()))));
|
||||
|
||||
EXPECT_TRUE(scoped_wifi_lan_service_info.isNull());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
} // namespace location
|
||||
Reference in New Issue
Block a user