Merge pull request #1153 from google/master

Merge main
This commit is contained in:
jgsobczak
2022-12-20 10:31:11 -08:00
committed by GitHub
2045 changed files with 157149 additions and 77234 deletions
+37
View File
@@ -0,0 +1,37 @@
name: Validate
on: [push, pull_request]
env:
FORCE_COLOR: true
jobs:
build-swift:
name: Build Swift
runs-on: macOS-latest
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Build
run: swift build
test-swift:
name: Test Swift
runs-on: macOS-latest
steps:
- uses: actions/checkout@v3
with:
submodules: true
- name: Test
run: swift test
build-linux:
name: Build Linux
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Build
run: CC=clang CXX=clang++ bazel build --check_visibility=false //connections:core --spawn_strategy=standalone
+1 -1
View File
@@ -29,7 +29,7 @@ This project follows [Google's Open Source Community
Guidelines](https://opensource.google.com/conduct/).
## Last Updated
Jaunary 2022
January 2022
## Copybara Manual Sync Dates
2022-02-25
+22
View File
@@ -1,3 +1,25 @@
MIT License
Copyright (c) 2013-2022 Niels Lohmann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Apache License
Version 2.0, January 2004
+1 -1
View File
@@ -6,7 +6,7 @@
"repositoryURL": "https://github.com/firebase/abseil-cpp-SwiftPM.git",
"state": {
"branch": "main",
"revision": "d302de612e3d57c6f4afaf087da18fba8eac72a7",
"revision": "da43cbe34db0763a8eaf986ebda8510e7820d7f7",
"version": null
}
},
+115 -42
View File
@@ -4,12 +4,22 @@ import PackageDescription
let package = Package(
name: "NearbyConnections",
platforms: [
.iOS(.v11),
.macOS(.v10_13),
.tvOS(.v11),
.watchOS(.v4),
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "NearbyCoreAdapter",
targets: ["NearbyCoreAdapter"]
),
.library(
name: "NearbyConnections",
targets: ["NearbyConnections"]
)
),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
@@ -122,6 +132,7 @@ let package = Package(
name: "smhasher",
path: "third_party/smhasher",
exclude: [
"include",
"smhasher/src/CMakeLists.txt",
"smhasher/src/main.cpp",
"smhasher/README.md",
@@ -359,7 +370,7 @@ let package = Package(
]
),
.target(
name: "NearbyConnections",
name: "NearbyCoreAdapter",
dependencies: [
"google-toolbox-for-mac",
"smhasher",
@@ -369,12 +380,18 @@ let package = Package(
],
path: ".",
exclude: [
"presence",
"embedded",
"connections/clients/windows",
"connections/clients/ios",
"connections/samples/ios",
"connections/clients/swift/NearbyConnections",
"connections/clients/swift/NearbyCoreAdapter/BUILD",
"connections/clients/swift/NearbyCoreAdapter/Tests",
"connections/samples",
"docs",
"internal/platform/implementation/g3",
"internal/platform/implementation/ios",
"internal/platform/implementation/ios/Tests",
"internal/platform/implementation/ios/Mediums/Ble/Sockets/Tests",
"internal/platform/implementation/windows",
"third_party",
"CONTRIBUTING.md",
@@ -382,27 +399,23 @@ let package = Package(
"README.md",
"WORKSPACE",
// build files
"connections/clients/ios/BUILD",
"connections/implementation/proto/BUILD",
"connections/implementation/proto/CMakeLists.txt",
"connections/implementation/analytics/BUILD",
"connections/implementation/mediums/ble_v2/BUILD",
"connections/implementation/mediums/BUILD",
"connections/implementation/mediums/webrtc/BUILD",
"connections/implementation/BUILD",
"connections/implementation/fuzzers/BUILD",
"connections/implementation/fuzzers",
"connections/BUILD",
"internal/proto/analytics/BUILD",
"internal/BUILD",
"internal/crypto/BUILD",
"internal/crypto/BUILD.gn",
"internal/platform/implementation/shared/BUILD",
"internal/platform/implementation/ios/Mediums/BUILD",
"internal/platform/implementation/ios/Mediums/Ble/Sockets/BUILD",
"internal/platform/implementation/ios/Tests/BUILD",
"internal/platform/implementation/ios/BUILD",
"internal/platform/implementation/BUILD",
"internal/platform/BUILD",
"internal/analytics/BUILD",
"proto/mediums/BUILD",
"proto/errorcode/BUILD",
"proto/BUILD",
"proto/CMakeLists.txt",
// tests
"connections/listeners_test.cc",
"connections/strategy_test.cc",
@@ -410,6 +423,7 @@ let package = Package(
"connections/implementation/offline_service_controller_test.cc",
"connections/implementation/encryption_runner_test.cc",
"connections/implementation/p2p_cluster_pcp_handler_test.cc",
"connections/implementation/p2p_point_to_point_pcp_handler_test.cc",
"connections/implementation/base_pcp_handler_test.cc",
"connections/implementation/injected_bluetooth_device_store_test.cc",
"connections/implementation/internal_payload_factory_test.cc",
@@ -417,9 +431,11 @@ let package = Package(
"connections/implementation/payload_manager_test.cc",
"connections/implementation/offline_frames_validator_test.cc",
"connections/implementation/service_controller_router_test.cc",
"connections/implementation/wifi_hotspot_test.cc",
"connections/implementation/analytics/analytics_recorder_test.cc",
"connections/implementation/analytics/throughput_recorder_test.cc",
"connections/implementation/mediums/ble_v2_test.cc",
"connections/implementation/mediums/ble_v2/bloom_filter_test.cc",
"connections/implementation/mediums/ble_v2/ble_peripheral_test.cc",
"connections/implementation/mediums/ble_v2/ble_packet_test.cc",
"connections/implementation/mediums/ble_v2/ble_advertisement_test.cc",
"connections/implementation/mediums/ble_v2/advertisement_read_result_test.cc",
@@ -432,14 +448,13 @@ let package = Package(
"connections/implementation/mediums/ble_test.cc",
"connections/implementation/mediums/webrtc_test.cc",
"connections/implementation/mediums/lost_entity_tracker_test.cc",
"connections/implementation/mediums/uuid_test.cc",
"connections/implementation/mediums/webrtc/connection_flow_test.cc",
"connections/implementation/mediums/webrtc/webrtc_socket_impl_test.cc",
"connections/implementation/mediums/webrtc/signaling_frames_test.cc",
"connections/implementation/mediums/bluetooth_radio_test.cc",
"connections/implementation/mediums/wifi_direct_test.cc",
"connections/implementation/mediums/wifi_hotspot_test.cc",
"connections/implementation/mediums/wifi_test.cc",
"connections/implementation/endpoint_channel_manager_test.cc",
"connections/implementation/bwu_manager_test.cc",
"connections/implementation/base_bwu_handler_test.cc",
"connections/implementation/endpoint_manager_test.cc",
"connections/implementation/bluetooth_device_name_test.cc",
"connections/implementation/wifi_lan_service_info_test.cc",
@@ -449,25 +464,44 @@ let package = Package(
"connections/core_test.cc",
"connections/status_test.cc",
"connections/payload_test.cc",
"internal/crypto/aead_unittest.cc",
"internal/crypto/ec_private_key_unittest.cc",
"internal/crypto/ec_signature_creator_unittest.cc",
"internal/crypto/encryptor_unittest.cc",
"internal/crypto/hmac_unittest.cc",
"internal/crypto/random_unittest.cc",
"internal/crypto/rsa_private_key_unittest.cc",
"internal/crypto/secure_hash_unittest.cc",
"internal/crypto/sha2_unittest.cc",
"internal/crypto/signature_verifier_unittest.cc",
"internal/crypto/symmetric_key_unittest.cc",
"internal/proto/analytics/connections_log_test.cc",
"internal/platform/feature_flags_test.cc",
"internal/platform/cancelable_alarm_test.cc",
"internal/platform/crypto_test.cc",
"internal/platform/byte_array_test.cc",
"internal/platform/bluetooth_utils_test.cc",
"internal/platform/credential_storage_impl_test.cc",
"internal/platform/single_thread_executor_test.cc",
"internal/platform/scheduled_executor_test.cc",
"internal/platform/count_down_latch_test.cc",
"internal/platform/pipe_test.cc",
"internal/platform/uuid_test.cc",
"internal/platform/wifi_lan_connection_info_test.cc",
"internal/platform/wifi_direct_test.cc",
"internal/platform/wifi_hotspot_test.cc",
"internal/platform/wifi_lan_test.cc",
"internal/platform/wifi_test.cc",
"internal/platform/wifi_utils_test.cc",
"internal/platform/condition_variable_test.cc",
"internal/platform/thread_check_nocompile_test.py",
"internal/platform/bluetooth_classic_test.cc",
"internal/platform/bluetooth_connection_info_test.cc",
"internal/platform/mutex_test.cc",
"internal/platform/atomic_reference_test.cc",
"internal/platform/logging_test.cc",
"internal/platform/multi_thread_executor_test.cc",
"internal/platform/ble_connection_info_test.cc",
"internal/platform/ble_test.cc",
"internal/platform/ble_v2_test.cc",
"internal/platform/prng_test.cc",
@@ -484,50 +518,89 @@ let package = Package(
"internal/platform/cancellation_flag_test.cc",
"internal/platform/bluetooth_adapter_test.cc",
"internal/platform/byte_utils_test.cc",
"internal/analytics/analytics_recorder_test.cc",
"internal/platform/direct_executor_test.cc",
"internal/platform/borrowable_test.cc",
// simulation
"connections/implementation/offline_simulation_user.cc",
"connections/implementation/simulation_user.cc",
// proto
"connections/implementation/proto/offline_wire_formats.proto",
"connections/implementation/proto/offline_wire_formats_proto_config.asciipb",
"internal/proto/analytics/connections_log.proto",
"proto/connections_enums.proto",
"proto/connections_enums_proto_config.asciipb",
"proto/mediums/nfc_frames.proto",
"proto/mediums/ble_frames.proto",
"proto/mediums/ble_frames_portable_proto_config.asciipb",
"proto/mediums/web_rtc_signaling_frames.proto",
"proto/mediums/wifi_aware_frames.proto",
"proto/errorcode/error_code_enums.proto",
"proto/errorcode/error_code_enums_proto_config.asciipb",
"proto/sharing_enums.proto",
"connections/implementation/proto",
"internal/proto",
"proto",
// webrtc
"connections/implementation/webrtc_bwu_handler.cc",
"connections/implementation/webrtc_endpoint_channel.cc",
"connections/implementation/mediums/webrtc.cc",
"connections/implementation/mediums/webrtc/webrtc_socket_impl.cc",
"connections/implementation/mediums/webrtc/signaling_frames.cc",
"connections/implementation/mediums/webrtc/connection_flow.cc",
"connections/implementation/mediums/webrtc_peer_id.cc",
"connections/implementation/mediums/webrtc",
// This breaks the build, but seems to work fine without it?
"internal/platform/medium_environment.cc",
],
sources: [
"compiled_proto",
"connections",
"internal",
"proto",
],
publicHeadersPath: "connections/clients/ios/Public",
publicHeadersPath: "connections/clients/swift/NearbyCoreAdapter/Sources/Public",
cSettings: [
.headerSearchPath("./"),
.headerSearchPath("compiled_proto/"),
.define("NO_WEBRTC"),
.define("NEARBY_SWIFTPM"),
],
linkerSettings: [
.linkedLibrary("c++"),
.linkedFramework("CoreBluetooth"),
.linkedFramework("CoreFoundation"),
]
),
.target(
name: "NearbyConnections",
dependencies: ["NearbyCoreAdapter"],
path: ".",
exclude: [
"compiled_proto",
"connections/clients/windows",
"connections/clients/ios",
"connections/clients/swift/NearbyCoreAdapter",
"connections/clients/swift/NearbyConnections/BUILD",
"connections/clients/swift/NearbyConnections/Tests",
"connections/BUILD",
"connections/discovery_options.cc",
"connections/status.cc",
"connections/listeners_test.cc",
"connections/advertising_options.cc",
"connections/payload.cc",
"connections/strategy_test.cc",
"connections/connection_options.cc",
"connections/core_test.cc",
"connections/status_test.cc",
"connections/core.cc",
"connections/strategy.cc",
"connections/payload_test.cc",
"connections/implementation",
"connections/samples",
"docs",
"embedded",
"internal",
"presence",
"proto",
"third_party",
"CONTRIBUTING.md",
"LICENSE",
"README.md",
"WORKSPACE",
],
sources: [
"connections/clients/swift/NearbyConnections/Sources"
]
),
.testTarget(
name: "NearbyCoreAdapterTests",
dependencies: ["NearbyCoreAdapter"],
path: "connections/clients/swift/NearbyCoreAdapter/Tests"
),
.testTarget(
name: "NearbyConnectionsTests",
dependencies: ["NearbyConnections"],
path: "connections/clients/swift/NearbyConnections/Tests"
),
],
cLanguageStandard: .c99,
cxxLanguageStandard: CXXLanguageStandard.gnucxx14
+4 -8
View File
@@ -30,7 +30,7 @@ We support multiple platforms including Linux, iOS & Windows.
## Building for Linux
Currently we support building from source using [bazel] (https://bazel.build). Other BUILD system such as cmake may be added later.
###Prerequisites:
### Prerequisites:
1. Bazel
2. clang with support for c++ 17+
@@ -48,7 +48,7 @@ CC=clang CXX=clang++ bazel build -s --check_visibility=false //connections:core
Currently we support building with [Swift Package Manager](https://www.swift.org/package-manager).
###Prerequisites:
### Prerequisites:
1. Xcode. Available from Apple Store.
2. Google Protobuf Compiler (protoc). If you have [homebrew](https://brew.sh/) installed, you can do `brew install protobuf`.
@@ -59,11 +59,7 @@ To build the Nearby Connection library:
swift build
```
We also provide a iOS [sample app using the Nearby Connections library]
(https://github.com/google/nearby/blob/master/internal/platform/implementation/ios/Example/NearbyConnectionsExample/README.md).
###Limitation
### Limitation
The only Medium supported is Wifi LAN.
**Last Updated:** April 7, 2022
**Last Updated:** December 7, 2022
@@ -209,6 +209,7 @@ constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials
::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
: ssid_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
, password_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
, gateway_(nullptr)
, port_(0)
, frequency_(0){}
struct BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentialsDefaultTypeInternal {
@@ -606,13 +607,14 @@ bool ConnectionRequestFrame_Medium_IsValid(int value) {
case 8:
case 9:
case 10:
case 11:
return true;
default:
return false;
}
}
static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<std::string> ConnectionRequestFrame_Medium_strings[11] = {};
static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<std::string> ConnectionRequestFrame_Medium_strings[12] = {};
static const char ConnectionRequestFrame_Medium_names[] =
"BLE"
@@ -621,6 +623,7 @@ static const char ConnectionRequestFrame_Medium_names[] =
"MDNS"
"NFC"
"UNKNOWN_MEDIUM"
"USB"
"WEB_RTC"
"WIFI_AWARE"
"WIFI_DIRECT"
@@ -634,25 +637,27 @@ static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry ConnectionRequestFrame
{ {ConnectionRequestFrame_Medium_names + 21, 4}, 1 },
{ {ConnectionRequestFrame_Medium_names + 25, 3}, 7 },
{ {ConnectionRequestFrame_Medium_names + 28, 14}, 0 },
{ {ConnectionRequestFrame_Medium_names + 42, 7}, 9 },
{ {ConnectionRequestFrame_Medium_names + 49, 10}, 6 },
{ {ConnectionRequestFrame_Medium_names + 59, 11}, 8 },
{ {ConnectionRequestFrame_Medium_names + 70, 12}, 3 },
{ {ConnectionRequestFrame_Medium_names + 82, 8}, 5 },
{ {ConnectionRequestFrame_Medium_names + 42, 3}, 11 },
{ {ConnectionRequestFrame_Medium_names + 45, 7}, 9 },
{ {ConnectionRequestFrame_Medium_names + 52, 10}, 6 },
{ {ConnectionRequestFrame_Medium_names + 62, 11}, 8 },
{ {ConnectionRequestFrame_Medium_names + 73, 12}, 3 },
{ {ConnectionRequestFrame_Medium_names + 85, 8}, 5 },
};
static const int ConnectionRequestFrame_Medium_entries_by_number[] = {
5, // 0 -> UNKNOWN_MEDIUM
3, // 1 -> MDNS
2, // 2 -> BLUETOOTH
9, // 3 -> WIFI_HOTSPOT
10, // 3 -> WIFI_HOTSPOT
0, // 4 -> BLE
10, // 5 -> WIFI_LAN
7, // 6 -> WIFI_AWARE
11, // 5 -> WIFI_LAN
8, // 6 -> WIFI_AWARE
4, // 7 -> NFC
8, // 8 -> WIFI_DIRECT
6, // 9 -> WEB_RTC
9, // 8 -> WIFI_DIRECT
7, // 9 -> WEB_RTC
1, // 10 -> BLE_L2CAP
6, // 11 -> USB
};
const std::string& ConnectionRequestFrame_Medium_Name(
@@ -661,12 +666,12 @@ const std::string& ConnectionRequestFrame_Medium_Name(
::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings(
ConnectionRequestFrame_Medium_entries,
ConnectionRequestFrame_Medium_entries_by_number,
11, ConnectionRequestFrame_Medium_strings);
12, ConnectionRequestFrame_Medium_strings);
(void) dummy;
int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName(
ConnectionRequestFrame_Medium_entries,
ConnectionRequestFrame_Medium_entries_by_number,
11, value);
12, value);
return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() :
ConnectionRequestFrame_Medium_strings[idx].get();
}
@@ -674,7 +679,7 @@ bool ConnectionRequestFrame_Medium_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, ConnectionRequestFrame_Medium* value) {
int int_value;
bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue(
ConnectionRequestFrame_Medium_entries, 11, name, &int_value);
ConnectionRequestFrame_Medium_entries, 12, name, &int_value);
if (success) {
*value = static_cast<ConnectionRequestFrame_Medium>(int_value);
}
@@ -692,6 +697,7 @@ constexpr ConnectionRequestFrame_Medium ConnectionRequestFrame::NFC;
constexpr ConnectionRequestFrame_Medium ConnectionRequestFrame::WIFI_DIRECT;
constexpr ConnectionRequestFrame_Medium ConnectionRequestFrame::WEB_RTC;
constexpr ConnectionRequestFrame_Medium ConnectionRequestFrame::BLE_L2CAP;
constexpr ConnectionRequestFrame_Medium ConnectionRequestFrame::USB;
constexpr ConnectionRequestFrame_Medium ConnectionRequestFrame::Medium_MIN;
constexpr ConnectionRequestFrame_Medium ConnectionRequestFrame::Medium_MAX;
constexpr int ConnectionRequestFrame::Medium_ARRAYSIZE;
@@ -1018,13 +1024,14 @@ bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_IsValid(int value)
case 7:
case 8:
case 9:
case 11:
return true;
default:
return false;
}
}
static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<std::string> BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_strings[10] = {};
static ::PROTOBUF_NAMESPACE_ID::internal::ExplicitlyConstructed<std::string> BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_strings[11] = {};
static const char BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names[] =
"BLE"
@@ -1032,6 +1039,7 @@ static const char BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names[
"MDNS"
"NFC"
"UNKNOWN_MEDIUM"
"USB"
"WEB_RTC"
"WIFI_AWARE"
"WIFI_DIRECT"
@@ -1044,24 +1052,26 @@ static const ::PROTOBUF_NAMESPACE_ID::internal::EnumEntry BandwidthUpgradeNegoti
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 12, 4}, 1 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 16, 3}, 7 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 19, 14}, 0 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 33, 7}, 9 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 40, 10}, 6 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 50, 11}, 8 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 61, 12}, 3 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 73, 8}, 5 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 33, 3}, 11 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 36, 7}, 9 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 43, 10}, 6 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 53, 11}, 8 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 64, 12}, 3 },
{ {BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_names + 76, 8}, 5 },
};
static const int BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_entries_by_number[] = {
4, // 0 -> UNKNOWN_MEDIUM
2, // 1 -> MDNS
1, // 2 -> BLUETOOTH
8, // 3 -> WIFI_HOTSPOT
9, // 3 -> WIFI_HOTSPOT
0, // 4 -> BLE
9, // 5 -> WIFI_LAN
6, // 6 -> WIFI_AWARE
10, // 5 -> WIFI_LAN
7, // 6 -> WIFI_AWARE
3, // 7 -> NFC
7, // 8 -> WIFI_DIRECT
5, // 9 -> WEB_RTC
8, // 8 -> WIFI_DIRECT
6, // 9 -> WEB_RTC
5, // 11 -> USB
};
const std::string& BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_Name(
@@ -1070,12 +1080,12 @@ const std::string& BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_Name(
::PROTOBUF_NAMESPACE_ID::internal::InitializeEnumStrings(
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_entries,
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_entries_by_number,
10, BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_strings);
11, BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_strings);
(void) dummy;
int idx = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumName(
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_entries,
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_entries_by_number,
10, value);
11, value);
return idx == -1 ? ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString() :
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_strings[idx].get();
}
@@ -1083,7 +1093,7 @@ bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium* value) {
int int_value;
bool success = ::PROTOBUF_NAMESPACE_ID::internal::LookUpEnumValue(
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_entries, 10, name, &int_value);
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_entries, 11, name, &int_value);
if (success) {
*value = static_cast<BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium>(int_value);
}
@@ -1100,6 +1110,7 @@ constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium BandwidthUpgra
constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium BandwidthUpgradeNegotiationFrame_UpgradePathInfo::NFC;
constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium BandwidthUpgradeNegotiationFrame_UpgradePathInfo::WIFI_DIRECT;
constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium BandwidthUpgradeNegotiationFrame_UpgradePathInfo::WEB_RTC;
constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium BandwidthUpgradeNegotiationFrame_UpgradePathInfo::USB;
constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium BandwidthUpgradeNegotiationFrame_UpgradePathInfo::Medium_MIN;
constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium BandwidthUpgradeNegotiationFrame_UpgradePathInfo::Medium_MAX;
constexpr int BandwidthUpgradeNegotiationFrame_UpgradePathInfo::Medium_ARRAYSIZE;
@@ -5414,13 +5425,17 @@ class BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_I
(*has_bits)[0] |= 2u;
}
static void set_has_port(HasBits* has_bits) {
(*has_bits)[0] |= 4u;
(*has_bits)[0] |= 8u;
}
static void set_has_frequency(HasBits* has_bits) {
(*has_bits)[0] |= 8u;
(*has_bits)[0] |= 16u;
}
static void set_has_gateway(HasBits* has_bits) {
(*has_bits)[0] |= 4u;
}
};
const ::PROTOBUF_NAMESPACE_ID::internal::LazyString BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_i_give_permission_to_break_this_code_default_gateway_{{{"0.0.0.0", 7}}, {nullptr}};
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::MessageLite(arena, is_message_owned) {
@@ -5450,6 +5465,11 @@ BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::Bandwidt
password_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_password(),
GetArenaForAllocation());
}
gateway_.UnsafeSetDefault(nullptr);
if (from._internal_has_gateway()) {
gateway_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, from._internal_gateway(),
GetArenaForAllocation());
}
::memcpy(&port_, &from.port_,
static_cast<size_t>(reinterpret_cast<char*>(&frequency_) -
reinterpret_cast<char*>(&port_)) + sizeof(frequency_));
@@ -5465,6 +5485,7 @@ password_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlr
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
password_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
gateway_.UnsafeSetDefault(nullptr);
::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
reinterpret_cast<char*>(&port_) - reinterpret_cast<char*>(this)),
0, static_cast<size_t>(reinterpret_cast<char*>(&frequency_) -
@@ -5482,6 +5503,7 @@ inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
ssid_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
password_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
gateway_.DestroyNoArena(nullptr);
}
void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::ArenaDtor(void* object) {
@@ -5501,15 +5523,18 @@ void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::Cle
(void) cached_has_bits;
cached_has_bits = _has_bits_[0];
if (cached_has_bits & 0x00000003u) {
if (cached_has_bits & 0x00000007u) {
if (cached_has_bits & 0x00000001u) {
ssid_.ClearNonDefaultToEmpty();
}
if (cached_has_bits & 0x00000002u) {
password_.ClearNonDefaultToEmpty();
}
if (cached_has_bits & 0x00000004u) {
gateway_.ClearToDefault(::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_i_give_permission_to_break_this_code_default_gateway_, GetArenaForAllocation());
}
}
if (cached_has_bits & 0x0000000cu) {
if (cached_has_bits & 0x00000018u) {
::memset(&port_, 0, static_cast<size_t>(
reinterpret_cast<char*>(&frequency_) -
reinterpret_cast<char*>(&port_)) + sizeof(frequency_));
@@ -5561,6 +5586,15 @@ const char* BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia
} else
goto handle_unusual;
continue;
// optional string gateway = 5 [default = "0.0.0.0"];
case 5:
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
auto str = _internal_mutable_gateway();
ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
CHK_(ptr);
} else
goto handle_unusual;
continue;
default:
goto handle_unusual;
} // switch
@@ -5605,17 +5639,23 @@ uint8_t* BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials:
}
// optional int32 port = 3;
if (cached_has_bits & 0x00000004u) {
if (cached_has_bits & 0x00000008u) {
target = stream->EnsureSpace(target);
target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(3, this->_internal_port(), target);
}
// optional int32 frequency = 4;
if (cached_has_bits & 0x00000008u) {
if (cached_has_bits & 0x00000010u) {
target = stream->EnsureSpace(target);
target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(4, this->_internal_frequency(), target);
}
// optional string gateway = 5 [default = "0.0.0.0"];
if (cached_has_bits & 0x00000004u) {
target = stream->WriteStringMaybeAliased(
5, this->_internal_gateway(), target);
}
if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
target = stream->WriteRaw(_internal_metadata_.unknown_fields<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(),
static_cast<int>(_internal_metadata_.unknown_fields<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target);
@@ -5633,7 +5673,7 @@ size_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::B
(void) cached_has_bits;
cached_has_bits = _has_bits_[0];
if (cached_has_bits & 0x0000000fu) {
if (cached_has_bits & 0x0000001fu) {
// optional string ssid = 1;
if (cached_has_bits & 0x00000001u) {
total_size += 1 +
@@ -5648,13 +5688,20 @@ size_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::B
this->_internal_password());
}
// optional int32 port = 3;
// optional string gateway = 5 [default = "0.0.0.0"];
if (cached_has_bits & 0x00000004u) {
total_size += 1 +
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
this->_internal_gateway());
}
// optional int32 port = 3;
if (cached_has_bits & 0x00000008u) {
total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_port());
}
// optional int32 frequency = 4;
if (cached_has_bits & 0x00000008u) {
if (cached_has_bits & 0x00000010u) {
total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int32SizePlusOne(this->_internal_frequency());
}
@@ -5680,7 +5727,7 @@ void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::Mer
(void) cached_has_bits;
cached_has_bits = from._has_bits_[0];
if (cached_has_bits & 0x0000000fu) {
if (cached_has_bits & 0x0000001fu) {
if (cached_has_bits & 0x00000001u) {
_internal_set_ssid(from._internal_ssid());
}
@@ -5688,9 +5735,12 @@ void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::Mer
_internal_set_password(from._internal_password());
}
if (cached_has_bits & 0x00000004u) {
port_ = from.port_;
_internal_set_gateway(from._internal_gateway());
}
if (cached_has_bits & 0x00000008u) {
port_ = from.port_;
}
if (cached_has_bits & 0x00000010u) {
frequency_ = from.frequency_;
}
_has_bits_[0] |= cached_has_bits;
@@ -5725,6 +5775,11 @@ void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::Int
&password_, lhs_arena,
&other->password_, rhs_arena
);
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
nullptr,
&gateway_, lhs_arena,
&other->gateway_, rhs_arena
);
::PROTOBUF_NAMESPACE_ID::internal::memswap<
PROTOBUF_FIELD_OFFSET(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials, frequency_)
+ sizeof(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::frequency_)
@@ -13,7 +13,7 @@
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3019004 < PROTOBUF_MIN_PROTOC_VERSION
#if 3019001 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
@@ -234,11 +234,12 @@ enum ConnectionRequestFrame_Medium : int {
ConnectionRequestFrame_Medium_NFC = 7,
ConnectionRequestFrame_Medium_WIFI_DIRECT = 8,
ConnectionRequestFrame_Medium_WEB_RTC = 9,
ConnectionRequestFrame_Medium_BLE_L2CAP = 10
ConnectionRequestFrame_Medium_BLE_L2CAP = 10,
ConnectionRequestFrame_Medium_USB = 11
};
bool ConnectionRequestFrame_Medium_IsValid(int value);
constexpr ConnectionRequestFrame_Medium ConnectionRequestFrame_Medium_Medium_MIN = ConnectionRequestFrame_Medium_UNKNOWN_MEDIUM;
constexpr ConnectionRequestFrame_Medium ConnectionRequestFrame_Medium_Medium_MAX = ConnectionRequestFrame_Medium_BLE_L2CAP;
constexpr ConnectionRequestFrame_Medium ConnectionRequestFrame_Medium_Medium_MAX = ConnectionRequestFrame_Medium_USB;
constexpr int ConnectionRequestFrame_Medium_Medium_ARRAYSIZE = ConnectionRequestFrame_Medium_Medium_MAX + 1;
const std::string& ConnectionRequestFrame_Medium_Name(ConnectionRequestFrame_Medium value);
@@ -360,11 +361,12 @@ enum BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium : int {
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_WIFI_AWARE = 6,
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_NFC = 7,
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_WIFI_DIRECT = 8,
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_WEB_RTC = 9
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_WEB_RTC = 9,
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_USB = 11
};
bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_IsValid(int value);
constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_Medium_MIN = BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_UNKNOWN_MEDIUM;
constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_Medium_MAX = BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_WEB_RTC;
constexpr BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_Medium_MAX = BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_USB;
constexpr int BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_Medium_ARRAYSIZE = BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_Medium_MAX + 1;
const std::string& BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_Name(BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium value);
@@ -1064,6 +1066,8 @@ class ConnectionRequestFrame final :
ConnectionRequestFrame_Medium_WEB_RTC;
static constexpr Medium BLE_L2CAP =
ConnectionRequestFrame_Medium_BLE_L2CAP;
static constexpr Medium USB =
ConnectionRequestFrame_Medium_USB;
static inline bool Medium_IsValid(int value) {
return ConnectionRequestFrame_Medium_IsValid(value);
}
@@ -3232,6 +3236,7 @@ class BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials fin
enum : int {
kSsidFieldNumber = 1,
kPasswordFieldNumber = 2,
kGatewayFieldNumber = 5,
kPortFieldNumber = 3,
kFrequencyFieldNumber = 4,
};
@@ -3271,6 +3276,24 @@ class BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials fin
std::string* _internal_mutable_password();
public:
// optional string gateway = 5 [default = "0.0.0.0"];
bool has_gateway() const;
private:
bool _internal_has_gateway() const;
public:
void clear_gateway();
const std::string& gateway() const;
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_gateway(ArgT0&& arg0, ArgT... args);
std::string* mutable_gateway();
PROTOBUF_NODISCARD std::string* release_gateway();
void set_allocated_gateway(std::string* gateway);
private:
const std::string& _internal_gateway() const;
inline PROTOBUF_ALWAYS_INLINE void _internal_set_gateway(const std::string& value);
std::string* _internal_mutable_gateway();
public:
// optional int32 port = 3;
bool has_port() const;
private:
@@ -3308,6 +3331,8 @@ class BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials fin
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr ssid_;
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr password_;
static const ::PROTOBUF_NAMESPACE_ID::internal::LazyString _i_give_permission_to_break_this_code_default_gateway_;
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr gateway_;
int32_t port_;
int32_t frequency_;
friend struct ::TableStruct_connections_2fimplementation_2fproto_2foffline_5fwire_5fformats_2eproto;
@@ -3619,6 +3644,8 @@ class BandwidthUpgradeNegotiationFrame_UpgradePathInfo final :
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_WIFI_DIRECT;
static constexpr Medium WEB_RTC =
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_WEB_RTC;
static constexpr Medium USB =
BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_USB;
static inline bool Medium_IsValid(int value) {
return BandwidthUpgradeNegotiationFrame_UpgradePathInfo_Medium_IsValid(value);
}
@@ -9280,7 +9307,7 @@ inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia
// optional int32 port = 3;
inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_has_port() const {
bool value = (_has_bits_[0] & 0x00000004u) != 0;
bool value = (_has_bits_[0] & 0x00000008u) != 0;
return value;
}
inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::has_port() const {
@@ -9288,7 +9315,7 @@ inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia
}
inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::clear_port() {
port_ = 0;
_has_bits_[0] &= ~0x00000004u;
_has_bits_[0] &= ~0x00000008u;
}
inline int32_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_port() const {
return port_;
@@ -9298,7 +9325,7 @@ inline int32_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCreden
return _internal_port();
}
inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_set_port(int32_t value) {
_has_bits_[0] |= 0x00000004u;
_has_bits_[0] |= 0x00000008u;
port_ = value;
}
inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::set_port(int32_t value) {
@@ -9308,7 +9335,7 @@ inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia
// optional int32 frequency = 4;
inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_has_frequency() const {
bool value = (_has_bits_[0] & 0x00000008u) != 0;
bool value = (_has_bits_[0] & 0x00000010u) != 0;
return value;
}
inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::has_frequency() const {
@@ -9316,7 +9343,7 @@ inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia
}
inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::clear_frequency() {
frequency_ = 0;
_has_bits_[0] &= ~0x00000008u;
_has_bits_[0] &= ~0x00000010u;
}
inline int32_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_frequency() const {
return frequency_;
@@ -9326,7 +9353,7 @@ inline int32_t BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCreden
return _internal_frequency();
}
inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_set_frequency(int32_t value) {
_has_bits_[0] |= 0x00000008u;
_has_bits_[0] |= 0x00000010u;
frequency_ = value;
}
inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::set_frequency(int32_t value) {
@@ -9334,6 +9361,66 @@ inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentia
// @@protoc_insertion_point(field_set:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.frequency)
}
// optional string gateway = 5 [default = "0.0.0.0"];
inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_has_gateway() const {
bool value = (_has_bits_[0] & 0x00000004u) != 0;
return value;
}
inline bool BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::has_gateway() const {
return _internal_has_gateway();
}
inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::clear_gateway() {
gateway_.ClearToDefault(::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_i_give_permission_to_break_this_code_default_gateway_, GetArenaForAllocation());
_has_bits_[0] &= ~0x00000004u;
}
inline const std::string& BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::gateway() const {
// @@protoc_insertion_point(field_get:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.gateway)
if (gateway_.IsDefault(nullptr)) return _i_give_permission_to_break_this_code_default_gateway_.get();
return _internal_gateway();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::set_gateway(ArgT0&& arg0, ArgT... args) {
_has_bits_[0] |= 0x00000004u;
gateway_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
// @@protoc_insertion_point(field_set:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.gateway)
}
inline std::string* BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::mutable_gateway() {
std::string* _s = _internal_mutable_gateway();
// @@protoc_insertion_point(field_mutable:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.gateway)
return _s;
}
inline const std::string& BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_gateway() const {
return gateway_.Get();
}
inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_set_gateway(const std::string& value) {
_has_bits_[0] |= 0x00000004u;
gateway_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::NonEmptyDefault{}, value, GetArenaForAllocation());
}
inline std::string* BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_internal_mutable_gateway() {
_has_bits_[0] |= 0x00000004u;
return gateway_.Mutable(::location::nearby::connections::BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::_i_give_permission_to_break_this_code_default_gateway_, GetArenaForAllocation());
}
inline std::string* BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::release_gateway() {
// @@protoc_insertion_point(field_release:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.gateway)
if (!_internal_has_gateway()) {
return nullptr;
}
_has_bits_[0] &= ~0x00000004u;
auto* p = gateway_.ReleaseNonDefault(nullptr, GetArenaForAllocation());
return p;
}
inline void BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WifiDirectCredentials::set_allocated_gateway(std::string* gateway) {
if (gateway != nullptr) {
_has_bits_[0] |= 0x00000004u;
} else {
_has_bits_[0] &= ~0x00000004u;
}
gateway_.SetAllocated(nullptr, gateway,
GetArenaForAllocation());
// @@protoc_insertion_point(field_set_allocated:location.nearby.connections.BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials.gateway)
}
// -------------------------------------------------------------------
// BandwidthUpgradeNegotiationFrame_UpgradePathInfo_WebRtcCredentials
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,617 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: internal/proto/device_metadata.proto
#include "internal/proto/device_metadata.pb.h"
#include <algorithm>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
PROTOBUF_PRAGMA_INIT_SEG
namespace nearby {
namespace internal {
constexpr DeviceMetadata::DeviceMetadata(
::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
: stable_device_id_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
, account_name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
, device_name_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
, icon_url_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
, bluetooth_mac_address_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
, device_type_(0)
{}
struct DeviceMetadataDefaultTypeInternal {
constexpr DeviceMetadataDefaultTypeInternal()
: _instance(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized{}) {}
~DeviceMetadataDefaultTypeInternal() {}
union {
DeviceMetadata _instance;
};
};
PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT DeviceMetadataDefaultTypeInternal _DeviceMetadata_default_instance_;
} // namespace internal
} // namespace nearby
static ::PROTOBUF_NAMESPACE_ID::Metadata file_level_metadata_internal_2fproto_2fdevice_5fmetadata_2eproto[1];
static const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* file_level_enum_descriptors_internal_2fproto_2fdevice_5fmetadata_2eproto[1];
static constexpr ::PROTOBUF_NAMESPACE_ID::ServiceDescriptor const** file_level_service_descriptors_internal_2fproto_2fdevice_5fmetadata_2eproto = nullptr;
const uint32_t TableStruct_internal_2fproto_2fdevice_5fmetadata_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
PROTOBUF_FIELD_OFFSET(::nearby::internal::DeviceMetadata, _has_bits_),
PROTOBUF_FIELD_OFFSET(::nearby::internal::DeviceMetadata, _internal_metadata_),
~0u, // no _extensions_
~0u, // no _oneof_case_
~0u, // no _weak_field_map_
~0u, // no _inlined_string_donated_
PROTOBUF_FIELD_OFFSET(::nearby::internal::DeviceMetadata, stable_device_id_),
PROTOBUF_FIELD_OFFSET(::nearby::internal::DeviceMetadata, account_name_),
PROTOBUF_FIELD_OFFSET(::nearby::internal::DeviceMetadata, device_name_),
PROTOBUF_FIELD_OFFSET(::nearby::internal::DeviceMetadata, icon_url_),
PROTOBUF_FIELD_OFFSET(::nearby::internal::DeviceMetadata, bluetooth_mac_address_),
PROTOBUF_FIELD_OFFSET(::nearby::internal::DeviceMetadata, device_type_),
0,
1,
2,
3,
4,
5,
};
static const ::PROTOBUF_NAMESPACE_ID::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
{ 0, 12, -1, sizeof(::nearby::internal::DeviceMetadata)},
};
static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] = {
reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&::nearby::internal::_DeviceMetadata_default_instance_),
};
const char descriptor_table_protodef_internal_2fproto_2fdevice_5fmetadata_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
"\n$internal/proto/device_metadata.proto\022\017"
"nearby.internal\"\264\003\n\016DeviceMetadata\022\035\n\020st"
"able_device_id\030\001 \001(\tH\000\210\001\001\022\031\n\014account_nam"
"e\030\002 \001(\tH\001\210\001\001\022\030\n\013device_name\030\003 \001(\tH\002\210\001\001\022\025"
"\n\010icon_url\030\004 \001(\tH\003\210\001\001\022\"\n\025bluetooth_mac_a"
"ddress\030\005 \001(\tH\004\210\001\001\022D\n\013device_type\030\006 \001(\0162*"
".nearby.internal.DeviceMetadata.DeviceTy"
"peH\005\210\001\001\"`\n\nDeviceType\022\017\n\013UNSPECIFIED\020\000\022\t"
"\n\005PHONE\020\001\022\n\n\006TABLET\020\002\022\013\n\007DISPLAY\020\003\022\n\n\006LA"
"PTOP\020\004\022\006\n\002TV\020\005\022\t\n\005WATCH\020\006B\023\n\021_stable_dev"
"ice_idB\017\n\r_account_nameB\016\n\014_device_nameB"
"\013\n\t_icon_urlB\030\n\026_bluetooth_mac_addressB\016"
"\n\014_device_typeb\006proto3"
;
static ::PROTOBUF_NAMESPACE_ID::internal::once_flag descriptor_table_internal_2fproto_2fdevice_5fmetadata_2eproto_once;
const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_internal_2fproto_2fdevice_5fmetadata_2eproto = {
false, false, 502, descriptor_table_protodef_internal_2fproto_2fdevice_5fmetadata_2eproto, "internal/proto/device_metadata.proto",
&descriptor_table_internal_2fproto_2fdevice_5fmetadata_2eproto_once, nullptr, 0, 1,
schemas, file_default_instances, TableStruct_internal_2fproto_2fdevice_5fmetadata_2eproto::offsets,
file_level_metadata_internal_2fproto_2fdevice_5fmetadata_2eproto, file_level_enum_descriptors_internal_2fproto_2fdevice_5fmetadata_2eproto, file_level_service_descriptors_internal_2fproto_2fdevice_5fmetadata_2eproto,
};
PROTOBUF_ATTRIBUTE_WEAK const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable* descriptor_table_internal_2fproto_2fdevice_5fmetadata_2eproto_getter() {
return &descriptor_table_internal_2fproto_2fdevice_5fmetadata_2eproto;
}
// Force running AddDescriptors() at dynamic initialization time.
PROTOBUF_ATTRIBUTE_INIT_PRIORITY static ::PROTOBUF_NAMESPACE_ID::internal::AddDescriptorsRunner dynamic_init_dummy_internal_2fproto_2fdevice_5fmetadata_2eproto(&descriptor_table_internal_2fproto_2fdevice_5fmetadata_2eproto);
namespace nearby {
namespace internal {
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* DeviceMetadata_DeviceType_descriptor() {
::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(&descriptor_table_internal_2fproto_2fdevice_5fmetadata_2eproto);
return file_level_enum_descriptors_internal_2fproto_2fdevice_5fmetadata_2eproto[0];
}
bool DeviceMetadata_DeviceType_IsValid(int value) {
switch (value) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
return true;
default:
return false;
}
}
#if (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
constexpr DeviceMetadata_DeviceType DeviceMetadata::UNSPECIFIED;
constexpr DeviceMetadata_DeviceType DeviceMetadata::PHONE;
constexpr DeviceMetadata_DeviceType DeviceMetadata::TABLET;
constexpr DeviceMetadata_DeviceType DeviceMetadata::DISPLAY;
constexpr DeviceMetadata_DeviceType DeviceMetadata::LAPTOP;
constexpr DeviceMetadata_DeviceType DeviceMetadata::TV;
constexpr DeviceMetadata_DeviceType DeviceMetadata::WATCH;
constexpr DeviceMetadata_DeviceType DeviceMetadata::DeviceType_MIN;
constexpr DeviceMetadata_DeviceType DeviceMetadata::DeviceType_MAX;
constexpr int DeviceMetadata::DeviceType_ARRAYSIZE;
#endif // (__cplusplus < 201703) && (!defined(_MSC_VER) || (_MSC_VER >= 1900 && _MSC_VER < 1912))
// ===================================================================
class DeviceMetadata::_Internal {
public:
using HasBits = decltype(std::declval<DeviceMetadata>()._has_bits_);
static void set_has_stable_device_id(HasBits* has_bits) {
(*has_bits)[0] |= 1u;
}
static void set_has_account_name(HasBits* has_bits) {
(*has_bits)[0] |= 2u;
}
static void set_has_device_name(HasBits* has_bits) {
(*has_bits)[0] |= 4u;
}
static void set_has_icon_url(HasBits* has_bits) {
(*has_bits)[0] |= 8u;
}
static void set_has_bluetooth_mac_address(HasBits* has_bits) {
(*has_bits)[0] |= 16u;
}
static void set_has_device_type(HasBits* has_bits) {
(*has_bits)[0] |= 32u;
}
};
DeviceMetadata::DeviceMetadata(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned)
: ::PROTOBUF_NAMESPACE_ID::Message(arena, is_message_owned) {
SharedCtor();
if (!is_message_owned) {
RegisterArenaDtor(arena);
}
// @@protoc_insertion_point(arena_constructor:nearby.internal.DeviceMetadata)
}
DeviceMetadata::DeviceMetadata(const DeviceMetadata& from)
: ::PROTOBUF_NAMESPACE_ID::Message(),
_has_bits_(from._has_bits_) {
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
stable_device_id_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
stable_device_id_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (from._internal_has_stable_device_id()) {
stable_device_id_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_stable_device_id(),
GetArenaForAllocation());
}
account_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
account_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (from._internal_has_account_name()) {
account_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_account_name(),
GetArenaForAllocation());
}
device_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
device_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (from._internal_has_device_name()) {
device_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_device_name(),
GetArenaForAllocation());
}
icon_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
icon_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (from._internal_has_icon_url()) {
icon_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_icon_url(),
GetArenaForAllocation());
}
bluetooth_mac_address_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
bluetooth_mac_address_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (from._internal_has_bluetooth_mac_address()) {
bluetooth_mac_address_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_bluetooth_mac_address(),
GetArenaForAllocation());
}
device_type_ = from.device_type_;
// @@protoc_insertion_point(copy_constructor:nearby.internal.DeviceMetadata)
}
inline void DeviceMetadata::SharedCtor() {
stable_device_id_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
stable_device_id_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
account_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
account_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
device_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
device_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
icon_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
icon_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
bluetooth_mac_address_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
bluetooth_mac_address_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
device_type_ = 0;
}
DeviceMetadata::~DeviceMetadata() {
// @@protoc_insertion_point(destructor:nearby.internal.DeviceMetadata)
if (GetArenaForAllocation() != nullptr) return;
SharedDtor();
_internal_metadata_.Delete<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
inline void DeviceMetadata::SharedDtor() {
GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
stable_device_id_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
account_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
device_name_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
icon_url_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
bluetooth_mac_address_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
}
void DeviceMetadata::ArenaDtor(void* object) {
DeviceMetadata* _this = reinterpret_cast< DeviceMetadata* >(object);
(void)_this;
}
void DeviceMetadata::RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena*) {
}
void DeviceMetadata::SetCachedSize(int size) const {
_cached_size_.Set(size);
}
void DeviceMetadata::Clear() {
// @@protoc_insertion_point(message_clear_start:nearby.internal.DeviceMetadata)
uint32_t cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
cached_has_bits = _has_bits_[0];
if (cached_has_bits & 0x0000001fu) {
if (cached_has_bits & 0x00000001u) {
stable_device_id_.ClearNonDefaultToEmpty();
}
if (cached_has_bits & 0x00000002u) {
account_name_.ClearNonDefaultToEmpty();
}
if (cached_has_bits & 0x00000004u) {
device_name_.ClearNonDefaultToEmpty();
}
if (cached_has_bits & 0x00000008u) {
icon_url_.ClearNonDefaultToEmpty();
}
if (cached_has_bits & 0x00000010u) {
bluetooth_mac_address_.ClearNonDefaultToEmpty();
}
}
device_type_ = 0;
_has_bits_.Clear();
_internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
}
const char* DeviceMetadata::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) {
#define CHK_(x) if (PROTOBUF_PREDICT_FALSE(!(x))) goto failure
_Internal::HasBits has_bits{};
while (!ctx->Done(&ptr)) {
uint32_t tag;
ptr = ::PROTOBUF_NAMESPACE_ID::internal::ReadTag(ptr, &tag);
switch (tag >> 3) {
// optional string stable_device_id = 1;
case 1:
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 10)) {
auto str = _internal_mutable_stable_device_id();
ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "nearby.internal.DeviceMetadata.stable_device_id"));
CHK_(ptr);
} else
goto handle_unusual;
continue;
// optional string account_name = 2;
case 2:
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 18)) {
auto str = _internal_mutable_account_name();
ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "nearby.internal.DeviceMetadata.account_name"));
CHK_(ptr);
} else
goto handle_unusual;
continue;
// optional string device_name = 3;
case 3:
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 26)) {
auto str = _internal_mutable_device_name();
ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "nearby.internal.DeviceMetadata.device_name"));
CHK_(ptr);
} else
goto handle_unusual;
continue;
// optional string icon_url = 4;
case 4:
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
auto str = _internal_mutable_icon_url();
ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "nearby.internal.DeviceMetadata.icon_url"));
CHK_(ptr);
} else
goto handle_unusual;
continue;
// optional string bluetooth_mac_address = 5;
case 5:
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 42)) {
auto str = _internal_mutable_bluetooth_mac_address();
ptr = ::PROTOBUF_NAMESPACE_ID::internal::InlineGreedyStringParser(str, ptr, ctx);
CHK_(::PROTOBUF_NAMESPACE_ID::internal::VerifyUTF8(str, "nearby.internal.DeviceMetadata.bluetooth_mac_address"));
CHK_(ptr);
} else
goto handle_unusual;
continue;
// optional .nearby.internal.DeviceMetadata.DeviceType device_type = 6;
case 6:
if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 48)) {
uint64_t val = ::PROTOBUF_NAMESPACE_ID::internal::ReadVarint64(&ptr);
CHK_(ptr);
_internal_set_device_type(static_cast<::nearby::internal::DeviceMetadata_DeviceType>(val));
} else
goto handle_unusual;
continue;
default:
goto handle_unusual;
} // switch
handle_unusual:
if ((tag == 0) || ((tag & 7) == 4)) {
CHK_(ptr);
ctx->SetLastTag(tag);
goto message_done;
}
ptr = UnknownFieldParse(
tag,
_internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(),
ptr, ctx);
CHK_(ptr != nullptr);
} // while
message_done:
_has_bits_.Or(has_bits);
return ptr;
failure:
ptr = nullptr;
goto message_done;
#undef CHK_
}
uint8_t* DeviceMetadata::_InternalSerialize(
uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const {
// @@protoc_insertion_point(serialize_to_array_start:nearby.internal.DeviceMetadata)
uint32_t cached_has_bits = 0;
(void) cached_has_bits;
// optional string stable_device_id = 1;
if (_internal_has_stable_device_id()) {
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
this->_internal_stable_device_id().data(), static_cast<int>(this->_internal_stable_device_id().length()),
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
"nearby.internal.DeviceMetadata.stable_device_id");
target = stream->WriteStringMaybeAliased(
1, this->_internal_stable_device_id(), target);
}
// optional string account_name = 2;
if (_internal_has_account_name()) {
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
this->_internal_account_name().data(), static_cast<int>(this->_internal_account_name().length()),
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
"nearby.internal.DeviceMetadata.account_name");
target = stream->WriteStringMaybeAliased(
2, this->_internal_account_name(), target);
}
// optional string device_name = 3;
if (_internal_has_device_name()) {
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
this->_internal_device_name().data(), static_cast<int>(this->_internal_device_name().length()),
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
"nearby.internal.DeviceMetadata.device_name");
target = stream->WriteStringMaybeAliased(
3, this->_internal_device_name(), target);
}
// optional string icon_url = 4;
if (_internal_has_icon_url()) {
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
this->_internal_icon_url().data(), static_cast<int>(this->_internal_icon_url().length()),
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
"nearby.internal.DeviceMetadata.icon_url");
target = stream->WriteStringMaybeAliased(
4, this->_internal_icon_url(), target);
}
// optional string bluetooth_mac_address = 5;
if (_internal_has_bluetooth_mac_address()) {
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::VerifyUtf8String(
this->_internal_bluetooth_mac_address().data(), static_cast<int>(this->_internal_bluetooth_mac_address().length()),
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::SERIALIZE,
"nearby.internal.DeviceMetadata.bluetooth_mac_address");
target = stream->WriteStringMaybeAliased(
5, this->_internal_bluetooth_mac_address(), target);
}
// optional .nearby.internal.DeviceMetadata.DeviceType device_type = 6;
if (_internal_has_device_type()) {
target = stream->EnsureSpace(target);
target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteEnumToArray(
6, this->_internal_device_type(), target);
}
if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormat::InternalSerializeUnknownFieldsToArray(
_internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance), target, stream);
}
// @@protoc_insertion_point(serialize_to_array_end:nearby.internal.DeviceMetadata)
return target;
}
size_t DeviceMetadata::ByteSizeLong() const {
// @@protoc_insertion_point(message_byte_size_start:nearby.internal.DeviceMetadata)
size_t total_size = 0;
uint32_t cached_has_bits = 0;
// Prevent compiler warnings about cached_has_bits being unused
(void) cached_has_bits;
cached_has_bits = _has_bits_[0];
if (cached_has_bits & 0x0000003fu) {
// optional string stable_device_id = 1;
if (cached_has_bits & 0x00000001u) {
total_size += 1 +
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
this->_internal_stable_device_id());
}
// optional string account_name = 2;
if (cached_has_bits & 0x00000002u) {
total_size += 1 +
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
this->_internal_account_name());
}
// optional string device_name = 3;
if (cached_has_bits & 0x00000004u) {
total_size += 1 +
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
this->_internal_device_name());
}
// optional string icon_url = 4;
if (cached_has_bits & 0x00000008u) {
total_size += 1 +
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
this->_internal_icon_url());
}
// optional string bluetooth_mac_address = 5;
if (cached_has_bits & 0x00000010u) {
total_size += 1 +
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
this->_internal_bluetooth_mac_address());
}
// optional .nearby.internal.DeviceMetadata.DeviceType device_type = 6;
if (cached_has_bits & 0x00000020u) {
total_size += 1 +
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::EnumSize(this->_internal_device_type());
}
}
return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);
}
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData DeviceMetadata::_class_data_ = {
::PROTOBUF_NAMESPACE_ID::Message::CopyWithSizeCheck,
DeviceMetadata::MergeImpl
};
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*DeviceMetadata::GetClassData() const { return &_class_data_; }
void DeviceMetadata::MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to,
const ::PROTOBUF_NAMESPACE_ID::Message& from) {
static_cast<DeviceMetadata *>(to)->MergeFrom(
static_cast<const DeviceMetadata &>(from));
}
void DeviceMetadata::MergeFrom(const DeviceMetadata& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:nearby.internal.DeviceMetadata)
GOOGLE_DCHECK_NE(&from, this);
uint32_t cached_has_bits = 0;
(void) cached_has_bits;
cached_has_bits = from._has_bits_[0];
if (cached_has_bits & 0x0000003fu) {
if (cached_has_bits & 0x00000001u) {
_internal_set_stable_device_id(from._internal_stable_device_id());
}
if (cached_has_bits & 0x00000002u) {
_internal_set_account_name(from._internal_account_name());
}
if (cached_has_bits & 0x00000004u) {
_internal_set_device_name(from._internal_device_name());
}
if (cached_has_bits & 0x00000008u) {
_internal_set_icon_url(from._internal_icon_url());
}
if (cached_has_bits & 0x00000010u) {
_internal_set_bluetooth_mac_address(from._internal_bluetooth_mac_address());
}
if (cached_has_bits & 0x00000020u) {
device_type_ = from.device_type_;
}
_has_bits_[0] |= cached_has_bits;
}
_internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_);
}
void DeviceMetadata::CopyFrom(const DeviceMetadata& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:nearby.internal.DeviceMetadata)
if (&from == this) return;
Clear();
MergeFrom(from);
}
bool DeviceMetadata::IsInitialized() const {
return true;
}
void DeviceMetadata::InternalSwap(DeviceMetadata* other) {
using std::swap;
auto* lhs_arena = GetArenaForAllocation();
auto* rhs_arena = other->GetArenaForAllocation();
_internal_metadata_.InternalSwap(&other->_internal_metadata_);
swap(_has_bits_[0], other->_has_bits_[0]);
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
&stable_device_id_, lhs_arena,
&other->stable_device_id_, rhs_arena
);
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
&account_name_, lhs_arena,
&other->account_name_, rhs_arena
);
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
&device_name_, lhs_arena,
&other->device_name_, rhs_arena
);
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
&icon_url_, lhs_arena,
&other->icon_url_, rhs_arena
);
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::InternalSwap(
&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(),
&bluetooth_mac_address_, lhs_arena,
&other->bluetooth_mac_address_, rhs_arena
);
swap(device_type_, other->device_type_);
}
::PROTOBUF_NAMESPACE_ID::Metadata DeviceMetadata::GetMetadata() const {
return ::PROTOBUF_NAMESPACE_ID::internal::AssignDescriptors(
&descriptor_table_internal_2fproto_2fdevice_5fmetadata_2eproto_getter, &descriptor_table_internal_2fproto_2fdevice_5fmetadata_2eproto_once,
file_level_metadata_internal_2fproto_2fdevice_5fmetadata_2eproto[0]);
}
// @@protoc_insertion_point(namespace_scope)
} // namespace internal
} // namespace nearby
PROTOBUF_NAMESPACE_OPEN
template<> PROTOBUF_NOINLINE ::nearby::internal::DeviceMetadata* Arena::CreateMaybeMessage< ::nearby::internal::DeviceMetadata >(Arena* arena) {
return Arena::CreateMessageInternal< ::nearby::internal::DeviceMetadata >(arena);
}
PROTOBUF_NAMESPACE_CLOSE
// @@protoc_insertion_point(global_scope)
#include <google/protobuf/port_undef.inc>
@@ -0,0 +1,797 @@
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: internal/proto/device_metadata.proto
#ifndef GOOGLE_PROTOBUF_INCLUDED_internal_2fproto_2fdevice_5fmetadata_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_internal_2fproto_2fdevice_5fmetadata_2eproto
#include <limits>
#include <string>
#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3019000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3019001 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif
#include <google/protobuf/port_undef.inc>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h> // IWYU pragma: export
#include <google/protobuf/extension_set.h> // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_internal_2fproto_2fdevice_5fmetadata_2eproto
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
} // namespace internal
PROTOBUF_NAMESPACE_CLOSE
// Internal implementation detail -- do not use these members.
struct TableStruct_internal_2fproto_2fdevice_5fmetadata_2eproto {
static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1]
PROTOBUF_SECTION_VARIABLE(protodesc_cold);
static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
static const uint32_t offsets[];
};
extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_internal_2fproto_2fdevice_5fmetadata_2eproto;
namespace nearby {
namespace internal {
class DeviceMetadata;
struct DeviceMetadataDefaultTypeInternal;
extern DeviceMetadataDefaultTypeInternal _DeviceMetadata_default_instance_;
} // namespace internal
} // namespace nearby
PROTOBUF_NAMESPACE_OPEN
template<> ::nearby::internal::DeviceMetadata* Arena::CreateMaybeMessage<::nearby::internal::DeviceMetadata>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
namespace nearby {
namespace internal {
enum DeviceMetadata_DeviceType : int {
DeviceMetadata_DeviceType_UNSPECIFIED = 0,
DeviceMetadata_DeviceType_PHONE = 1,
DeviceMetadata_DeviceType_TABLET = 2,
DeviceMetadata_DeviceType_DISPLAY = 3,
DeviceMetadata_DeviceType_LAPTOP = 4,
DeviceMetadata_DeviceType_TV = 5,
DeviceMetadata_DeviceType_WATCH = 6,
DeviceMetadata_DeviceType_DeviceMetadata_DeviceType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(),
DeviceMetadata_DeviceType_DeviceMetadata_DeviceType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max()
};
bool DeviceMetadata_DeviceType_IsValid(int value);
constexpr DeviceMetadata_DeviceType DeviceMetadata_DeviceType_DeviceType_MIN = DeviceMetadata_DeviceType_UNSPECIFIED;
constexpr DeviceMetadata_DeviceType DeviceMetadata_DeviceType_DeviceType_MAX = DeviceMetadata_DeviceType_WATCH;
constexpr int DeviceMetadata_DeviceType_DeviceType_ARRAYSIZE = DeviceMetadata_DeviceType_DeviceType_MAX + 1;
const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* DeviceMetadata_DeviceType_descriptor();
template<typename T>
inline const std::string& DeviceMetadata_DeviceType_Name(T enum_t_value) {
static_assert(::std::is_same<T, DeviceMetadata_DeviceType>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function DeviceMetadata_DeviceType_Name.");
return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
DeviceMetadata_DeviceType_descriptor(), enum_t_value);
}
inline bool DeviceMetadata_DeviceType_Parse(
::PROTOBUF_NAMESPACE_ID::ConstStringParam name, DeviceMetadata_DeviceType* value) {
return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<DeviceMetadata_DeviceType>(
DeviceMetadata_DeviceType_descriptor(), name, value);
}
// ===================================================================
class DeviceMetadata final :
public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:nearby.internal.DeviceMetadata) */ {
public:
inline DeviceMetadata() : DeviceMetadata(nullptr) {}
~DeviceMetadata() override;
explicit constexpr DeviceMetadata(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);
DeviceMetadata(const DeviceMetadata& from);
DeviceMetadata(DeviceMetadata&& from) noexcept
: DeviceMetadata() {
*this = ::std::move(from);
}
inline DeviceMetadata& operator=(const DeviceMetadata& from) {
CopyFrom(from);
return *this;
}
inline DeviceMetadata& operator=(DeviceMetadata&& from) noexcept {
if (this == &from) return *this;
if (GetOwningArena() == from.GetOwningArena()
#ifdef PROTOBUF_FORCE_COPY_IN_MOVE
&& GetOwningArena() != nullptr
#endif // !PROTOBUF_FORCE_COPY_IN_MOVE
) {
InternalSwap(&from);
} else {
CopyFrom(from);
}
return *this;
}
static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
return GetDescriptor();
}
static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
return default_instance().GetMetadata().descriptor;
}
static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
return default_instance().GetMetadata().reflection;
}
static const DeviceMetadata& default_instance() {
return *internal_default_instance();
}
static inline const DeviceMetadata* internal_default_instance() {
return reinterpret_cast<const DeviceMetadata*>(
&_DeviceMetadata_default_instance_);
}
static constexpr int kIndexInFileMessages =
0;
friend void swap(DeviceMetadata& a, DeviceMetadata& b) {
a.Swap(&b);
}
inline void Swap(DeviceMetadata* other) {
if (other == this) return;
#ifdef PROTOBUF_FORCE_COPY_IN_SWAP
if (GetOwningArena() != nullptr &&
GetOwningArena() == other->GetOwningArena()) {
#else // PROTOBUF_FORCE_COPY_IN_SWAP
if (GetOwningArena() == other->GetOwningArena()) {
#endif // !PROTOBUF_FORCE_COPY_IN_SWAP
InternalSwap(other);
} else {
::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
}
}
void UnsafeArenaSwap(DeviceMetadata* other) {
if (other == this) return;
GOOGLE_DCHECK(GetOwningArena() == other->GetOwningArena());
InternalSwap(other);
}
// implements Message ----------------------------------------------
DeviceMetadata* New(::PROTOBUF_NAMESPACE_ID::Arena* arena = nullptr) const final {
return CreateMaybeMessage<DeviceMetadata>(arena);
}
using ::PROTOBUF_NAMESPACE_ID::Message::CopyFrom;
void CopyFrom(const DeviceMetadata& from);
using ::PROTOBUF_NAMESPACE_ID::Message::MergeFrom;
void MergeFrom(const DeviceMetadata& from);
private:
static void MergeImpl(::PROTOBUF_NAMESPACE_ID::Message* to, const ::PROTOBUF_NAMESPACE_ID::Message& from);
public:
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
bool IsInitialized() const final;
size_t ByteSizeLong() const final;
const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
uint8_t* _InternalSerialize(
uint8_t* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
int GetCachedSize() const final { return _cached_size_.Get(); }
private:
void SharedCtor();
void SharedDtor();
void SetCachedSize(int size) const final;
void InternalSwap(DeviceMetadata* other);
private:
friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
return "nearby.internal.DeviceMetadata";
}
protected:
explicit DeviceMetadata(::PROTOBUF_NAMESPACE_ID::Arena* arena,
bool is_message_owned = false);
private:
static void ArenaDtor(void* object);
inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
public:
static const ClassData _class_data_;
const ::PROTOBUF_NAMESPACE_ID::Message::ClassData*GetClassData() const final;
::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;
// nested types ----------------------------------------------------
typedef DeviceMetadata_DeviceType DeviceType;
static constexpr DeviceType UNSPECIFIED =
DeviceMetadata_DeviceType_UNSPECIFIED;
static constexpr DeviceType PHONE =
DeviceMetadata_DeviceType_PHONE;
static constexpr DeviceType TABLET =
DeviceMetadata_DeviceType_TABLET;
static constexpr DeviceType DISPLAY =
DeviceMetadata_DeviceType_DISPLAY;
static constexpr DeviceType LAPTOP =
DeviceMetadata_DeviceType_LAPTOP;
static constexpr DeviceType TV =
DeviceMetadata_DeviceType_TV;
static constexpr DeviceType WATCH =
DeviceMetadata_DeviceType_WATCH;
static inline bool DeviceType_IsValid(int value) {
return DeviceMetadata_DeviceType_IsValid(value);
}
static constexpr DeviceType DeviceType_MIN =
DeviceMetadata_DeviceType_DeviceType_MIN;
static constexpr DeviceType DeviceType_MAX =
DeviceMetadata_DeviceType_DeviceType_MAX;
static constexpr int DeviceType_ARRAYSIZE =
DeviceMetadata_DeviceType_DeviceType_ARRAYSIZE;
static inline const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor*
DeviceType_descriptor() {
return DeviceMetadata_DeviceType_descriptor();
}
template<typename T>
static inline const std::string& DeviceType_Name(T enum_t_value) {
static_assert(::std::is_same<T, DeviceType>::value ||
::std::is_integral<T>::value,
"Incorrect type passed to function DeviceType_Name.");
return DeviceMetadata_DeviceType_Name(enum_t_value);
}
static inline bool DeviceType_Parse(::PROTOBUF_NAMESPACE_ID::ConstStringParam name,
DeviceType* value) {
return DeviceMetadata_DeviceType_Parse(name, value);
}
// accessors -------------------------------------------------------
enum : int {
kStableDeviceIdFieldNumber = 1,
kAccountNameFieldNumber = 2,
kDeviceNameFieldNumber = 3,
kIconUrlFieldNumber = 4,
kBluetoothMacAddressFieldNumber = 5,
kDeviceTypeFieldNumber = 6,
};
// optional string stable_device_id = 1;
bool has_stable_device_id() const;
private:
bool _internal_has_stable_device_id() const;
public:
void clear_stable_device_id();
const std::string& stable_device_id() const;
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_stable_device_id(ArgT0&& arg0, ArgT... args);
std::string* mutable_stable_device_id();
PROTOBUF_NODISCARD std::string* release_stable_device_id();
void set_allocated_stable_device_id(std::string* stable_device_id);
private:
const std::string& _internal_stable_device_id() const;
inline PROTOBUF_ALWAYS_INLINE void _internal_set_stable_device_id(const std::string& value);
std::string* _internal_mutable_stable_device_id();
public:
// optional string account_name = 2;
bool has_account_name() const;
private:
bool _internal_has_account_name() const;
public:
void clear_account_name();
const std::string& account_name() const;
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_account_name(ArgT0&& arg0, ArgT... args);
std::string* mutable_account_name();
PROTOBUF_NODISCARD std::string* release_account_name();
void set_allocated_account_name(std::string* account_name);
private:
const std::string& _internal_account_name() const;
inline PROTOBUF_ALWAYS_INLINE void _internal_set_account_name(const std::string& value);
std::string* _internal_mutable_account_name();
public:
// optional string device_name = 3;
bool has_device_name() const;
private:
bool _internal_has_device_name() const;
public:
void clear_device_name();
const std::string& device_name() const;
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_device_name(ArgT0&& arg0, ArgT... args);
std::string* mutable_device_name();
PROTOBUF_NODISCARD std::string* release_device_name();
void set_allocated_device_name(std::string* device_name);
private:
const std::string& _internal_device_name() const;
inline PROTOBUF_ALWAYS_INLINE void _internal_set_device_name(const std::string& value);
std::string* _internal_mutable_device_name();
public:
// optional string icon_url = 4;
bool has_icon_url() const;
private:
bool _internal_has_icon_url() const;
public:
void clear_icon_url();
const std::string& icon_url() const;
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_icon_url(ArgT0&& arg0, ArgT... args);
std::string* mutable_icon_url();
PROTOBUF_NODISCARD std::string* release_icon_url();
void set_allocated_icon_url(std::string* icon_url);
private:
const std::string& _internal_icon_url() const;
inline PROTOBUF_ALWAYS_INLINE void _internal_set_icon_url(const std::string& value);
std::string* _internal_mutable_icon_url();
public:
// optional string bluetooth_mac_address = 5;
bool has_bluetooth_mac_address() const;
private:
bool _internal_has_bluetooth_mac_address() const;
public:
void clear_bluetooth_mac_address();
const std::string& bluetooth_mac_address() const;
template <typename ArgT0 = const std::string&, typename... ArgT>
void set_bluetooth_mac_address(ArgT0&& arg0, ArgT... args);
std::string* mutable_bluetooth_mac_address();
PROTOBUF_NODISCARD std::string* release_bluetooth_mac_address();
void set_allocated_bluetooth_mac_address(std::string* bluetooth_mac_address);
private:
const std::string& _internal_bluetooth_mac_address() const;
inline PROTOBUF_ALWAYS_INLINE void _internal_set_bluetooth_mac_address(const std::string& value);
std::string* _internal_mutable_bluetooth_mac_address();
public:
// optional .nearby.internal.DeviceMetadata.DeviceType device_type = 6;
bool has_device_type() const;
private:
bool _internal_has_device_type() const;
public:
void clear_device_type();
::nearby::internal::DeviceMetadata_DeviceType device_type() const;
void set_device_type(::nearby::internal::DeviceMetadata_DeviceType value);
private:
::nearby::internal::DeviceMetadata_DeviceType _internal_device_type() const;
void _internal_set_device_type(::nearby::internal::DeviceMetadata_DeviceType value);
public:
// @@protoc_insertion_point(class_scope:nearby.internal.DeviceMetadata)
private:
class _Internal;
template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
typedef void InternalArenaConstructable_;
typedef void DestructorSkippable_;
::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr stable_device_id_;
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr account_name_;
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr device_name_;
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr icon_url_;
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr bluetooth_mac_address_;
int device_type_;
friend struct ::TableStruct_internal_2fproto_2fdevice_5fmetadata_2eproto;
};
// ===================================================================
// ===================================================================
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif // __GNUC__
// DeviceMetadata
// optional string stable_device_id = 1;
inline bool DeviceMetadata::_internal_has_stable_device_id() const {
bool value = (_has_bits_[0] & 0x00000001u) != 0;
return value;
}
inline bool DeviceMetadata::has_stable_device_id() const {
return _internal_has_stable_device_id();
}
inline void DeviceMetadata::clear_stable_device_id() {
stable_device_id_.ClearToEmpty();
_has_bits_[0] &= ~0x00000001u;
}
inline const std::string& DeviceMetadata::stable_device_id() const {
// @@protoc_insertion_point(field_get:nearby.internal.DeviceMetadata.stable_device_id)
return _internal_stable_device_id();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void DeviceMetadata::set_stable_device_id(ArgT0&& arg0, ArgT... args) {
_has_bits_[0] |= 0x00000001u;
stable_device_id_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
// @@protoc_insertion_point(field_set:nearby.internal.DeviceMetadata.stable_device_id)
}
inline std::string* DeviceMetadata::mutable_stable_device_id() {
std::string* _s = _internal_mutable_stable_device_id();
// @@protoc_insertion_point(field_mutable:nearby.internal.DeviceMetadata.stable_device_id)
return _s;
}
inline const std::string& DeviceMetadata::_internal_stable_device_id() const {
return stable_device_id_.Get();
}
inline void DeviceMetadata::_internal_set_stable_device_id(const std::string& value) {
_has_bits_[0] |= 0x00000001u;
stable_device_id_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
}
inline std::string* DeviceMetadata::_internal_mutable_stable_device_id() {
_has_bits_[0] |= 0x00000001u;
return stable_device_id_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
}
inline std::string* DeviceMetadata::release_stable_device_id() {
// @@protoc_insertion_point(field_release:nearby.internal.DeviceMetadata.stable_device_id)
if (!_internal_has_stable_device_id()) {
return nullptr;
}
_has_bits_[0] &= ~0x00000001u;
auto* p = stable_device_id_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (stable_device_id_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
stable_device_id_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
}
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
return p;
}
inline void DeviceMetadata::set_allocated_stable_device_id(std::string* stable_device_id) {
if (stable_device_id != nullptr) {
_has_bits_[0] |= 0x00000001u;
} else {
_has_bits_[0] &= ~0x00000001u;
}
stable_device_id_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), stable_device_id,
GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (stable_device_id_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
stable_device_id_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
}
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
// @@protoc_insertion_point(field_set_allocated:nearby.internal.DeviceMetadata.stable_device_id)
}
// optional string account_name = 2;
inline bool DeviceMetadata::_internal_has_account_name() const {
bool value = (_has_bits_[0] & 0x00000002u) != 0;
return value;
}
inline bool DeviceMetadata::has_account_name() const {
return _internal_has_account_name();
}
inline void DeviceMetadata::clear_account_name() {
account_name_.ClearToEmpty();
_has_bits_[0] &= ~0x00000002u;
}
inline const std::string& DeviceMetadata::account_name() const {
// @@protoc_insertion_point(field_get:nearby.internal.DeviceMetadata.account_name)
return _internal_account_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void DeviceMetadata::set_account_name(ArgT0&& arg0, ArgT... args) {
_has_bits_[0] |= 0x00000002u;
account_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
// @@protoc_insertion_point(field_set:nearby.internal.DeviceMetadata.account_name)
}
inline std::string* DeviceMetadata::mutable_account_name() {
std::string* _s = _internal_mutable_account_name();
// @@protoc_insertion_point(field_mutable:nearby.internal.DeviceMetadata.account_name)
return _s;
}
inline const std::string& DeviceMetadata::_internal_account_name() const {
return account_name_.Get();
}
inline void DeviceMetadata::_internal_set_account_name(const std::string& value) {
_has_bits_[0] |= 0x00000002u;
account_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
}
inline std::string* DeviceMetadata::_internal_mutable_account_name() {
_has_bits_[0] |= 0x00000002u;
return account_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
}
inline std::string* DeviceMetadata::release_account_name() {
// @@protoc_insertion_point(field_release:nearby.internal.DeviceMetadata.account_name)
if (!_internal_has_account_name()) {
return nullptr;
}
_has_bits_[0] &= ~0x00000002u;
auto* p = account_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (account_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
account_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
}
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
return p;
}
inline void DeviceMetadata::set_allocated_account_name(std::string* account_name) {
if (account_name != nullptr) {
_has_bits_[0] |= 0x00000002u;
} else {
_has_bits_[0] &= ~0x00000002u;
}
account_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), account_name,
GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (account_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
account_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
}
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
// @@protoc_insertion_point(field_set_allocated:nearby.internal.DeviceMetadata.account_name)
}
// optional string device_name = 3;
inline bool DeviceMetadata::_internal_has_device_name() const {
bool value = (_has_bits_[0] & 0x00000004u) != 0;
return value;
}
inline bool DeviceMetadata::has_device_name() const {
return _internal_has_device_name();
}
inline void DeviceMetadata::clear_device_name() {
device_name_.ClearToEmpty();
_has_bits_[0] &= ~0x00000004u;
}
inline const std::string& DeviceMetadata::device_name() const {
// @@protoc_insertion_point(field_get:nearby.internal.DeviceMetadata.device_name)
return _internal_device_name();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void DeviceMetadata::set_device_name(ArgT0&& arg0, ArgT... args) {
_has_bits_[0] |= 0x00000004u;
device_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
// @@protoc_insertion_point(field_set:nearby.internal.DeviceMetadata.device_name)
}
inline std::string* DeviceMetadata::mutable_device_name() {
std::string* _s = _internal_mutable_device_name();
// @@protoc_insertion_point(field_mutable:nearby.internal.DeviceMetadata.device_name)
return _s;
}
inline const std::string& DeviceMetadata::_internal_device_name() const {
return device_name_.Get();
}
inline void DeviceMetadata::_internal_set_device_name(const std::string& value) {
_has_bits_[0] |= 0x00000004u;
device_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
}
inline std::string* DeviceMetadata::_internal_mutable_device_name() {
_has_bits_[0] |= 0x00000004u;
return device_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
}
inline std::string* DeviceMetadata::release_device_name() {
// @@protoc_insertion_point(field_release:nearby.internal.DeviceMetadata.device_name)
if (!_internal_has_device_name()) {
return nullptr;
}
_has_bits_[0] &= ~0x00000004u;
auto* p = device_name_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (device_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
device_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
}
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
return p;
}
inline void DeviceMetadata::set_allocated_device_name(std::string* device_name) {
if (device_name != nullptr) {
_has_bits_[0] |= 0x00000004u;
} else {
_has_bits_[0] &= ~0x00000004u;
}
device_name_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), device_name,
GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (device_name_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
device_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
}
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
// @@protoc_insertion_point(field_set_allocated:nearby.internal.DeviceMetadata.device_name)
}
// optional string icon_url = 4;
inline bool DeviceMetadata::_internal_has_icon_url() const {
bool value = (_has_bits_[0] & 0x00000008u) != 0;
return value;
}
inline bool DeviceMetadata::has_icon_url() const {
return _internal_has_icon_url();
}
inline void DeviceMetadata::clear_icon_url() {
icon_url_.ClearToEmpty();
_has_bits_[0] &= ~0x00000008u;
}
inline const std::string& DeviceMetadata::icon_url() const {
// @@protoc_insertion_point(field_get:nearby.internal.DeviceMetadata.icon_url)
return _internal_icon_url();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void DeviceMetadata::set_icon_url(ArgT0&& arg0, ArgT... args) {
_has_bits_[0] |= 0x00000008u;
icon_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
// @@protoc_insertion_point(field_set:nearby.internal.DeviceMetadata.icon_url)
}
inline std::string* DeviceMetadata::mutable_icon_url() {
std::string* _s = _internal_mutable_icon_url();
// @@protoc_insertion_point(field_mutable:nearby.internal.DeviceMetadata.icon_url)
return _s;
}
inline const std::string& DeviceMetadata::_internal_icon_url() const {
return icon_url_.Get();
}
inline void DeviceMetadata::_internal_set_icon_url(const std::string& value) {
_has_bits_[0] |= 0x00000008u;
icon_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
}
inline std::string* DeviceMetadata::_internal_mutable_icon_url() {
_has_bits_[0] |= 0x00000008u;
return icon_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
}
inline std::string* DeviceMetadata::release_icon_url() {
// @@protoc_insertion_point(field_release:nearby.internal.DeviceMetadata.icon_url)
if (!_internal_has_icon_url()) {
return nullptr;
}
_has_bits_[0] &= ~0x00000008u;
auto* p = icon_url_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (icon_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
icon_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
}
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
return p;
}
inline void DeviceMetadata::set_allocated_icon_url(std::string* icon_url) {
if (icon_url != nullptr) {
_has_bits_[0] |= 0x00000008u;
} else {
_has_bits_[0] &= ~0x00000008u;
}
icon_url_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), icon_url,
GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (icon_url_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
icon_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
}
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
// @@protoc_insertion_point(field_set_allocated:nearby.internal.DeviceMetadata.icon_url)
}
// optional string bluetooth_mac_address = 5;
inline bool DeviceMetadata::_internal_has_bluetooth_mac_address() const {
bool value = (_has_bits_[0] & 0x00000010u) != 0;
return value;
}
inline bool DeviceMetadata::has_bluetooth_mac_address() const {
return _internal_has_bluetooth_mac_address();
}
inline void DeviceMetadata::clear_bluetooth_mac_address() {
bluetooth_mac_address_.ClearToEmpty();
_has_bits_[0] &= ~0x00000010u;
}
inline const std::string& DeviceMetadata::bluetooth_mac_address() const {
// @@protoc_insertion_point(field_get:nearby.internal.DeviceMetadata.bluetooth_mac_address)
return _internal_bluetooth_mac_address();
}
template <typename ArgT0, typename... ArgT>
inline PROTOBUF_ALWAYS_INLINE
void DeviceMetadata::set_bluetooth_mac_address(ArgT0&& arg0, ArgT... args) {
_has_bits_[0] |= 0x00000010u;
bluetooth_mac_address_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, static_cast<ArgT0 &&>(arg0), args..., GetArenaForAllocation());
// @@protoc_insertion_point(field_set:nearby.internal.DeviceMetadata.bluetooth_mac_address)
}
inline std::string* DeviceMetadata::mutable_bluetooth_mac_address() {
std::string* _s = _internal_mutable_bluetooth_mac_address();
// @@protoc_insertion_point(field_mutable:nearby.internal.DeviceMetadata.bluetooth_mac_address)
return _s;
}
inline const std::string& DeviceMetadata::_internal_bluetooth_mac_address() const {
return bluetooth_mac_address_.Get();
}
inline void DeviceMetadata::_internal_set_bluetooth_mac_address(const std::string& value) {
_has_bits_[0] |= 0x00000010u;
bluetooth_mac_address_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArenaForAllocation());
}
inline std::string* DeviceMetadata::_internal_mutable_bluetooth_mac_address() {
_has_bits_[0] |= 0x00000010u;
return bluetooth_mac_address_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArenaForAllocation());
}
inline std::string* DeviceMetadata::release_bluetooth_mac_address() {
// @@protoc_insertion_point(field_release:nearby.internal.DeviceMetadata.bluetooth_mac_address)
if (!_internal_has_bluetooth_mac_address()) {
return nullptr;
}
_has_bits_[0] &= ~0x00000010u;
auto* p = bluetooth_mac_address_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (bluetooth_mac_address_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
bluetooth_mac_address_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
}
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
return p;
}
inline void DeviceMetadata::set_allocated_bluetooth_mac_address(std::string* bluetooth_mac_address) {
if (bluetooth_mac_address != nullptr) {
_has_bits_[0] |= 0x00000010u;
} else {
_has_bits_[0] &= ~0x00000010u;
}
bluetooth_mac_address_.SetAllocated(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), bluetooth_mac_address,
GetArenaForAllocation());
#ifdef PROTOBUF_FORCE_COPY_DEFAULT_STRING
if (bluetooth_mac_address_.IsDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited())) {
bluetooth_mac_address_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
}
#endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
// @@protoc_insertion_point(field_set_allocated:nearby.internal.DeviceMetadata.bluetooth_mac_address)
}
// optional .nearby.internal.DeviceMetadata.DeviceType device_type = 6;
inline bool DeviceMetadata::_internal_has_device_type() const {
bool value = (_has_bits_[0] & 0x00000020u) != 0;
return value;
}
inline bool DeviceMetadata::has_device_type() const {
return _internal_has_device_type();
}
inline void DeviceMetadata::clear_device_type() {
device_type_ = 0;
_has_bits_[0] &= ~0x00000020u;
}
inline ::nearby::internal::DeviceMetadata_DeviceType DeviceMetadata::_internal_device_type() const {
return static_cast< ::nearby::internal::DeviceMetadata_DeviceType >(device_type_);
}
inline ::nearby::internal::DeviceMetadata_DeviceType DeviceMetadata::device_type() const {
// @@protoc_insertion_point(field_get:nearby.internal.DeviceMetadata.device_type)
return _internal_device_type();
}
inline void DeviceMetadata::_internal_set_device_type(::nearby::internal::DeviceMetadata_DeviceType value) {
_has_bits_[0] |= 0x00000020u;
device_type_ = value;
}
inline void DeviceMetadata::set_device_type(::nearby::internal::DeviceMetadata_DeviceType value) {
_internal_set_device_type(value);
// @@protoc_insertion_point(field_set:nearby.internal.DeviceMetadata.device_type)
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif // __GNUC__
// @@protoc_insertion_point(namespace_scope)
} // namespace internal
} // namespace nearby
PROTOBUF_NAMESPACE_OPEN
template <> struct is_proto_enum< ::nearby::internal::DeviceMetadata_DeviceType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::nearby::internal::DeviceMetadata_DeviceType>() {
return ::nearby::internal::DeviceMetadata_DeviceType_descriptor();
}
PROTOBUF_NAMESPACE_CLOSE
// @@protoc_insertion_point(global_scope)
#include <google/protobuf/port_undef.inc>
#endif // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_internal_2fproto_2fdevice_5fmetadata_2eproto
+8 -19
View File
@@ -23,14 +23,15 @@ cc_library(
],
copts = ["-DCORE_ADAPTER_DLL"],
visibility = [
"//location/nearby/cpp/sharing:__subpackages__",
"//connections/clients:__subpackages__",
"//internal/platform/implementation:__subpackages__",
"//location/nearby/testing:__subpackages__",
],
deps = [
":core_types",
":event_logger",
"//connections/implementation:internal",
"//internal:device",
"//internal/analytics:event_logger",
"//internal/platform:base",
"//internal/platform:logging",
"//internal/platform:types",
@@ -47,11 +48,13 @@ cc_library(
"connection_options.cc",
"discovery_options.cc",
"payload.cc",
"status.cc",
"strategy.cc",
],
hdrs = [
"advertising_options.h",
"connection_options.h",
"device_provider.h",
"discovery_options.h",
"listeners.h",
"medium_selector.h",
@@ -66,32 +69,19 @@ cc_library(
],
copts = ["-DCORE_ADAPTER_DLL"],
visibility = [
"//location/nearby/cpp/sharing:__subpackages__",
"//connections:__subpackages__",
"//internal/analytics:__subpackages__",
"//internal/platform/implementation/ios:__subpackages__",
"//location/nearby/testing:__subpackages__",
],
deps = [
"//internal:device",
"//internal/platform:base",
"//internal/platform:types",
"//internal/platform:util",
"//proto:connections_enums_cc_proto",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/types:variant",
"@com_google_glog//:glog",
],
)
cc_library(
name = "event_logger",
hdrs = [
"event_logger.h",
],
visibility = [
"//internal/analytics:__subpackages__",
],
deps = [
"//internal/proto/analytics:connections_log_cc_proto",
],
)
@@ -109,8 +99,8 @@ cc_test(
deps = [
":core",
":core_types",
"//connections/implementation:internal",
"//connections/implementation:internal_test",
"//internal:device",
"//internal/platform:base",
"//internal/platform:logging",
"//internal/platform:types",
@@ -118,7 +108,6 @@ cc_test(
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:variant",
"@com_google_googletest//:gtest_main",
],
)
+7 -1
View File
@@ -29,7 +29,7 @@ namespace connections {
// Connection Options: used for both Advertising and Discovery.
// All fields are mutable, to make the type copy-assignable.
struct AdvertisingOptions : public OptionsBase {
bool auto_upgrade_bandwidth;
bool auto_upgrade_bandwidth = true;
bool enforce_topology_constraints;
bool low_power;
bool enable_bluetooth_listening;
@@ -37,8 +37,14 @@ struct AdvertisingOptions : public OptionsBase {
// Whether this is intended to be used in conjunction with InjectEndpoint().
bool is_out_of_band_connection = false;
// TODO(b/229927044): Replaces it as bool once Ble v1 is deprecated.
std::string fast_advertisement_service_uuid;
// The information about this device (eg. name, device type),
// to appear on the remote device.
// Defined by client/application.
const char* device_info;
// Returns a copy and normalizes allowed mediums:
// (1) If is_out_of_band_connection is true, verifies that there is only one
// medium allowed, defaulting to only Bluetooth if unspecified.
+31 -6
View File
@@ -11,7 +11,11 @@
# 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.
load("//tools/build_defs/apple:ios.bzl", "ios_static_framework")
# TODO(b/240046236): Rename this package as `objc`.
load("//tools/build_defs/apple:ios.bzl", "ios_static_framework", "ios_unit_test")
load("//tools/build_defs/swift:swift_library.bzl", "swift_library")
licenses(["notice"])
@@ -21,19 +25,19 @@ objc_library(
name = "Connections",
srcs = [
"Internal/GNCAdvertiser.mm",
"Internal/GNCCore.h",
"Internal/GNCCore.mm",
"Internal/GNCCoreConnection.h",
"Internal/GNCCoreConnection.mm",
"Internal/GNCDiscoverer.mm",
"Internal/GNCPayload.mm",
"Internal/GNCPayload+Internal.h",
"Internal/GNCPayloadListener.h",
"Internal/GNCPayloadListener.mm",
"Internal/GNCUtils.h",
"Internal/GNCUtils.mm",
],
hdrs = [
"Internal/GNCCore.h",
"Internal/GNCCoreConnection.h",
"Internal/GNCPayload+Internal.h",
"Internal/GNCPayloadListener.h",
"Internal/GNCUtils.h",
"Public/NearbyConnections/GNCAdvertiser.h",
"Public/NearbyConnections/GNCConnection.h",
"Public/NearbyConnections/GNCConnections.h",
@@ -41,15 +45,36 @@ objc_library(
"Public/NearbyConnections/GNCPayload.h",
],
features = ["-layering_check"],
module_name = "NearbyConnections",
deps = [
"//connections:core",
"//connections:core_types",
"//internal/platform/implementation/ios:Platform",
"//third_party/apple_frameworks:Foundation",
"//third_party/objective_c/google_toolbox_for_mac:GTM_Logger",
"@com_google_absl//absl/functional:bind_front",
],
)
swift_library(
name = "BuildTestsLib",
testonly = 1,
srcs = ["BuildTests/Test.swift"],
deps = [
":Connections",
"//third_party/apple_frameworks:XCTest",
],
)
ios_unit_test(
name = "BuildTests",
minimum_os_version = "12.0",
runner = "//testing/utp/ios:IOS_12",
deps = [
":BuildTestsLib",
],
)
MIN_IOS_VERSION = "12.0"
HDRS_POD = [
@@ -0,0 +1,8 @@
import NearbyConnections
import XCTest
class BuildTests: XCTestCase {
func testBuild() {
// At least one test case is needed.
}
}
@@ -150,7 +150,7 @@ class GNCAdvertiserConnectionListener {
// The connection was accepted by the client.
if (payload_listener_ == nullptr) {
payload_listener_ = std::make_unique<GNCPayloadListener>(
advertiser.core,
strongAdvertiser.core,
^{
return endpointInfo.connectionHandlers;
},
@@ -158,7 +158,7 @@ class GNCAdvertiserConnectionListener {
return endpointInfo.connection.payloads;
});
}
advertiser.core->_core->AcceptConnection(
strongAdvertiser.core->_core->AcceptConnection(
CppStringFromObjCString(endpointId),
PayloadListener{
.payload_cb = absl::bind_front(&GNCPayloadListener::OnPayload,
@@ -169,7 +169,7 @@ class GNCAdvertiserConnectionListener {
ResultListener{});
} else {
// The connection was rejected by the client.
advertiser.core->_core->RejectConnection(CppStringFromObjCString(endpointId),
strongAdvertiser.core->_core->RejectConnection(CppStringFromObjCString(endpointId),
ResultListener{});
}
});
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifdef __cplusplus
#import <Foundation/Foundation.h>
#include <memory>
@@ -35,3 +37,5 @@ NS_ASSUME_NONNULL_BEGIN
GNCCore *GNCGetCore();
NS_ASSUME_NONNULL_END
#endif
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifdef __cplusplus
#import <Foundation/Foundation.h>
#import "connections/clients/ios/Internal/GNCCore.h"
@@ -42,3 +44,5 @@ NS_ASSUME_NONNULL_BEGIN
@end
NS_ASSUME_NONNULL_END
#endif
@@ -34,12 +34,9 @@
NS_ASSUME_NONNULL_BEGIN
using ::location::nearby::ByteArray;
using ::location::nearby::CppStringFromObjCString;
using ::location::nearby::connections::DiscoveryOptions;
using ::location::nearby::connections::ConnectionOptions;
using ::location::nearby::connections::DiscoveryListener;
using ::location::nearby::connections::DistanceInfo;
using ::location::nearby::connections::GNCStrategyToStrategy;
using ResultListener = ::location::nearby::connections::ResultCallback;
using ::location::nearby::connections::Status;
@@ -307,7 +304,7 @@ class GNCDiscoveryListener {
ConnectionRequestInfo{.endpoint_info = ByteArrayFromNSData(info),
.listener = std::move(listener)},
ConnectionOptions{},
ResultListener{.result_cb = [&connFailureHandler](Status status) {
ResultListener{.result_cb = [connFailureHandler](Status status) {
if (!status.Ok()) {
dispatch_sync(dispatch_get_main_queue(), ^{
connFailureHandler(GNCConnectionFailureUnknown);
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifdef __cplusplus
#import <Foundation/Foundation.h>
#include <string>
@@ -54,3 +56,5 @@ class GNCPayloadListener : public PayloadListener {
} // namespace location
NS_ASSUME_NONNULL_END
#endif
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifdef __cplusplus
#import <Foundation/Foundation.h>
#include <string>
@@ -40,3 +42,5 @@ const Strategy& GNCStrategyToStrategy(GNCStrategy strategy);
@end
NS_ASSUME_NONNULL_END
#endif
@@ -0,0 +1,49 @@
# Copyright 2022 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.
load("//tools/build_defs/apple:ios.bzl", "ios_unit_test")
load("//tools/build_defs/swift:swift_library.bzl", "swift_library")
licenses(["notice"])
package(default_visibility = ["//visibility:public"])
swift_library(
name = "NearbyConnections",
srcs = glob(["Sources/**/*.swift"]),
module_name = "NearbyConnections",
deps = [
"//connections/clients/swift/NearbyCoreAdapter",
"//third_party/apple_frameworks:Foundation",
],
)
swift_library(
name = "TestsLib",
testonly = 1,
srcs = ["Tests/BuildTests.swift"],
deps = [
":NearbyConnections",
"//third_party/apple_frameworks:XCTest",
],
)
ios_unit_test(
name = "Tests",
minimum_os_version = "12.0",
runner = "//testing/utp/ios:IOS_12",
deps = [
":TestsLib",
],
)
@@ -0,0 +1,146 @@
// Copyright 2022 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.
import Foundation
import NearbyCoreAdapter
/// Publishes an advertisement and notifies its delegate about connection requests from nearby
/// endpoints.
public class Advertiser {
/// The delegate object that handles advertising-related events.
public weak var delegate: AdvertiserDelegate?
/// The connection manager for this instance.
public let connectionManager: ConnectionManager
lazy var connection: InternalConnection? = {
let connection = InternalConnection()
connection.delegate = self
return connection
}()
/// Initializes the discoverer object.
///
/// - Parameter connectionManager: The connection manager for this instance.
public init(connectionManager: ConnectionManager) {
self.connectionManager = connectionManager
}
/// Starts advertising the local endpoint.
///
/// After this method is called (until you call `stopAdvertising()`), the framework calls your
/// delegates `advertiser(_:didReceiveConnectionRequestFrom:with:connectionRequestHandler:)`
/// method when remote endpoints request a connection.
public func startAdvertising(using context: Data) {
let options = GNCAdvertisingOptions(strategy: connectionManager.strategy.objc)
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.startAdvertising(
asService: connectionManager.serviceID, endpointInfo: context,
options: options, delegate: connection)
}
/// Stops advertising the local endpoint.
public func stopAdvertising() {
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.stopAdvertising()
}
deinit {
stopAdvertising()
}
}
extension Advertiser: InternalConnectionDelegate {
func connected(
toEndpoint endpointID: String, withEndpointInfo info: Data, authenticationToken: String
) {
connectionManager.queue.async { [weak self] in
guard let self = self else { return }
self.delegate?.advertiser(self, didReceiveConnectionRequestFrom: endpointID, with: info) {
(accept) in
guard accept else {
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.rejectConnectionRequest(fromEndpoint: endpointID)
return
}
self.connectionManager.delegate?.connectionManager(
self.connectionManager, didChangeTo: .connecting, for: endpointID)
self.connectionManager.delegate?.connectionManager(
self.connectionManager, didReceive: authenticationToken, from: endpointID
) { accept in
guard accept else {
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.rejectConnectionRequest(fromEndpoint: endpointID)
return
}
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.acceptConnectionRequest(
fromEndpoint: endpointID, delegate: self.connectionManager.payload)
}
}
}
}
func acceptedConnection(toEndpoint endpointID: String) {
connectionManager.queue.async { [weak self] in
guard let connectionManager = self?.connectionManager else { return }
connectionManager.delegate?.connectionManager(
connectionManager, didChangeTo: .connected, for: endpointID)
}
}
func rejectedConnection(toEndpoint endpointID: String, with status: GNCStatus) {
connectionManager.queue.async { [weak self] in
guard let connectionManager = self?.connectionManager else { return }
connectionManager.delegate?.connectionManager(
connectionManager, didChangeTo: .rejected, for: endpointID)
}
}
func disconnected(fromEndpoint endpointID: String) {
connectionManager.queue.async { [weak self] in
guard let connectionManager = self?.connectionManager else { return }
connectionManager.delegate?.connectionManager(
connectionManager, didChangeTo: .disconnected, for: endpointID)
}
}
}
/// The `AdvertiserDelegate` protocol defines methods that an `Advertiser` objects delegate can
/// implement to handle advertising-related events.
///
/// Delegate methods are executed on the `.main` queue by default, but a specific `DispatchQueue` on
/// which to call the delegate methods can be passed to `ConnectionManager`.
public protocol AdvertiserDelegate: AnyObject {
/// Called when a connection request is received from a nearby endpoint.
///
/// Important: Accepting a connection request will not yet establish a connection that allows
/// data transference. The connection must first be verified by both parties via the
/// `ConnectionManagerDelegate`, before data can flow freely.
///
/// - Parameters:
/// - advertiser: The advertiser object that received a connection request.
/// - endpointID: The endpoint ID of the nearby enpoint that requested the connection.
/// - info: An arbitrary piece of data received from the nearby endpoint. This can be used to
/// provide further information to the user about the nature of the invitation.
/// - connectionRequestHandler: A block that your code must call to indicate whether the
/// advertiser should accept or decline the connection request.
func advertiser(
_ advertiser: Advertiser, didReceiveConnectionRequestFrom endpointID: EndpointID,
with context: Data, connectionRequestHandler: @escaping (Bool) -> Void)
}
@@ -0,0 +1,30 @@
// Copyright 2022 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.
import NearbyCoreAdapter
/// Token used to cancel a transfer.
public class CancellationToken {
internal let payloadID: Int64
internal init(_ payloadID: Int64) {
self.payloadID = payloadID
}
/// Cancel the ongoing transfer.
public func cancel() {
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.cancelPayload(payloadID)
}
}
@@ -0,0 +1,375 @@
// Copyright 2022 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.
import NearbyCoreAdapter
/// Manages communication between the local endpoint and all remote endpoints connected to it.
public class ConnectionManager {
/// The delegate object that handles connection-related events.
public weak var delegate: ConnectionManagerDelegate?
/// The service identifier to advertise as or search for.
public let serviceID: String
/// A value indicating the connection strategy and restrictions for advertisement or discovery.
public let strategy: Strategy
/// `DispatchQueue` on which all delegate methods are called.
public let queue: DispatchQueue
private var transfers: [PayloadID: [EndpointID: Progress]] = [:]
lazy var payload: InternalPayload? = {
let payload = InternalPayload()
payload.delegate = self
return payload
}()
/// Initializes the connection manager object.
///
/// - Parameters:
/// - serviceID: The indentifier of your service advertised to other endpoints or to be searched
/// for while discovering other endpoints. This can be an arbitrary string, so long as it
/// uniquely identifies your service. A good default is to use your apps package name.
/// - strategy: Connection strategy to be used during advertisement or discovery.
/// - queue: `DispatchQueue` on which all delegate methods are called. `.main` by default.
public init(serviceID: String, strategy: Strategy, queue: DispatchQueue = .main) {
self.serviceID = serviceID
self.strategy = strategy
self.queue = queue
}
/// Sends a message as `Data` to nearby endpoints.
///
/// This method is asynchronous (nonblocking).
///
/// On the recipient device, the connection manager instance calls its delegates
/// `connectionManager(_:didReceive:withID:from:)` method with the message after it has been fully
/// received.
///
/// On both the local and recipient device, the connection manager instance calls its delegates
/// `connectionManager(_:didReceiveTransferUpdate:from:forPayload:)` method when delivery
/// succeeds, has a progress update or when an in-flight error occurs.
///
/// - Parameters:
/// - data: An instance containing the message to send.
/// - endpointIDs: An array of endpoint IDs representing the endpoints that should receive the
/// message.
/// - id: A unique ID for the payload. This ID is provided to the remote endpoint. A random ID
/// will be generated if none is set.
/// - completionHandler: A closure that gets called when the framework attempts to send the
/// message. Upon success, the handler is called with an error value of nil. Upon failure,
/// the handle is called with an error object that indicates what went wrong. This does not
/// indicate that the send has successfully completed yet. Errors might still occur during
/// transmission (and at different times for different endpoints).
/// `connectionManager(_:didReceiveTransferUpdate:from:forPayload:)`is called when delivery
/// succeeds or when an in-flight error occurs.
/// - Returns: A cancellation token used to cancel the transfer.
public func send(
_ data: Data, to endpointIDs: [EndpointID], id: PayloadID? = nil,
completionHandler: ((Error?) -> Void)? = nil
)
-> CancellationToken
{
let payload: GNCBytesPayload
if let id = id {
payload = GNCBytesPayload(data: data, identifier: id)
} else {
payload = GNCBytesPayload(data: data)
}
return send(payload, to: endpointIDs, completionHandler: completionHandler)
}
/// Opens a byte stream to nearby endpoints.
///
/// This method is asynchronous (nonblocking).
///
/// On the recipient device, the connection manager instance calls its delegates
/// `connectionManager(_:didReceive:withID:from:cancellationToken:)` method with the stream.
///
/// On both the local and recipient device, the connection manager instance calls its delegates
/// `connectionManager(_:didReceiveTransferUpdate:from:forPayload:)` method when delivery
/// succeeds, has a progress update or when an in-flight error occurs.
///
/// - Parameters:
/// - stream:
/// - endpointIDs: An array of endpoint IDs representing the endpoints that should receive this
/// stream.
/// - id: A unique ID for the payload. This ID is provided to the remote endpoint. A random ID
/// will be generated if none is set.
/// - completionHandler: A closure that gets called when the framework attempts to send the
/// stream. Upon success, the handler is called with an error value of nil. Upon failure,
/// the handle is called with an error object that indicates what went wrong. This does not
/// indicate that the send has successfully completed yet. Errors might still occur during
/// transmission (and at different times for different endpoints).
/// `connectionManager(_:didReceiveTransferUpdate:from:forPayload:)`is called when delivery
/// succeeds or when an in-flight error occurs.
/// - Returns: A cancellation token used to cancel the transfer.
public func startStream(
_ stream: InputStream, to endpointIDs: [EndpointID], id: PayloadID? = nil,
completionHandler: ((Error?) -> Void)? = nil
) -> CancellationToken {
let payload: GNCStreamPayload
if let id = id {
payload = GNCStreamPayload(stream: stream, identifier: id)
} else {
payload = GNCStreamPayload(stream: stream)
}
return send(payload, to: endpointIDs, completionHandler: completionHandler)
}
/// Sends the contents of a URL to nearby endpoints.
///
/// This method is asynchronous (nonblocking).
///
/// On the recipient device, the connection manager calls its delegates
/// `connectionManager(_:didStartReceivingResourceWithID:from:at:withName:cancellationToken:)`
/// method as soon as it begins receiving the resource.
///
/// On both the local and recipient device, the connection manager instance calls its delegates
/// `connectionManager(_:didReceiveTransferUpdate:from:forPayload:)` method when delivery
/// succeeds, has a progress update or when an in-flight error occurs.
///
/// - Parameters:
/// - resourceURL: A file URL.
/// - resourceName: A name for the resource.
/// - endpointIDs: An array of endpoint IDs representing the endpoints that should receive this
/// resource.
/// - id: A unique ID for the payload. This ID is provided to the remote endpoint. A random ID
/// will be generated if none is set.
/// - completionHandler: A closure that gets called when the framework attempts to send the
/// resource. Upon success, the handler is called with an error value of nil. Upon failure,
/// the handle is called with an error object that indicates what went wrong. This does not
/// indicate that the send has successfully completed yet. Errors might still occur during
/// transmission (and at different times for different endpoints).
/// `connectionManager(_:didReceiveTransferUpdate:from:forPayload:)`is called when delivery
/// succeeds or when an in-flight error occurs.
/// - Returns: A cancellation token used to cancel the transfer.
public func sendResource(
at resourceURL: URL, withName resourceName: String, to endpointIDs: [EndpointID],
id: PayloadID? = nil, completionHandler: ((Error?) -> Void)? = nil
) -> CancellationToken {
let remotePath = URL(fileURLWithPath: resourceName)
let parentFolder = remotePath.deletingLastPathComponent().relativePath
let fileName = remotePath.lastPathComponent
let payload: GNCFilePayload
if let id = id {
payload = GNCFilePayload(
fileURL: resourceURL, parentFolder: parentFolder, fileName: fileName, identifier: id)
} else {
payload = GNCFilePayload(fileURL: resourceURL, parentFolder: parentFolder, fileName: fileName)
}
return send(payload, to: endpointIDs, completionHandler: completionHandler)
}
private func send(
_ payload: GNCPayload, to endpointIDs: [EndpointID],
completionHandler: ((Error?) -> Void)? = nil
) -> CancellationToken {
for endpointID in endpointIDs {
if transfers[payload.identifier] == nil {
transfers[payload.identifier] = [:]
}
transfers[payload.identifier]?[endpointID] = Progress()
}
GNCCoreAdapter.shared.send(payload, toEndpoints: endpointIDs) { _ in
// TODO(b/257824412): Handle errors from completion handler.
completionHandler?(nil)
}
return CancellationToken(payload.identifier)
}
/// Disconnect from a remote endpoint.
///
/// - Parameter endpointID: The ID of the remote endpoint.
public func disconnect(from endpointID: EndpointID) {
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.disconnect(fromEndpoint: endpointID)
}
}
extension ConnectionManager: InternalPayloadDelegate {
func receivedPayload(_ payload: GNCPayload, fromEndpoint endpointID: String) {
queue.async { [weak self] in
guard let self = self else { return }
if self.transfers[payload.identifier] == nil {
self.transfers[payload.identifier] = [:]
}
self.transfers[payload.identifier]?[endpointID] = Progress()
let payloadID = payload.identifier
let cancellationToken = CancellationToken(payload.identifier)
if let bytesPayload = payload as? GNCBytesPayload {
self.delegate?.connectionManager(
self, didReceive: bytesPayload.data, withID: payloadID, from: endpointID)
}
if let streamPayload = payload as? GNCStreamPayload {
self.delegate?.connectionManager(
self, didReceive: streamPayload.stream, withID: payloadID, from: endpointID,
cancellationToken: cancellationToken)
}
if let filePayload = payload as? GNCFilePayload {
let name = (filePayload.parentFolder as NSString).appendingPathComponent(
filePayload.fileName)
self.delegate?.connectionManager(
self, didStartReceivingResourceWithID: payloadID, from: endpointID,
at: filePayload.fileURL, withName: name, cancellationToken: cancellationToken)
}
}
}
func receivedProgressUpdate(
forPayload payloadID: Int64, with status: GNCPayloadStatus, fromEndpoint endpointID: String,
bytesTransfered: Int64, totalBytes: Int64
) {
queue.async { [weak self] in
guard let self = self, let progress = self.transfers[payloadID]?[endpointID] else { return }
progress.totalUnitCount = totalBytes
progress.completedUnitCount = bytesTransfered
switch status {
case .success:
self.transfers[payloadID]?.removeValue(forKey: endpointID)
self.delegate?.connectionManager(
self, didReceiveTransferUpdate: .success, from: endpointID, forPayload: payloadID)
case .failure:
self.transfers[payloadID]?.removeValue(forKey: endpointID)
// TODO(b/257824412): Handle errors from completion handler.
break
case .canceled:
self.transfers[payloadID]?.removeValue(forKey: endpointID)
self.delegate?.connectionManager(
self, didReceiveTransferUpdate: .canceled, from: endpointID, forPayload: payloadID)
case .inProgress:
self.delegate?.connectionManager(
self, didReceiveTransferUpdate: .progress(progress), from: endpointID,
forPayload: payloadID)
}
if self.transfers[payloadID]?.isEmpty ?? false {
self.transfers.removeValue(forKey: payloadID)
}
}
}
}
/// The `ConnectionManagerDelegate` protocol defines methods that a `ConnectionManager` objects
/// delegate can implement to handle connection-related events.
///
/// Delegate methods are executed on the `.main` queue by default, but a specific `DispatchQueue` on
/// which to call the delegate methods can be passed to `ConnectionManager`.
public protocol ConnectionManagerDelegate: AnyObject {
/// Called to validate the verification code generated for the pair of endpoints.
///
/// Your app should confirm whether you connected to the correct endpoint. Typically this involves
/// showing the verification code on both devices and having the users manually compare and
/// confirm; however, this is only required if you desire a secure connection between the devices.
/// Upon confirmation, your app should call the provided `verificationHandler` block, passing
/// either `true` (to trust the nearby endpoint) or `false` (to reject it).
///
/// Important: The Nearby Connections framework makes no attempt to validate the verification
/// code in any way. If your delegate does not implement this method, all verification codes
/// are accepted automatically.
///
/// - Parameters:
/// - connectionManager: The connection manager object through which the verification code was
/// received.
/// - verificationCode: An identical token given to both endpoints.
/// - endpointID: The endpoint ID of the nearby endpoint that needs verification.
/// - verificationHandler: Your app should call this handler with a value of `true` if the
/// nearby endpoint should be trusted, or `false` otherwise.
func connectionManager(
_ connectionManager: ConnectionManager, didReceive verificationCode: String,
from endpointID: EndpointID, verificationHandler: @escaping (Bool) -> Void)
/// Indicates that a `Data` object has been received from a nearby endpoint.
///
/// - Parameters:
/// - connectionManager: The connection manager object through which the data was received.
/// - data: An object containing the received data.
/// - payloadID: The ID of the payload, as provided by the sender.
/// - endpointID: The endpoint ID of the sender.
func connectionManager(
_ connectionManager: ConnectionManager, didReceive data: Data, withID payloadID: PayloadID,
from endpointID: EndpointID)
/// Called when a nearby endpoint opens a byte stream connection to the local endpoint.
///
/// - Parameters:
/// - connectionManager: The connection manager object through which the byte stream was
/// received.
/// - stream: An `InputStream` object that represents the local endpoint for the byte stream.
/// - payloadID: The ID of the payload, as provided by the sender.
/// - endpointID: The endpoint ID of the originator of the stream.
/// - token: Token used to cancel the stream.
func connectionManager(
_ connectionManager: ConnectionManager, didReceive stream: InputStream,
withID payloadID: PayloadID,
from endpointID: EndpointID, cancellationToken token: CancellationToken)
/// Indicates that the local endpoint began receiving a resource from a nearby endpoint.
///
/// - Parameters:
/// - connectionManager: The connection manager object that started receiving the resource.
/// - payloadID: The ID of the payload, as provided by the sender.
/// - endpointID: The endpoint ID of the sender.
/// - localURL: Provides the location of a file containing the data being received.
/// - name: The name of the resource, as provided by the sender.
/// - token: Token used to cancel the resource transfer.
func connectionManager(
_ connectionManager: ConnectionManager, didStartReceivingResourceWithID payloadID: PayloadID,
from endpointID: EndpointID, at localURL: URL, withName name: String,
cancellationToken token: CancellationToken)
/// Called when a progress update is available for an incoming or outgoing transfer.
///
/// - Parameters:
/// - connectionManager: The connection manager object that received the update.
/// - update: A success, failure, cancellation or progress update.
/// - endpointID: The remote endpoint ID.
/// - payloadID: The ID of the payload, as provided by the sender.
func connectionManager(
_ connectionManager: ConnectionManager, didReceiveTransferUpdate update: TransferUpdate,
from endpointID: EndpointID, forPayload payloadID: PayloadID)
/// Called when the status of the connection to a nearby endpoint changes.
///
/// - Parameters:
/// - connectionManager: The connection manager object that manages the connection whose state
/// changed.
/// - state: The new state of the connection.
/// - endpointID: The ID of the nearby endpoint whose connection status has changed.
func connectionManager(
_ connectionManager: ConnectionManager, didChangeTo state: ConnectionState,
for endpointID: EndpointID
)
}
extension ConnectionManagerDelegate {
public func connectionManager(
_ connectionManager: ConnectionManager, didReceive verificationCode: String,
from endpointID: EndpointID, verificationHandler: @escaping (Bool) -> Void
) {
verificationHandler(true)
}
}
@@ -0,0 +1,25 @@
// Copyright 2022 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.
/// Indicates the current status of the connection between a local and remote endpoint.
public enum ConnectionState {
/// A connection to the remote endpoint is currently being established.
case connecting
/// The local endpoint is currently connected to the remote endpoint.
case connected
/// The remote endpoint is no longer connected.
case disconnected
/// The local or remote endpoint has rejected the connection request.
case rejected
}
@@ -0,0 +1,182 @@
// Copyright 2022 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.
import Foundation
import NearbyCoreAdapter
/// Searches for nearby endpoints and provides the ability to request connections to them.
public class Discoverer {
/// The delegate object that handles discovery-related events.
public weak var delegate: DiscovererDelegate?
/// The connection manager for this instance.
public let connectionManager: ConnectionManager
lazy var connection: InternalConnection? = {
let connection = InternalConnection()
connection.delegate = self
return connection
}()
lazy var discovery: InternalDiscovery? = {
let discovery = InternalDiscovery()
discovery.delegate = self
return discovery
}()
/// Initializes the discoverer object.
///
/// - Parameter connectionManager: The connection manager for this instance.
public init(connectionManager: ConnectionManager) {
self.connectionManager = connectionManager
}
/// Starts searching for nearby remote endpoints.
///
/// After this method is called (until you call `stopDiscovery()`), the framework calls your
/// delegates `discoverer(_:didFind:with:)` and `discoverer(_:didLose:)` methods as new endpoints
/// are found and lost.
public func startDiscovery() {
let options = GNCDiscoveryOptions(strategy: connectionManager.strategy.objc)
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.startDiscovery(
asService: connectionManager.serviceID, options: options, delegate: discovery)
}
/// Stops searching for nearby remote endpoints.
public func stopDiscovery() {
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.stopDiscovery()
}
/// Requests a connection to a discovered remote endpoint.
///
/// - Parameters:
/// - endpointID: The ID of the endpoint to request a connection to.
/// - context: An arbitrary piece of data that is passed to the nearby endpoint. This can be
/// used to provide further information to the user about the nature of the invitation.
public func requestConnection(to endpointID: EndpointID, using context: Data) {
let options = GNCConnectionOptions()
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.requestConnection(
toEndpoint: endpointID, endpointInfo: context,
options: options, delegate: connection)
}
deinit {
stopDiscovery()
}
}
extension Discoverer: InternalConnectionDelegate {
func connected(
toEndpoint endpointID: String, withEndpointInfo info: Data, authenticationToken: String
) {
connectionManager.queue.async { [weak self] in
guard let connectionManager = self?.connectionManager else { return }
connectionManager.delegate?.connectionManager(
connectionManager, didChangeTo: .connecting, for: endpointID)
connectionManager.delegate?.connectionManager(
connectionManager, didReceive: authenticationToken, from: endpointID
) { accept in
guard accept else {
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.rejectConnectionRequest(fromEndpoint: endpointID)
return
}
// TODO(b/257824412): Handle errors from completion handler.
GNCCoreAdapter.shared.acceptConnectionRequest(
fromEndpoint: endpointID, delegate: connectionManager.payload)
}
}
}
func acceptedConnection(toEndpoint endpointID: String) {
connectionManager.queue.async { [weak self] in
guard let connectionManager = self?.connectionManager else { return }
connectionManager.delegate?.connectionManager(
connectionManager, didChangeTo: .connected, for: endpointID)
}
}
func rejectedConnection(toEndpoint endpointID: String, with status: GNCStatus) {
connectionManager.queue.async { [weak self] in
guard let connectionManager = self?.connectionManager else { return }
connectionManager.delegate?.connectionManager(
connectionManager, didChangeTo: .rejected, for: endpointID)
}
}
func disconnected(fromEndpoint endpointID: String) {
connectionManager.queue.async { [weak self] in
guard let connectionManager = self?.connectionManager else { return }
connectionManager.delegate?.connectionManager(
connectionManager, didChangeTo: .disconnected, for: endpointID)
}
}
}
extension Discoverer: InternalDiscoveryDelegate {
func foundEndpoint(_ endpointID: String, withEndpointInfo info: Data) {
connectionManager.queue.async { [weak self] in
guard let self = self else { return }
self.delegate?.discoverer(self, didFind: endpointID, with: info)
}
}
func lostEndpoint(_ endpointID: String) {
connectionManager.queue.async { [weak self] in
guard let self = self else { return }
self.delegate?.discoverer(self, didLose: endpointID)
}
}
}
/// The `DiscovererDelegate` protocol defines methods that a `Discoverer` objects delegate can
/// implement to handle discovery-related events.
///
/// Delegate methods are executed on the `.main` queue by default, but a specific `DispatchQueue` on
/// which to call the delegate methods can be passed to `ConnectionManager`.
public protocol DiscovererDelegate: AnyObject {
/// Called when a nearby endpoint is found.
///
/// The endpoint ID provided to this delegate method can be used to request a connection with the
/// nearby endpoint.
///
/// - Parameters:
/// - discoverer: The discoverer object that found the nearby endpoint.
/// - endpointID: The unique ID of the endpoint that was found.
/// - context: An arbitrary piece of data received from the nearby endpoint. This can be used to
/// provide further information to the user about the nature of the invitation.
func discoverer(_ discoverer: Discoverer, didFind endpointID: EndpointID, with context: Data)
/// Called when a nearby endpoint is lost.
///
/// This callback informs your app that connection requests can no longer be sent to an endpoint,
/// and that your app should remove that endpoint from its user interface.
///
/// Important: Because there is a delay between when a discovered endpoint disappears and when
/// Nearby Connections detects that it has left, the fact that your app has not yet received a
/// disappearance callback does not guarantee that it can communicate with the endpoint
/// successfully.
///
/// - Parameters:
/// - discoverer: The discoverer object that lost the nearby endpoint.
/// - endpointID: The unique ID of the nearby endpoint that was lost.
func discoverer(_ discoverer: Discoverer, didLose endpointID: EndpointID)
}
@@ -0,0 +1,16 @@
// Copyright 2022 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.
/// Used to represent an enpoint.
public typealias EndpointID = String
@@ -0,0 +1,46 @@
// Copyright 2022 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.
import NearbyCoreAdapter
class InternalConnection: GNCConnectionDelegate {
weak var delegate: InternalConnectionDelegate?
func connected(
toEndpoint endpointID: String, withEndpointInfo info: Data, authenticationToken: String
) {
delegate?.connected(
toEndpoint: endpointID, withEndpointInfo: info, authenticationToken: authenticationToken)
}
func acceptedConnection(toEndpoint endpointID: String) {
delegate?.acceptedConnection(toEndpoint: endpointID)
}
func rejectedConnection(toEndpoint endpointID: String, with status: GNCStatus) {
delegate?.rejectedConnection(toEndpoint: endpointID, with: status)
}
func disconnected(fromEndpoint endpointID: String) {
delegate?.disconnected(fromEndpoint: endpointID)
}
}
protocol InternalConnectionDelegate: AnyObject {
func connected(
toEndpoint endpointID: String, withEndpointInfo info: Data, authenticationToken: String)
func acceptedConnection(toEndpoint endpointID: String)
func rejectedConnection(toEndpoint endpointID: String, with status: GNCStatus)
func disconnected(fromEndpoint endpointID: String)
}
@@ -0,0 +1,32 @@
// Copyright 2022 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.
import NearbyCoreAdapter
class InternalDiscovery: GNCDiscoveryDelegate {
weak var delegate: InternalDiscoveryDelegate?
func foundEndpoint(_ endpointID: String, withEndpointInfo info: Data) {
delegate?.foundEndpoint(endpointID, withEndpointInfo: info)
}
func lostEndpoint(_ endpointID: String) {
delegate?.lostEndpoint(endpointID)
}
}
protocol InternalDiscoveryDelegate: AnyObject {
func foundEndpoint(_ endpointID: String, withEndpointInfo info: Data)
func lostEndpoint(_ endpointID: String)
}
@@ -0,0 +1,39 @@
// Copyright 2022 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.
import NearbyCoreAdapter
class InternalPayload: GNCPayloadDelegate {
weak var delegate: InternalPayloadDelegate?
func receivedPayload(_ payload: GNCPayload, fromEndpoint endpointID: String) {
delegate?.receivedPayload(payload, fromEndpoint: endpointID)
}
func receivedProgressUpdate(
forPayload payloadID: Int64, with status: GNCPayloadStatus, fromEndpoint endpointID: String,
bytesTransfered: Int64, totalBytes: Int64
) {
delegate?.receivedProgressUpdate(
forPayload: payloadID, with: status, fromEndpoint: endpointID,
bytesTransfered: bytesTransfered, totalBytes: totalBytes)
}
}
protocol InternalPayloadDelegate: AnyObject {
func receivedPayload(_ payload: GNCPayload, fromEndpoint endpointID: String)
func receivedProgressUpdate(
forPayload payloadID: Int64, with status: GNCPayloadStatus, fromEndpoint endpointID: String,
bytesTransfered: Int64, totalBytes: Int64)
}
@@ -0,0 +1,25 @@
// Copyright 2022 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.
import NearbyCoreAdapter
/// Used to represent a payload.
public typealias PayloadID = Int64
extension PayloadID {
/// A convenience method for generating a unique payload ID.
public static func unique() -> PayloadID {
return GNCPayload.generateID()
}
}
@@ -0,0 +1,45 @@
// Copyright 2022 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.
import NearbyCoreAdapter
/// Indicates the connection strategy and restrictions for advertisement or discovery.
///
/// - Note: Only a subset of mediums are supported by certain strategies as depicted in the table
/// below. Generally, more restrictive strategies have better medium support.
///
/// | | BT Classic | BLE | LAN | Aware | NFC | USB | Hotspot | Direct | 5GHz WiFi |
/// |--------------|:----------:|:---:|:---:|:-----:|:---:|:---:|:-------:|:------:|:---------:|
/// | cluster | | | | | | | × | × | × |
/// | star | | | | | | | | | × |
/// | pointToPoint | | | | | | | | | |
///
/// - Important: In order to discover another endpoint, the remote endpoint must be advertising
/// using the same strategy.
public enum Strategy {
/// No restrictions on the amount of incoming and outgoing connections.
case cluster
/// Restricts the discoverer to a single connection, while advertisers have no restrictions on
/// amount of connections.
case star
/// Restricts both adverisers and discoverers to a single connection.
case pointToPoint
internal var objc: NearbyCoreAdapter.Strategy {
switch self {
case .cluster: return .cluster
case .star: return .star
case .pointToPoint: return .pointToPoint
}
}
}
@@ -0,0 +1,27 @@
// Copyright 2022 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.
import Foundation
/// Indicates the current status of the transfer.
public enum TransferUpdate {
/// The remote endpoint has successfully received the full transfer.
case success
/// Either the local or remote endpoint has canceled the transfer.
case canceled
/// The remote endpoint failed to receive the transfer with the associated error.
case failure(Error)
/// The the transfer is currently in progress with an associated progress value.
case progress(Progress)
}
@@ -0,0 +1,8 @@
import NearbyConnections
import XCTest
class BuildTests: XCTestCase {
func testBuild() {
// At least one test case is needed.
}
}
@@ -0,0 +1,59 @@
# Copyright 2022 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.
load("//tools/build_defs/apple:ios.bzl", "ios_unit_test")
load("//tools/build_defs/swift:swift_library.bzl", "swift_library")
licenses(["notice"])
package(default_visibility = ["//visibility:public"])
objc_library(
name = "NearbyCoreAdapter",
srcs = glob([
"Sources/*.mm",
"Sources/*.m",
"Sources/*.h",
]),
hdrs = glob(["Sources/Public/**/*.h"]),
features = ["-layering_check"],
module_name = "NearbyCoreAdapter",
deps = [
"//connections:core",
"//connections:core_types",
"//internal/platform:base",
"//internal/platform/implementation/ios:Platform", # buildcleaner: keep
"//third_party/apple_frameworks:Foundation",
"//third_party/apple_frameworks:ObjectiveC",
],
)
swift_library(
name = "TestsLib",
testonly = 1,
srcs = ["Tests/BuildTests.swift"],
deps = [
":NearbyCoreAdapter",
"//third_party/apple_frameworks:XCTest",
],
)
ios_unit_test(
name = "Tests",
minimum_os_version = "12.0",
runner = "//testing/utp/ios:IOS_12",
deps = [
":TestsLib",
],
)
@@ -0,0 +1,50 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
#ifdef __cplusplus
namespace location {
namespace nearby {
class InputStream;
}
} // namespace location
#endif
@interface CPPInputStreamBinding : NSObject
/**
* Creates and attaches a @c CPPInputStreamBinding object to the provided stream as an associated
* object.
*
* This association makes it possible for a c++ pointer to live as long as the original user
* provided @c NSInputStream object.
*
* @param stream The stream to become associated with.
*/
+ (void)bindToStream:(NSInputStream *)stream;
#ifdef __cplusplus
/**
* Retreives a reference to the c++ pointer associated to the provided stream.
*
* CPPInputStreamBinding::bindToStream: must be called on the this stream before calling this
* function.
*
* @param stream The stream that has a c++ pointer associated with it.
*/
+ (location::nearby::InputStream &)getRefFromStream:(NSInputStream *)stream;
#endif
@end
@@ -0,0 +1,90 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/CPPInputStreamBinding.h"
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#include <memory>
#include <vector>
// TODO(b/239758418): Change this to the non-internal version when available.
#include "internal/platform/input_stream.h"
using ::location::nearby::ByteArray;
using ::location::nearby::Exception;
using ::location::nearby::ExceptionOr;
using ::location::nearby::InputStream;
class CPPInputStream : public InputStream {
public:
explicit CPPInputStream(NSInputStream *iStream) : iStream_(iStream) { [iStream_ open]; }
~CPPInputStream() override { Close(); }
ExceptionOr<ByteArray> Read(std::int64_t size) override {
std::vector<uint8_t> buffer;
buffer.reserve(size);
NSInteger numberOfBytesRead = [iStream_ read:buffer.data() maxLength:size];
if (numberOfBytesRead == 0) {
return ExceptionOr<ByteArray>();
}
if (numberOfBytesRead < 0) {
return ExceptionOr<ByteArray>(Exception::kIo);
}
return ExceptionOr<ByteArray>(ByteArray((const char *)buffer.data(), numberOfBytesRead));
}
Exception Close() override {
[iStream_ close];
return Exception{Exception::kSuccess};
}
private:
// Prevent a retain cycle since NSInputStream will have a strong reference to this object.
__weak NSInputStream *iStream_;
};
// Wrap a c++ InputStream subclass in objective-c so it can be associated with the original
// NSInputStream object. The association makes it possible for the unique_ptr to live as long as
// the original user provided NSInputStream.
@implementation CPPInputStreamBinding {
@public
std::unique_ptr<CPPInputStream> _cppStream;
}
// This field's address is used as a unique identifier.
static char gAssociatedStreamKey;
- (instancetype)initWithStream:(NSInputStream *)stream {
self = [super init];
if (self) {
_cppStream = std::make_unique<CPPInputStream>(stream);
}
return self;
}
+ (void)bindToStream:(NSInputStream *)stream {
CPPInputStreamBinding *binding = [[CPPInputStreamBinding alloc] initWithStream:stream];
objc_setAssociatedObject(stream, &gAssociatedStreamKey, binding,
OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (InputStream &)getRefFromStream:(NSInputStream *)stream {
CPPInputStreamBinding *binding = objc_getAssociatedObject(stream, &gAssociatedStreamKey);
return *binding->_cppStream;
}
@end
@@ -0,0 +1,35 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCAdvertisingOptions.h"
#ifdef __cplusplus
namespace location {
namespace nearby {
namespace connections {
class AdvertisingOptions;
}
} // namespace nearby
} // namespace location
#endif
@interface GNCAdvertisingOptions (CppConversions)
#ifdef __cplusplus
- (location::nearby::connections::AdvertisingOptions)toCpp;
#endif
@end
@@ -0,0 +1,35 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCAdvertisingOptions.h"
#import <Foundation/Foundation.h>
#include "connections/advertising_options.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCAdvertisingOptions+CppConversions.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCStrategy+Internal.h"
using ::location::nearby::connections::AdvertisingOptions;
using ::location::nearby::connections::CppStrategyFromGNCStrategy;
@implementation GNCAdvertisingOptions (CppConversions)
- (AdvertisingOptions)toCpp {
AdvertisingOptions advertising_options;
advertising_options.strategy = CppStrategyFromGNCStrategy(self.strategy);
return advertising_options;
}
@end
@@ -0,0 +1,31 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCAdvertisingOptions.h"
#import <Foundation/Foundation.h>
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCStrategy.h"
@implementation GNCAdvertisingOptions
- (instancetype)initWithStrategy:(GNCStrategy)strategy {
self = [super init];
if (self) {
_strategy = strategy;
}
return self;
}
@end
@@ -0,0 +1,35 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCConnectionOptions.h"
#ifdef __cplusplus
namespace location {
namespace nearby {
namespace connections {
class ConnectionOptions;
}
} // namespace nearby
} // namespace location
#endif
@interface GNCConnectionOptions (CppConversions)
#ifdef __cplusplus
- (location::nearby::connections::ConnectionOptions)toCpp;
#endif
@end
@@ -0,0 +1,31 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCConnectionOptions.h"
#import <Foundation/Foundation.h>
#include "connections/connection_options.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCConnectionOptions+CppConversions.h"
using ::location::nearby::connections::ConnectionOptions;
@implementation GNCConnectionOptions (CppConversions)
- (ConnectionOptions)toCpp {
return ConnectionOptions{};
}
@end
@@ -0,0 +1,21 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCConnectionOptions.h"
#import <Foundation/Foundation.h>
@implementation GNCConnectionOptions
@end
@@ -0,0 +1,417 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCCoreAdapter.h"
#import <Foundation/Foundation.h>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "connections/core.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCAdvertisingOptions+CppConversions.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCConnectionOptions+CppConversions.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCDiscoveryOptions+CppConversions.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCError+Internal.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCPayload+CppConversions.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCAdvertisingOptions.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCConnectionDelegate.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCConnectionOptions.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCDiscoveryDelegate.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCDiscoveryOptions.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCError.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCPayload.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCPayloadDelegate.h"
using ::location::nearby::ByteArray;
using ::location::nearby::connections::AdvertisingOptions;
using ::location::nearby::connections::ConnectionListener;
using ::location::nearby::connections::ConnectionOptions;
using ::location::nearby::connections::ConnectionRequestInfo;
using ::location::nearby::connections::ConnectionResponseInfo;
using ::location::nearby::connections::Core;
using ::location::nearby::connections::DiscoveryListener;
using ::location::nearby::connections::DiscoveryOptions;
using ::location::nearby::connections::Payload;
using ::location::nearby::connections::PayloadListener;
using ::location::nearby::connections::PayloadProgressInfo;
using ResultListener = ::location::nearby::connections::ResultCallback;
using ::location::nearby::connections::ServiceControllerRouter;
using ::location::nearby::connections::Status;
GNCStatus GNCStatusFromCppStatus(Status status) {
switch (status.value) {
case Status::kSuccess:
return GNCStatusSuccess;
case Status::kError:
return GNCStatusError;
case Status::kOutOfOrderApiCall:
return GNCStatusOutOfOrderApiCall;
case Status::kAlreadyHaveActiveStrategy:
return GNCStatusAlreadyHaveActiveStrategy;
case Status::kAlreadyAdvertising:
return GNCStatusAlreadyAdvertising;
case Status::kAlreadyDiscovering:
return GNCStatusAlreadyDiscovering;
case Status::kEndpointIoError:
return GNCStatusEndpointIoError;
case Status::kEndpointUnknown:
return GNCStatusEndpointUnknown;
case Status::kConnectionRejected:
return GNCStatusConnectionRejected;
case Status::kAlreadyConnectedToEndpoint:
return GNCStatusAlreadyConnectedToEndpoint;
case Status::kNotConnectedToEndpoint:
return GNCStatusNotConnectedToEndpoint;
case Status::kBluetoothError:
return GNCStatusBluetoothError;
case Status::kBleError:
return GNCStatusBleError;
case Status::kWifiLanError:
return GNCStatusWifiLanError;
case Status::kPayloadUnknown:
return GNCStatusPayloadUnknown;
}
}
@interface GNCCoreAdapter () {
std::unique_ptr<Core> _core;
std::unique_ptr<ServiceControllerRouter> _serviceControllerRouter;
}
@end
@implementation GNCCoreAdapter
+ (GNCCoreAdapter *)shared {
static dispatch_once_t onceToken;
static GNCCoreAdapter *shared = nil;
dispatch_once(&onceToken, ^{
shared = [[GNCCoreAdapter alloc] init];
});
return shared;
}
- (instancetype)init {
self = [super init];
if (self) {
_serviceControllerRouter = std::make_unique<ServiceControllerRouter>();
_core = std::make_unique<Core>(_serviceControllerRouter.get());
}
return self;
}
- (void)dealloc {
// Make sure Core is deleted before ServiceControllerRouter.
_core.reset();
_serviceControllerRouter.reset();
}
- (void)startAdvertisingAsService:(NSString *)serviceID
endpointInfo:(NSData *)endpointInfo
options:(GNCAdvertisingOptions *)advertisingOptions
delegate:(id<GNCConnectionDelegate>)delegate
withCompletionHandler:(void (^)(NSError *error))completionHandler {
std::string service_id = [serviceID cStringUsingEncoding:[NSString defaultCStringEncoding]];
AdvertisingOptions advertising_options = [advertisingOptions toCpp];
ConnectionListener listener;
listener.initiated_cb = ^(const std::string &endpoint_id, const ConnectionResponseInfo &info) {
NSString *endpointID = @(endpoint_id.c_str());
NSData *endpointInfo = [NSData dataWithBytes:info.remote_endpoint_info.data()
length:info.remote_endpoint_info.size()];
NSString *authenticationToken = @(info.authentication_token.c_str());
[delegate connectedToEndpoint:endpointID
withEndpointInfo:endpointInfo
authenticationToken:authenticationToken];
};
listener.accepted_cb = ^(const std::string &endpoint_id) {
NSString *endpointID = @(endpoint_id.c_str());
[delegate acceptedConnectionToEndpoint:endpointID];
};
listener.rejected_cb = ^(const std::string &endpoint_id, Status status) {
NSString *endpointID = @(endpoint_id.c_str());
[delegate rejectedConnectionToEndpoint:endpointID withStatus:GNCStatusFromCppStatus(status)];
};
listener.disconnected_cb = ^(const std::string &endpoint_id) {
NSString *endpointID = @(endpoint_id.c_str());
[delegate disconnectedFromEndpoint:endpointID];
};
ConnectionRequestInfo connection_request_info;
connection_request_info.endpoint_info =
ByteArray((const char *)endpointInfo.bytes, endpointInfo.length);
connection_request_info.listener = std::move(listener);
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->StartAdvertising(service_id, advertising_options, connection_request_info, result);
}
- (void)stopAdvertisingWithCompletionHandler:(void (^)(NSError *error))completionHandler {
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->StopAdvertising(result);
}
- (void)startDiscoveryAsService:(NSString *)serviceID
options:(GNCDiscoveryOptions *)discoveryOptions
delegate:(id<GNCDiscoveryDelegate>)delegate
withCompletionHandler:(void (^)(NSError *error))completionHandler {
std::string service_id = [serviceID cStringUsingEncoding:[NSString defaultCStringEncoding]];
DiscoveryOptions discovery_options = [discoveryOptions toCpp];
DiscoveryListener listener;
listener.endpoint_found_cb = ^(const std::string &endpoint_id, const ByteArray &endpoint_info,
const std::string &service_id) {
NSString *endpointID = @(endpoint_id.c_str());
NSData *info = [NSData dataWithBytes:endpoint_info.data() length:endpoint_info.size()];
[delegate foundEndpoint:endpointID withEndpointInfo:info];
};
listener.endpoint_lost_cb = ^(const std::string &endpoint_id) {
NSString *endpointID = @(endpoint_id.c_str());
[delegate lostEndpoint:endpointID];
};
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->StartDiscovery(service_id, discovery_options, std::move(listener), result);
}
- (void)stopDiscoveryWithCompletionHandler:(void (^)(NSError *error))completionHandler {
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->StopDiscovery(result);
}
- (void)requestConnectionToEndpoint:(NSString *)endpointID
endpointInfo:(NSData *)endpointInfo
options:(GNCConnectionOptions *)connectionOptions
delegate:(id<GNCConnectionDelegate>)delegate
withCompletionHandler:(void (^)(NSError *error))completionHandler {
std::string endpoint_id = [endpointID cStringUsingEncoding:[NSString defaultCStringEncoding]];
ConnectionListener listener;
listener.initiated_cb = ^(const std::string &endpoint_id, const ConnectionResponseInfo &info) {
NSString *endpointID = @(endpoint_id.c_str());
NSData *endpointInfo = [NSData dataWithBytes:info.remote_endpoint_info.data()
length:info.remote_endpoint_info.size()];
NSString *authenticationToken = @(info.authentication_token.c_str());
[delegate connectedToEndpoint:endpointID
withEndpointInfo:endpointInfo
authenticationToken:authenticationToken];
};
listener.accepted_cb = ^(const std::string &endpoint_id) {
NSString *endpointID = @(endpoint_id.c_str());
[delegate acceptedConnectionToEndpoint:endpointID];
};
listener.rejected_cb = ^(const std::string &endpoint_id, Status status) {
NSString *endpointID = @(endpoint_id.c_str());
[delegate rejectedConnectionToEndpoint:endpointID withStatus:GNCStatusFromCppStatus(status)];
};
listener.disconnected_cb = ^(const std::string &endpoint_id) {
NSString *endpointID = @(endpoint_id.c_str());
[delegate disconnectedFromEndpoint:endpointID];
};
ConnectionRequestInfo connection_request_info;
connection_request_info.endpoint_info =
ByteArray((const char *)endpointInfo.bytes, endpointInfo.length);
connection_request_info.listener = std::move(listener);
ConnectionOptions connection_options = [connectionOptions toCpp];
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->RequestConnection(endpoint_id, connection_request_info, connection_options, result);
}
- (void)acceptConnectionRequestFromEndpoint:(NSString *)endpointID
delegate:(id<GNCPayloadDelegate>)delegate
withCompletionHandler:(void (^)(NSError *error))completionHandler {
std::string endpoint_id = [endpointID cStringUsingEncoding:[NSString defaultCStringEncoding]];
PayloadListener listener;
listener.payload_cb = ^(const std::string &endpoint_id, Payload payload) {
NSString *endpointID = @(endpoint_id.c_str());
GNCPayload *gncPayload = [GNCPayload fromCpp:std::move(payload)];
[delegate receivedPayload:gncPayload fromEndpoint:endpointID];
};
listener.payload_progress_cb =
^(const std::string &endpoint_id, const PayloadProgressInfo &info) {
NSString *endpointID = @(endpoint_id.c_str());
GNCPayloadStatus status;
switch (info.status) {
case PayloadProgressInfo::Status::kSuccess:
status = GNCPayloadStatusSuccess;
break;
case PayloadProgressInfo::Status::kFailure:
status = GNCPayloadStatusFailure;
break;
case PayloadProgressInfo::Status::kInProgress:
status = GNCPayloadStatusInProgress;
break;
case PayloadProgressInfo::Status::kCanceled:
status = GNCPayloadStatusCanceled;
break;
}
[delegate receivedProgressUpdateForPayload:info.payload_id
withStatus:status
fromEndpoint:endpointID
bytesTransfered:info.bytes_transferred
totalBytes:info.total_bytes];
};
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->AcceptConnection(endpoint_id, std::move(listener), result);
}
- (void)rejectConnectionRequestFromEndpoint:(NSString *)endpointID
withCompletionHandler:(void (^)(NSError *error))completionHandler {
std::string endpoint_id = [endpointID cStringUsingEncoding:[NSString defaultCStringEncoding]];
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->RejectConnection(endpoint_id, result);
}
- (void)sendPayload:(GNCPayload *)payload
toEndpoints:(NSArray<NSString *> *)endpointIDs
withCompletionHandler:(void (^)(NSError *error))completionHandler {
std::vector<std::string> endpoint_ids;
endpoint_ids.reserve([endpointIDs count]);
for (NSString *endpointID in endpointIDs) {
std::string endpoint_id = [endpointID cStringUsingEncoding:[NSString defaultCStringEncoding]];
endpoint_ids.push_back(endpoint_id);
}
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->SendPayload(endpoint_ids, [payload toCpp], result);
}
- (void)cancelPayload:(int64_t)payloadID
withCompletionHandler:(void (^)(NSError *error))completionHandler {
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->CancelPayload(payloadID, result);
}
- (void)disconnectFromEndpoint:(NSString *)endpointID
withCompletionHandler:(void (^)(NSError *error))completionHandler {
std::string endpoint_id = [endpointID cStringUsingEncoding:[NSString defaultCStringEncoding]];
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->DisconnectFromEndpoint(endpoint_id, result);
}
- (void)stopAllEndpointsWithCompletionHandler:(void (^)(NSError *error))completionHandler {
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->StopAllEndpoints(result);
}
- (void)initiateBandwidthUpgrade:(NSString *)endpointID
withCompletionHandler:(void (^)(NSError *error))completionHandler {
std::string endpoint_id = [endpointID cStringUsingEncoding:[NSString defaultCStringEncoding]];
ResultListener result;
result.result_cb = ^(Status status) {
NSError *err = NSErrorFromCppStatus(status);
if (completionHandler) {
completionHandler(err);
}
};
_core->InitiateBandwidthUpgrade(endpoint_id, result);
}
- (NSString *)localEndpointID {
std::string endpoint_id = _core->GetLocalEndpointId();
return @(endpoint_id.c_str());
}
@end
@@ -0,0 +1,35 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCDiscoveryOptions.h"
#ifdef __cplusplus
namespace location {
namespace nearby {
namespace connections {
class DiscoveryOptions;
}
} // namespace nearby
} // namespace location
#endif
@interface GNCDiscoveryOptions (CppConversions)
#ifdef __cplusplus
- (location::nearby::connections::DiscoveryOptions)toCpp;
#endif
@end
@@ -0,0 +1,35 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCDiscoveryOptions.h"
#import <Foundation/Foundation.h>
#include "connections/discovery_options.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCDiscoveryOptions+CppConversions.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCStrategy+Internal.h"
using ::location::nearby::connections::CppStrategyFromGNCStrategy;
using ::location::nearby::connections::DiscoveryOptions;
@implementation GNCDiscoveryOptions (CppConversions)
- (DiscoveryOptions)toCpp {
DiscoveryOptions discovery_options;
discovery_options.strategy = CppStrategyFromGNCStrategy(self.strategy);
return discovery_options;
}
@end
@@ -0,0 +1,31 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCDiscoveryOptions.h"
#import <Foundation/Foundation.h>
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCStrategy.h"
@implementation GNCDiscoveryOptions
- (instancetype)initWithStrategy:(GNCStrategy)strategy {
self = [super init];
if (self) {
_strategy = strategy;
}
return self;
}
@end
@@ -0,0 +1,26 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
#ifdef __cplusplus
namespace location {
namespace nearby {
namespace connections {
class Status;
NSError *NSErrorFromCppStatus(Status status);
} // namespace connections
} // namespace nearby
} // namespace location
#endif
@@ -0,0 +1,72 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCError.h"
#import <Foundation/Foundation.h>
#include "connections/status.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCError+Internal.h"
extern NSErrorDomain const GNCErrorDomain = @"com.google.nearby.connections.error";
namespace location {
namespace nearby {
namespace connections {
NSError *NSErrorFromCppStatus(Status status) {
switch (status.value) {
case Status::kSuccess:
return nil;
case Status::kError:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorUnknown userInfo:nil];
case Status::kOutOfOrderApiCall:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorOutOfOrderApiCall userInfo:nil];
case Status::kAlreadyHaveActiveStrategy:
return [NSError errorWithDomain:GNCErrorDomain
code:GNCErrorAlreadyHaveActiveStrategy
userInfo:nil];
case Status::kAlreadyAdvertising:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorAlreadyAdvertising userInfo:nil];
case Status::kAlreadyDiscovering:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorAlreadyDiscovering userInfo:nil];
case Status::kEndpointIoError:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorEndpointIoError userInfo:nil];
case Status::kEndpointUnknown:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorEndpointUnknown userInfo:nil];
case Status::kConnectionRejected:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorConnectionRejected userInfo:nil];
case Status::kAlreadyConnectedToEndpoint:
return [NSError errorWithDomain:GNCErrorDomain
code:GNCErrorAlreadyConnectedToEndpoint
userInfo:nil];
case Status::kNotConnectedToEndpoint:
return [NSError errorWithDomain:GNCErrorDomain
code:GNCErrorNotConnectedToEndpoint
userInfo:nil];
case Status::kBluetoothError:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorBluetoothError userInfo:nil];
case Status::kBleError:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorBleError userInfo:nil];
case Status::kWifiLanError:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorWifiLanError userInfo:nil];
case Status::kPayloadUnknown:
return [NSError errorWithDomain:GNCErrorDomain code:GNCErrorPayloadUnknown userInfo:nil];
}
}
} // namespace connections
} // namespace nearby
} // namespace location
@@ -0,0 +1,26 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
#ifdef __cplusplus
namespace location {
namespace nearby {
class Exception;
namespace connections {
NSError *NSErrorFromCppException(Exception exception);
} // namespace connections
} // namespace nearby
} // namespace location
#endif
@@ -0,0 +1,57 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCException.h"
#import <Foundation/Foundation.h>
// TODO(b/239758418): Change this to the non-internal version when available.
#include "internal/platform/exception.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCException+Internal.h"
extern NSErrorDomain const GNCExceptionDomain = @"com.google.nearby.connections.exception";
namespace location {
namespace nearby {
namespace connections {
NSError *NSErrorFromCppException(Exception exception) {
switch (exception.value) {
case Exception::kSuccess:
return nil;
case Exception::kFailed:
return [NSError errorWithDomain:GNCExceptionDomain code:GNCExceptionUnknown userInfo:nil];
case Exception::kIo:
return [NSError errorWithDomain:GNCExceptionDomain code:GNCExceptionIO userInfo:nil];
case Exception::kInterrupted:
return [NSError errorWithDomain:GNCExceptionDomain code:GNCExceptionInterrupted userInfo:nil];
case Exception::kInvalidProtocolBuffer:
return [NSError errorWithDomain:GNCExceptionDomain
code:GNCExceptionInvalidProtocolBuffer
userInfo:nil];
case Exception::kExecution:
return [NSError errorWithDomain:GNCExceptionDomain code:GNCExceptionExecution userInfo:nil];
case Exception::kTimeout:
return [NSError errorWithDomain:GNCExceptionDomain code:GNCExceptionTimeout userInfo:nil];
case Exception::kIllegalCharacters:
return [NSError errorWithDomain:GNCExceptionDomain
code:GNCExceptionIllegalCharacters
userInfo:nil];
}
}
} // namespace connections
} // namespace nearby
} // namespace location
@@ -0,0 +1,36 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
#ifdef __cplusplus
namespace location {
namespace nearby {
class InputStream;
}
} // namespace location
#endif
@interface GNCInputStream : NSInputStream <NSStreamDelegate>
- (nonnull instancetype)initWithData:(nonnull NSData *)data NS_UNAVAILABLE;
- (nonnull instancetype)initWithURL:(nonnull NSURL *)url NS_UNAVAILABLE;
#ifdef __cplusplus
- (nonnull instancetype)initWithCppInputStream:(nonnull location::nearby::InputStream *)stream
NS_DESIGNATED_INITIALIZER;
#endif
@end
@@ -0,0 +1,124 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCInputStream.h"
#import <Foundation/Foundation.h>
#include <algorithm>
// TODO(b/239758418): Change this to the non-internal version when available.
#include "internal/platform/input_stream.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCException+Internal.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCException.h"
using ::location::nearby::ByteArray;
using ::location::nearby::ExceptionOr;
using ::location::nearby::InputStream;
using ::location::nearby::connections::NSErrorFromCppException;
@implementation GNCInputStream {
NSStreamStatus _streamStatus;
NSError *_streamError;
id<NSStreamDelegate> _delegate;
InputStream *_stream;
}
- (instancetype)initWithCppInputStream:(InputStream *)stream {
// Init with empty data because init is not a designated initializer.
self = [super initWithData:[[NSData alloc] init]];
if (self) {
_streamStatus = NSStreamStatusNotOpen;
_delegate = self;
_stream = stream;
}
return self;
}
- (BOOL)hasBytesAvailable {
return _streamStatus == NSStreamStatusOpen;
}
- (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)maxLen {
ExceptionOr<ByteArray> readResult = _stream->Read(maxLen);
if (!readResult.ok()) {
_streamError = NSErrorFromCppException(readResult.GetException());
_streamStatus = NSStreamStatusError;
return -1;
}
ByteArray byteArray = readResult.GetResult();
if (byteArray.size() == 0) {
_streamStatus = NSStreamStatusAtEnd;
return 0;
}
memcpy(buffer, byteArray.data(), std::min(maxLen, byteArray.size()));
return byteArray.size();
}
- (BOOL)getBuffer:(uint8_t **)buffer length:(NSUInteger *)length {
return NO;
}
- (void)scheduleInRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode {
}
- (void)removeFromRunLoop:(NSRunLoop *)runLoop forMode:(NSString *)mode {
}
- (void)open {
_streamStatus = NSStreamStatusOpen;
}
- (void)close {
_streamStatus = NSStreamStatusClosed;
_stream->Close();
}
- (NSStreamStatus)streamStatus {
return _streamStatus;
}
- (NSError *)streamError {
return _streamError;
}
- (id<NSStreamDelegate>)delegate {
return _delegate;
}
- (void)setDelegate:(id<NSStreamDelegate>)delegate {
// By default, a stream is its own delegate, and subclasses of NSInputStream and NSOutputStream
// must maintain this contract. Since we override this method in our subclass, we must
// restore the receiver as its own delegate when passed nil.
if (delegate) {
_delegate = delegate;
} else {
_delegate = self;
}
}
- (id)propertyForKey:(NSStreamPropertyKey)key {
return nil;
}
- (BOOL)setProperty:(id)property forKey:(NSStreamPropertyKey)key {
return NO;
}
@end
@@ -0,0 +1,39 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCPayload.h"
#ifdef __cplusplus
namespace location {
namespace nearby {
namespace connections {
class Payload;
}
} // namespace nearby
} // namespace location
#endif
@interface GNCPayload (CppConversions)
#ifdef __cplusplus
+ (nonnull GNCPayload *)fromCpp:(location::nearby::connections::Payload)payload;
#endif
#ifdef __cplusplus
- (location::nearby::connections::Payload)toCpp;
#endif
@end
@@ -0,0 +1,100 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCPayload.h"
#import <Foundation/Foundation.h>
#include <string>
#include "connections/payload.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/CPPInputStreamBinding.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCInputStream.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCPayload+CppConversions.h"
using ::location::nearby::ByteArray;
using ::location::nearby::InputFile;
using ::location::nearby::InputStream;
using ::location::nearby::connections::Payload;
@implementation GNCPayload (CppConversions)
+ (GNCPayload *)fromCpp:(Payload)payload {
int64_t payloadId = payload.GetId();
switch (payload.GetType()) {
case location::nearby::connections::PayloadType::kBytes: {
ByteArray bytes = payload.AsBytes();
NSData *payloadData = [NSData dataWithBytes:bytes.data() length:bytes.size()];
return [[GNCBytesPayload alloc] initWithData:payloadData identifier:payloadId];
}
case location::nearby::connections::PayloadType::kFile: {
InputFile *inputFile = payload.AsFile();
NSString *filePath = @(inputFile->GetFilePath().c_str());
NSString *parentFolder = @(payload.GetParentFolder().c_str());
NSString *fileName = @(payload.GetFileName().c_str());
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
return [[GNCFilePayload alloc] initWithFileURL:fileURL
parentFolder:parentFolder
fileName:fileName
identifier:payloadId];
}
case location::nearby::connections::PayloadType::kStream: {
GNCInputStream *stream = [[GNCInputStream alloc] initWithCppInputStream:payload.AsStream()];
return [[GNCStreamPayload alloc] initWithStream:stream identifier:payloadId];
}
case location::nearby::connections::PayloadType::kUnknown:
return nil;
}
}
- (Payload)toCpp {
return Payload();
}
@end
@implementation GNCBytesPayload (CppConversions)
- (Payload)toCpp {
return Payload(self.identifier, ByteArray((const char *)self.data.bytes, self.data.length));
}
@end
@implementation GNCStreamPayload (CppConversions)
- (Payload)toCpp {
// GNCStreamPayload will most likely be destroyed almost immediately, so a weak self would be
// useless and a strong self will cause a retain cycle. This is why we are keeping a weak
// reference of the stream instead. The input stream should be kept alive by a strong reference
// on the user end.
__weak NSInputStream *stream = self.stream;
return Payload(self.identifier, [stream]() -> InputStream & {
return [CPPInputStreamBinding getRefFromStream:stream];
});
}
@end
@implementation GNCFilePayload (CppConversions)
- (Payload)toCpp {
std::string path = [self.fileURL.path cStringUsingEncoding:[NSString defaultCStringEncoding]];
std::string folder = [self.parentFolder cStringUsingEncoding:[NSString defaultCStringEncoding]];
std::string name = [self.fileName cStringUsingEncoding:[NSString defaultCStringEncoding]];
return Payload(self.identifier, folder, name, InputFile(path, self.totalSize.longLongValue));
}
@end
@@ -0,0 +1,114 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCPayload.h"
#import <Foundation/Foundation.h>
#include <string>
#include "connections/payload.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/CPPInputStreamBinding.h"
using ::location::nearby::connections::Payload;
@implementation GNCPayload
+ (int64_t)generateID {
return Payload::GenerateId();
}
- (instancetype)initWithIdentifier:(int64_t)identifier {
self = [super init];
if (self) {
_identifier = identifier;
}
return self;
}
@end
@implementation GNCBytesPayload
- (instancetype)initWithData:(NSData *)data identifier:(int64_t)identifier {
self = [super initWithIdentifier:identifier];
if (self) {
_data = [data copy];
}
return self;
}
- (instancetype)initWithData:(NSData *)data {
return [self initWithData:data identifier:Payload::GenerateId()];
}
@end
@implementation GNCStreamPayload
- (instancetype)initWithStream:(NSInputStream *)stream identifier:(int64_t)identifier {
self = [super initWithIdentifier:identifier];
if (self) {
_stream = stream;
[CPPInputStreamBinding bindToStream:stream];
}
return self;
}
- (instancetype)initWithStream:(NSInputStream *)stream {
return [self initWithStream:stream identifier:Payload::GenerateId()];
}
@end
@implementation GNCFilePayload
@synthesize totalSize = _totalSize;
- (NSNumber *)totalSize {
if (!_totalSize) {
NSNumber *fileSize;
BOOL result = [_fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:nil];
if (!result) {
fileSize = [NSNumber numberWithInt:-1];
}
_totalSize = fileSize;
}
return _totalSize;
}
- (instancetype)initWithFileURL:(NSURL *)fileURL
parentFolder:(NSString *)parentFolder
fileName:(NSString *)fileName
identifier:(int64_t)identifier {
self = [super initWithIdentifier:identifier];
if (self) {
_fileURL = [fileURL copy];
_parentFolder = [parentFolder copy];
_fileName = [fileName copy];
}
return self;
}
- (instancetype)initWithFileURL:(NSURL *)fileURL
parentFolder:(NSString *)parentFolder
fileName:(NSString *)fileName {
return [self initWithFileURL:fileURL
parentFolder:parentFolder
fileName:fileName
identifier:Payload::GenerateId()];
}
@end
@@ -1,4 +1,4 @@
// Copyright 2020 Google LLC
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -11,19 +11,18 @@
// 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 CORE_CONFIG_H_
#define CORE_CONFIG_H_
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, GNCStrategy);
#ifdef __cplusplus
namespace location {
namespace nearby {
namespace connections {
// TODO(b/224783653): Update DLL_API to check if we can add dllimport back.
#define DLL_API // Define DLL_API as blank since we don't import/export
// anything internally.
class Strategy;
Strategy CppStrategyFromGNCStrategy(GNCStrategy strategy);
} // namespace connections
} // namespace nearby
} // namespace location
#endif // CORE_CONFIG_H_
#endif
@@ -0,0 +1,40 @@
// Copyright 2022 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.
#import "connections/clients/swift/NearbyCoreAdapter/Sources/Public/NearbyCoreAdapter/GNCStrategy.h"
#import <Foundation/Foundation.h>
#include "connections/strategy.h"
#import "connections/clients/swift/NearbyCoreAdapter/Sources/GNCStrategy+Internal.h"
namespace location {
namespace nearby {
namespace connections {
Strategy CppStrategyFromGNCStrategy(GNCStrategy strategy) {
switch (strategy) {
case GNCStrategyCluster:
return Strategy::kP2pCluster;
case GNCStrategyStar:
return Strategy::kP2pStar;
case GNCStrategyPointToPoint:
return Strategy::kP2pPointToPoint;
}
}
} // namespace connections
} // namespace nearby
} // namespace location
@@ -0,0 +1,44 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
typedef NS_CLOSED_ENUM(NSInteger, GNCStrategy);
// TODO(b/239609583): Current sdk only exposes `strategy`, but we should add full support.
/**
* A @c GNCAdvertisingOptions object represents the configuration for local endpoint advertisement.
*/
@interface GNCAdvertisingOptions : NSObject
/**
* The connection strategy.
*/
@property(nonatomic, readonly) GNCStrategy strategy;
/**
* @remark init is not an available initializer.
*/
- (nonnull instancetype)init NS_UNAVAILABLE;
/**
* Creates an advertising options object.
*
* @param strategy The connection strategy.
*
* @return The initialized options object, or nil if an error occurs.
*/
- (nonnull instancetype)initWithStrategy:(GNCStrategy)strategy NS_DESIGNATED_INITIALIZER;
@end
@@ -0,0 +1,95 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
/**
* Indicates the status of a connection.
*/
typedef NS_CLOSED_ENUM(NSInteger, GNCStatus) {
GNCStatusSuccess,
GNCStatusError,
GNCStatusOutOfOrderApiCall,
GNCStatusAlreadyHaveActiveStrategy,
GNCStatusAlreadyAdvertising,
GNCStatusAlreadyDiscovering,
GNCStatusEndpointIoError,
GNCStatusEndpointUnknown,
GNCStatusConnectionRejected,
GNCStatusAlreadyConnectedToEndpoint,
GNCStatusNotConnectedToEndpoint,
GNCStatusBluetoothError,
GNCStatusBleError,
GNCStatusWifiLanError,
GNCStatusPayloadUnknown,
};
/**
* The @c GNCConnectionDelegate protocol defines methods that a delegate can implement to handle
* connection-related events.
*/
@protocol GNCConnectionDelegate
/**
* A basic encrypted channel has been created between you and the endpoint. Both sides are now
* asked if they wish to accept or reject the connection before any data can be sent over this
* channel.
*
* This is your chance, before you accept the connection, to confirm that you connected to the
* correct device. Both devices are given an identical token; it's up to you to decide how to
* verify it before proceeding. Typically this involves showing the token on both devices and
* having the users manually compare and confirm; however, this is only required if you desire a
* secure connection between the devices.
*
* Whichever route you decide to take (including not authenticating the other device), call
* GNCCoreAdapter::acceptConnectionRequestFromEndpoint:delegate: when you're ready to talk, or
* GNCCoreAdapter::rejectConnectionRequestFromEndpoint:withCompletionHandler: to close the
* connection.
*
* @param endpointID The identifier for the remote endpoint.
* @param info Other relevant information about the connection.
* @param authenticationToken The token to be verified.
*/
- (void)connectedToEndpoint:(nonnull NSString *)endpointID
withEndpointInfo:(nonnull NSData *)info
authenticationToken:(nonnull NSString *)authenticationToken;
/**
* Called after both sides have accepted the connection. Both sides may now send Payloads to each
* other.
*
* @param endpointID The identifier for the remote endpoint.
*/
- (void)acceptedConnectionToEndpoint:(nonnull NSString *)endpointID;
/**
* Called when either side rejected the connection. Payloads can not be exchaged. Call
* GNCCoreAdapter::disconnectFromEndpoint:withCompletionHandler: to terminate the connection.
*
* @param endpointID The identifier for the remote endpoint.
* @param status The reason for rejection.
*/
- (void)rejectedConnectionToEndpoint:(nonnull NSString *)endpointID withStatus:(GNCStatus)status;
/**
* Called when a remote endpoint is disconnected or has become unreachable. At this point service
* (re-)discovery may start again.
*
* @param endpointID The identifier for the remote endpoint.
*/
- (void)disconnectedFromEndpoint:(nonnull NSString *)endpointID;
// TODO(b/239832442): Add OnBandwidthChanged(const std::string &endpoint_id, Medium medium).
@end
@@ -0,0 +1,23 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
// TODO(b/239610255): Current sdk doesn't expose anything, but we should add full support.
/**
* A @c GNCConnectionOptions object represents the configuration for connecting to remote endpoints.
*/
@interface GNCConnectionOptions : NSObject
@end
@@ -0,0 +1,194 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
@class GNCAdvertisingOptions;
@class GNCConnectionOptions;
@class GNCDiscoveryOptions;
@class GNCPayload;
@protocol GNCConnectionDelegate;
@protocol GNCDiscoveryDelegate;
@protocol GNCPayloadDelegate;
/**
* This class defines the API of the Nearby Connections Core library.
*/
@interface GNCCoreAdapter : NSObject
/**
* A @c GNCCoreAdapter singleton.
*/
@property(nonnull, nonatomic, class, readonly) GNCCoreAdapter *shared;
/**
* Starts advertising an endpoint for a local app.
*
* @param serviceID An identifier to advertise your app to other endpoints. This can be an arbitrary
* string, so long as it uniquely identifies your service. A good default is to use
* your app's package name.
* @param endpointInfo Arbitrary bytes of additional data that can be read and used by remote
* endpoints. A good default is a utf-8 encoded string to represent a local
* endpoint name.
* @param advertisingOptions The options for advertising.
* @param delegate A delegate to handle notifications about connection events.
* @param completionHandler Access the status of the operation when available.
*/
- (void)startAdvertisingAsService:(nonnull NSString *)serviceID
endpointInfo:(nonnull NSData *)endpointInfo
options:(nonnull GNCAdvertisingOptions *)advertisingOptions
delegate:(nullable id<GNCConnectionDelegate>)delegate
withCompletionHandler:(nullable void (^)(NSError *_Nullable error))completionHandler;
/**
* Stops advertising a local endpoint. Should be called after calling
* startAdvertisingAsService:endpointInfo:options:delegate:withCompletionHandler:, as soon as the
* application no longer needs to advertise itself or goes inactive. Payloads can still be sent to
* connected endpoints after advertising ends.
*
* @param completionHandler Access the status of the operation when available.
*/
- (void)stopAdvertisingWithCompletionHandler:
(nullable void (^)(NSError *_Nonnull error))completionHandler;
/**
* Starts discovery for remote endpoints with the specified service ID.
*
* @param serviceID The ID for the service to be discovered, as specified in the corresponding call
* to start advertising.
* @param discoveryOptions The options for discovery.
* @param delegate A delegate to handle notifications about endpoint discovery events.
* @param completionHandler Access the status of the operation when available.
*/
- (void)startDiscoveryAsService:(nonnull NSString *)serviceID
options:(nonnull GNCDiscoveryOptions *)discoveryOptions
delegate:(nullable id<GNCDiscoveryDelegate>)delegate
withCompletionHandler:(nullable void (^)(NSError *_Nullable error))completionHandler;
/**
* Stops discovery for remote endpoints, after a previous call to
* startDiscoveryAsService:options:delegate:withCompletionHandler:, when the client no longer needs
* to discover endpoints or goes inactive. Payloads can still be sent to connected endpoints after
* discovery ends.
*
* @param completionHandler Access the status of the operation when available.
*/
- (void)stopDiscoveryWithCompletionHandler:
(nullable void (^)(NSError *_Nonnull error))completionHandler;
/**
* Sends a request to connect to a remote endpoint.
*
* @param endpointID The identifier for the remote endpoint to which a connection request will be
* sent. Should match the endpointID provided by the
* GNCDiscoveryDelegate::foundEndpoint:withEndpointInfo: delegate method.
* @param endpointInfo Arbitrary bytes of additional data that can be read and used by remote
* endpoints. A good default is a utf-8 encoded string to represent a local
* endpoint name.
* @param connectionOptions The options for connecting.
* @param delegate A delegate to handle notifications about connection events.
* @param completionHandler Access the status of the operation when available.
*/
- (void)requestConnectionToEndpoint:(nonnull NSString *)endpointID
endpointInfo:(nonnull NSData *)endpointInfo
options:(nonnull GNCConnectionOptions *)connectionOptions
delegate:(nullable id<GNCConnectionDelegate>)delegate
withCompletionHandler:(nullable void (^)(NSError *_Nullable error))completionHandler;
/**
* Accepts a connection to a remote endpoint. This method must be called before payloads can be
* exchanged with the remote endpoint.
* @param endpointID The identifier for the remote endpoint. Should match the endpointID provided by
* the
* GNCConnectionDelegate::connectedToEndpoint:withEndpointInfo:authenticationToken: delegate method.
* @param delegate A delegate to handle notifications about incoming payload events.
* @param completionHandler Access the status of the operation when available.
*/
- (void)acceptConnectionRequestFromEndpoint:(nonnull NSString *)endpointID
delegate:(nullable id<GNCPayloadDelegate>)delegate
withCompletionHandler:
(nullable void (^)(NSError *_Nullable error))completionHandler;
/**
* Rejects a connection to a remote endpoint.
*
* @param endpointID The identifier for the remote endpoint. Should match the endpointID provided by
* the
* GNCConnectionDelegate::connectedToEndpoint:withEndpointInfo:authenticationToken: delegate method.
* @param completionHandler Access the status of the operation when available.
*/
- (void)rejectConnectionRequestFromEndpoint:(nonnull NSString *)endpointID
withCompletionHandler:
(nullable void (^)(NSError *_Nullable error))completionHandler;
/**
* Sends a payload to a list of remote endpoints. Payloads can only be sent to remote endpoints once
* a notice of connection acceptance has been delivered via
* GNCConnectionDelegate::acceptedConnectionToEndpoint:.
*
* @param payload The Payload to be sent.
* @param endpointIDs List of remote endpoint identifiers to which the payload should be sent.
* @param completionHandler Access the status of the operation when available.
*/
- (void)sendPayload:(nonnull GNCPayload *)payload
toEndpoints:(nonnull NSArray<NSString *> *)endpointIDs
withCompletionHandler:(nullable void (^)(NSError *_Nullable error))completionHandler;
/**
* Cancels a payload currently in-flight to or from remote endpoint(s).
*
* @param payloadID The identifier for the Payload to be canceled.
* @param completionHandler Access the status of the operation when available.
*/
- (void)cancelPayload:(int64_t)payloadID
withCompletionHandler:(nullable void (^)(NSError *_Nullable error))completionHandler;
/**
* Disconnects from a remote endpoint. Payloads can no longer be sent to or received from the
* endpoint after this method is called.
*
* @param endpointID The identifier for the remote endpoint to disconnect from.
* @param completionHandler Access the status of the operation when available.
*/
- (void)disconnectFromEndpoint:(nonnull NSString *)endpointID
withCompletionHandler:(nullable void (^)(NSError *_Nullable error))completionHandler;
/**
* Disconnects from, and removes all traces of, all connected and/or discovered endpoints. This call
* is expected to be preceded by a call to stop advertising or discovery as needed. After calling
* stopAllEndpointsWithCompletionHandler:, no further operations with remote endpoints will be
* possible until a new call to start advertising or discovery.
*
* @param completionHandler Access the status of the operation when available.
*/
- (void)stopAllEndpointsWithCompletionHandler:
(nullable void (^)(NSError *_Nullable error))completionHandler;
/**
* Sends a request to initiate connection bandwidth upgrade.
*
* @param endpointID The identifier for the remote endpoint which will be switching to a higher
* connection data rate and possibly different wireless protocol.
* @param completionHandler Access the status of the operation when available.
*/
- (void)initiateBandwidthUpgrade:(nonnull NSString *)endpointID
withCompletionHandler:(nullable void (^)(NSError *_Nullable error))completionHandler;
/**
* The local endpoint indentifier generated by Nearby Connections.
*/
@property(nonnull, nonatomic, readonly, copy) NSString *localEndpointID;
@end
@@ -0,0 +1,38 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
/**
* The @c GNCDiscoveryDelegate protocol defines methods that a delegate can implement to handle
* discovery-related events.
*/
@protocol GNCDiscoveryDelegate
/**
* Called when a remote endpoint is discovered.
*
* @param endpointID The ID of the remote endpoint that was discovered.
* @param info The info of the remote endpoint represented by bytes.
*/
- (void)foundEndpoint:(nonnull NSString *)endpointID withEndpointInfo:(nonnull NSData *)info;
/**
* Called when a remote endpoint is no longer discoverable.
*
* @param endpointID The ID of the remote endpoint that was lost.
*/
- (void)lostEndpoint:(nonnull NSString *)endpointID;
@end
@@ -0,0 +1,44 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
typedef NS_CLOSED_ENUM(NSInteger, GNCStrategy);
// TODO(b/239610253): Current sdk only exposes `strategy`, but we should add full support.
/**
* A @c GNCDiscoveryOptions object represents the configuration for remote endpoint discovery.
*/
@interface GNCDiscoveryOptions : NSObject
/**
* The connection strategy.
*/
@property(nonatomic, readonly) GNCStrategy strategy;
/**
* @remark init is not an available initializer.
*/
- (nonnull instancetype)init NS_UNAVAILABLE;
/**
* Creates a discovery options object.
*
* @param strategy The connection strategy.
*
* @return The initialized options object, or nil if an error occurs.
*/
- (nonnull instancetype)initWithStrategy:(GNCStrategy)strategy NS_DESIGNATED_INITIALIZER;
@end
@@ -0,0 +1,40 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
/**
* The domain for @c NSErrors raised by Nearby Connections.
*/
extern NSErrorDomain const GNCErrorDomain;
/**
* Nearby Connections error codes.
*/
typedef NS_ERROR_ENUM(GNCErrorDomain, GNCErrorCode){
GNCErrorUnknown,
GNCErrorOutOfOrderApiCall,
GNCErrorAlreadyHaveActiveStrategy,
GNCErrorAlreadyAdvertising,
GNCErrorAlreadyDiscovering,
GNCErrorEndpointIoError,
GNCErrorEndpointUnknown,
GNCErrorConnectionRejected,
GNCErrorAlreadyConnectedToEndpoint,
GNCErrorNotConnectedToEndpoint,
GNCErrorBluetoothError,
GNCErrorBleError,
GNCErrorWifiLanError,
GNCErrorPayloadUnknown,
} NS_SWIFT_NAME(NearbyError);
@@ -0,0 +1,30 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
/**
* The domain for @c NSErrors raised by Nearby Connections as exceptions.
*/
extern NSErrorDomain const GNCExceptionDomain;
/**
* Nearby Connections exception codes.
*/
typedef NS_ERROR_ENUM(GNCExceptionDomain, GNCExceptionCode){
GNCExceptionUnknown, GNCExceptionIO,
GNCExceptionInterrupted, GNCExceptionInvalidProtocolBuffer,
GNCExceptionExecution, GNCExceptionTimeout,
GNCExceptionIllegalCharacters,
} NS_SWIFT_NAME(NearbyException);
@@ -0,0 +1,159 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
/**
* A @c GNCPayload object represents the data being sent to or received from a remote device.
*/
@interface GNCPayload : NSObject
/**
* The unique identifier for this payload.
*/
@property(nonatomic, readonly) int64_t identifier;
/**
* @remark init is not an available initializer.
*/
- (nonnull instancetype)init NS_UNAVAILABLE;
/**
* Generates a random payload ID.
*/
+ (int64_t)generateID;
@end
/**
* A @c GNCBytesPayload object represents a payload that holds simple bytes.
*/
@interface GNCBytesPayload : GNCPayload
/**
* The byte data for this payload.
*/
@property(nonnull, nonatomic, readonly, copy) NSData *data;
/**
* Creates a bytes payload object with identifier.
*
* @param data An instance containing the message to send.
* @param identifier A unique identifier for the payload.
*
* @return The initialized payload object, or nil if an error occurs.
*/
- (nonnull instancetype)initWithData:(nonnull NSData *)data
identifier:(int64_t)identifier NS_DESIGNATED_INITIALIZER;
/**
* Creates a bytes payload object.
*
* @param data An instance containing the message to send.
* @return The initialized payload object, or nil if an error occurs.
*/
- (nonnull instancetype)initWithData:(nonnull NSData *)data;
@end
/**
* A @c GNCStreamPayload object represents a payload holds an open stream that can be read from by
* remote endpoints.
*/
@interface GNCStreamPayload : GNCPayload
/**
* The open stream for this payload.
*/
@property(nonnull, nonatomic, readonly) NSInputStream *stream;
/**
* Creates a stream payload object with identifier.
*
* @param stream An input stream instance.
* @param identifier A unique identifier for the payload.
*
* @return The initialized payload object, or nil if an error occurs.
*/
- (nonnull instancetype)initWithStream:(nonnull NSInputStream *)stream
identifier:(int64_t)identifier NS_DESIGNATED_INITIALIZER;
/**
* Creates a stream payload object.
*
* @param stream An input stream instance.
*
* @return The initialized payload object, or nil if an error occurs.
*/
- (nonnull instancetype)initWithStream:(nonnull NSInputStream *)stream;
@end
/**
* A @c GNCFilePayload object represents a payload that holds a file.
*/
@interface GNCFilePayload : GNCPayload
/**
* The URL of the file associated with this payload.
*/
@property(nonnull, nonatomic, readonly, copy) NSURL *fileURL;
/**
* The relative path where the remote device should save this payload.
*/
@property(nonnull, nonatomic, readonly, copy) NSString *parentFolder;
/**
* The file name the remote device should save this payload as.
*
* This value does not have to be respected (you could ask to save it as "photo.png" but instead the
* recipient saves it as "photo (1).png")
*/
@property(nonnull, nonatomic, readonly, copy) NSString *fileName;
/**
* The total size of the file associated with this payload in bytes.
*/
@property(nonnull, nonatomic, readonly, copy) NSNumber *totalSize;
/**
* Creates a file payload object with identifier.
*
* @param fileURL A file URL.
* @param parentFolder The relative path where the remote device should save this payload.
* @param fileName The file name the remote device should save this payload as.
* @param identifier A unique identifier for the payload.
*
* @return The initialized payload object, or nil if an error occurs.
*/
- (nonnull instancetype)initWithFileURL:(nonnull NSURL *)fileURL
parentFolder:(nonnull NSString *)parentFolder
fileName:(nonnull NSString *)fileName
identifier:(int64_t)identifier NS_DESIGNATED_INITIALIZER;
/**
* Creates a file payload object.
*
* @param fileURL A file URL.
* @param parentFolder The relative path where the remote device should save this payload.
* @param fileName The file name the remote device should save this payload as.
*
* @return The initialized payload object, or nil if an error occurs.
*/
- (nonnull instancetype)initWithFileURL:(nonnull NSURL *)fileURL
parentFolder:(nonnull NSString *)parentFolder
fileName:(nonnull NSString *)fileName;
@end
@@ -0,0 +1,60 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
@class GNCPayload;
/**
* Indicates the status of a payload transfer.
*/
typedef NS_CLOSED_ENUM(NSInteger, GNCPayloadStatus) {
GNCPayloadStatusSuccess,
GNCPayloadStatusFailure,
GNCPayloadStatusInProgress,
GNCPayloadStatusCanceled,
};
/**
* The @c GNCPayloadDelegate protocol defines methods that a delegate can implement to handle
* payload-related events.
*/
@protocol GNCPayloadDelegate
/**
* Called when a payload is received from a remote endpoint. Depending on the type of the payload,
* all of the data may or may not have been received at the time of this call.
*
* @param payload The Payload object received.
* @param endpointID The identifier for the remote endpoint that sent the payload.
*/
- (void)receivedPayload:(nonnull GNCPayload *)payload fromEndpoint:(nonnull NSString *)endpointID;
/**
* Called with progress information about an active payload transfer, either incoming or outgoing.
*
* @param payloadID The identifier the sent or received payload.
* @param status The status of the payload transfer.
* @param endpointID The identifier for the remote endpoint that is sending or receiving this
* payload.
* @param bytesTransfered The number of bytes transfered so far.
* @param totalBytes The total bytes of the transfer.
*/
- (void)receivedProgressUpdateForPayload:(int64_t)payloadID
withStatus:(GNCPayloadStatus)status
fromEndpoint:(nonnull NSString *)endpointID
bytesTransfered:(int64_t)bytesTransfered
totalBytes:(int64_t)totalBytes;
@end
@@ -0,0 +1,24 @@
// Copyright 2022 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.
#import <Foundation/Foundation.h>
/**
* Indicates the strategy or advertisement or discovery.
*/
typedef NS_CLOSED_ENUM(NSInteger, GNCStrategy) {
GNCStrategyCluster, // M-to-N
GNCStrategyStar, // 1-to-N
GNCStrategyPointToPoint, // 1-to-1
} NS_SWIFT_NAME(Strategy);
@@ -0,0 +1,24 @@
// Copyright 2022 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.
#import "GNCAdvertisingOptions.h"
#import "GNCConnectionDelegate.h"
#import "GNCConnectionOptions.h"
#import "GNCCoreAdapter.h"
#import "GNCDiscoveryDelegate.h"
#import "GNCDiscoveryOptions.h"
#import "GNCError.h"
#import "GNCPayload.h"
#import "GNCPayloadDelegate.h"
#import "GNCStrategy.h"
@@ -0,0 +1,8 @@
import NearbyCoreAdapter
import XCTest
class BuildTests: XCTestCase {
func testBuild() {
// At least one test case is needed.
}
}
+113 -4
View File
@@ -11,28 +11,101 @@
# 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.
# TODO(b/240046236): Refactor this into a new `cpp` package.
load("//third_party/lexan/build_defs:lexan.bzl", "lexan")
load(
"expand_version_template.bzl",
"expand_version_template",
)
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
package(default_visibility = ["//location/nearby:__subpackages__"])
licenses(["notice"])
cc_library(
name = "types",
hdrs = [
"dll_config.h",
],
visibility = [
"//connections:__subpackages__",
"//connections/clients/windows:__subpackages__",
"//internal/platform:__pkg__",
"//internal/platform/implementation:__subpackages__",
],
deps = ["@com_google_absl//absl/strings"],
)
bzl_library(
name = "expand_version_template_bzl",
srcs = ["expand_version_template.bzl"],
parse_tests = False,
visibility = ["//visibility:private"],
)
# Default version if none is provided.
vardef("VERSION", "1.0.0.0")
# When built with rapid, a version value will be passed down from the build config via blaze
# When built manually, invoke blaze with --define=VERSION=1.2.3.4
# If VERSION is not passed from blaze, the default value defined above will be used.
expand_version_template(
name = "version_expanded",
out = "version.rc",
template = "version.rc.tpl",
version = varref("VERSION"),
)
lexan.resource_files(
name = "resources",
rc_files = [
":version_expanded",
],
)
# Build with --config=lexan
lexan.cc_windows_dll(
name = "core_adapter",
name = "nearby_connections",
srcs = [
"advertising_options_w.cc",
"connection_options_w.cc",
"core_adapter.cc",
"discovery_options_w.cc",
"file_w.cc",
"listeners_w.cc",
"payload_w.cc",
"strategy_w.cc",
],
hdrs = [
"advertising_options_w.h",
"connection_options_w.h",
"core_adapter.h",
"discovery_options_w.h",
"dll_config.h",
"file_w.h",
"listeners_w.h",
"medium_selector_w.h",
"options_base_w.h",
"out_of_band_connection_metadata_w.h",
"params_w.h",
"payload_w.h",
"strategy_w.h",
],
copts = ["-DCORE_ADAPTER_BUILD_DLL -DCOMPILING_CORE"],
defines = ["CORE_ADAPTER_DLL"],
hdrs_deps = ["//connections:core"],
tags = ["windows-dll"],
deps = [
"//third_party/dart_lang/v2:dart_api_dl",
":resources",
"//connections:core",
"//connections:core_types",
"//connections/clients/windows:types",
"//internal/platform:base",
"//internal/platform/implementation/windows",
"//third_party/dart_lang/v2:dart_api_dl",
"//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory",
"@com_google_absl//absl/strings",
],
@@ -41,24 +114,60 @@ lexan.cc_windows_dll(
# Build with --config=lexan
# TODO(b/203019344) Move this configuration under dart folder and create a BUILD there.
lexan.cc_windows_dll(
name = "core_adapter_dart",
name = "nearby_connections_dart",
srcs = [
"advertising_options_w.cc",
"connection_options_w.cc",
"core_adapter.cc",
"dart/core_adapter_dart.cc",
"discovery_options_w.cc",
"file_w.cc",
"listeners_w.cc",
"payload_w.cc",
"strategy_w.cc",
],
hdrs = [
"advertising_options_w.h",
"connection_options_w.h",
"core_adapter.h",
"dart/core_adapter_dart.h",
"discovery_options_w.h",
"dll_config.h",
"file_w.h",
"listeners_w.h",
"medium_selector_w.h",
"options_base_w.h",
"out_of_band_connection_metadata_w.h",
"params_w.h",
"payload_w.h",
"strategy_w.h",
],
copts = ["-DCORE_ADAPTER_DART_BUILD_DLL -DCORE_ADAPTER_DLL -DCOMPILING_CORE"],
defines = ["CORE_ADAPTER_DART_DLL"],
tags = ["windows-dll"],
deps = [
"//third_party/dart_lang/v2:dart_api_dl",
":resources",
"//connections:core",
"//connections:core_types",
"//internal/platform:base",
"//internal/platform/implementation/windows",
"//third_party/dart_lang/v2:dart_api_dl",
"//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory",
"@com_google_absl//absl/strings",
],
)
cc_test(
name = "connections_test",
size = "small",
srcs = [
"bluetooth_classic_server_socket_test.cc",
],
deps = [
"//connections:core",
"//internal/platform:logging",
"//internal/platform/implementation/windows",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_googletest//:gtest_main",
],
)
@@ -0,0 +1,48 @@
// Copyright 2022 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 "connections/clients/windows/advertising_options_w.h"
#include <string>
namespace location::nearby::windows {
// Returns a copy and normalizes allowed mediums:
// (1) If is_out_of_band_connection is true, verifies that there is only one
// medium allowed, defaulting to only Bluetooth if unspecified.
// (2) If no mediums are allowed, allow all mediums.
AdvertisingOptionsW AdvertisingOptionsW::CompatibleOptions() const {
AdvertisingOptionsW result = *this;
// Out-of-band connections initiate connections via an injected endpoint
// rather than through the normal discovery flow. These types of connections
// can only be injected via a single medium.
if (is_out_of_band_connection) {
int num_enabled = result.allowed.Count(true);
// Default to allow only Bluetooth if no single medium is specified.
if (num_enabled != 1) {
result.allowed.SetAll(false);
result.allowed.bluetooth = true;
}
return result;
}
// Normal connections (i.e., not out-of-band) connections can specify
// multiple mediums. If none are specified, default to allowing all mediums.
if (!allowed.Any(true)) result.allowed.SetAll(true);
return result;
}
} // namespace location::nearby::windows
@@ -0,0 +1,49 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_ADVERTISING_OPTIONS_W_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_ADVERTISING_OPTIONS_W_H_
#include "connections/clients/windows/options_base_w.h"
namespace location::nearby::windows {
extern "C" {
// Advertising Options: used for Advertising.
// All fields are mutable, to make the type copy-assignable.
struct DLL_API AdvertisingOptionsW : public OptionsBaseW {
bool auto_upgrade_bandwidth = true;
bool enforce_topology_constraints;
bool low_power;
// Whether this is intended to be used in conjunction with InjectEndpoint().
bool is_out_of_band_connection = false;
const char* fast_advertisement_service_uuid;
// The information about this device (eg. name, device type),
// to appear on the remote device.
// Defined by client/application.
const char* device_info;
// Returns a copy and normalizes allowed mediums:
// (1) If is_out_of_band_connection is true, verifies that there is only one
// medium allowed, defaulting to only Bluetooth if unspecified.
// (2) If no mediums are allowed, allow all mediums.
AdvertisingOptionsW CompatibleOptions() const;
};
} // extern "C"
} // namespace location::nearby::windows
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_ADVERTISING_OPTIONS_W_H_
@@ -0,0 +1,612 @@
// Copyright 2022 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 <windows.h>
#include <cstdint>
#include <string>
#include "gtest/gtest.h"
#include "absl/synchronization/notification.h"
#include "connections/advertising_options.h"
#include "connections/core.h"
#include "connections/implementation/service_controller_router.h"
#include "connections/listeners.h"
#include "connections/status.h"
#include "connections/strategy.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/count_down_latch.h"
namespace location::nearby::windows {
using ::location::nearby::ByteArray;
using ::location::nearby::connections::AdvertisingOptions;
using ::location::nearby::connections::ConnectionListener;
using ::location::nearby::connections::ConnectionRequestInfo;
using ::location::nearby::connections::Core;
using ::location::nearby::connections::ServiceControllerRouter;
using ::location::nearby::connections::Status;
using ::location::nearby::connections::Strategy;
constexpr absl::string_view SERVICE_ID =
"com.google.location.nearby.apps.helloconnections";
constexpr int TimeoutSeconds = 3;
constexpr int LoopCount = 10;
constexpr absl::string_view device_name = "12345678901";
AdvertisingOptions AdvertiseOptions{
{
// Strategy
{
Strategy::kP2pPointToPoint,
},
// Allowed:
{
true, // bluetooth
true, // ble
true, // webrtc
true, // wifi_lan
true, // wifi_hotspot
},
},
true, // auto_upgrade_bandwidth
true, // enforce_topology_constraints
false, // low_power
false, // enable_bluetooth_listening
false, // enable_webrtc_listening
false, // is_out_of_band_connection
"", // fast_advertisement_service_uuid
};
class PerformanceTimer {
public:
static void start() {
QueryPerformanceFrequency(&frequency_);
QueryPerformanceCounter(&starting_time_);
}
static void stop() {
QueryPerformanceCounter(&ending_time_);
elapsed_microseconds_.QuadPart =
ending_time_.QuadPart - starting_time_.QuadPart;
elapsed_milliseconds_ = elapsed_microseconds_.QuadPart / 100;
}
static uint64_t ElapsedMilliseconds() { return elapsed_milliseconds_; }
private:
static uint64_t elapsed_milliseconds_;
static LARGE_INTEGER starting_time_;
static LARGE_INTEGER ending_time_;
static LARGE_INTEGER elapsed_microseconds_;
static LARGE_INTEGER frequency_;
};
uint64_t PerformanceTimer::elapsed_milliseconds_;
LARGE_INTEGER PerformanceTimer::starting_time_;
LARGE_INTEGER PerformanceTimer::ending_time_;
LARGE_INTEGER PerformanceTimer::elapsed_microseconds_;
LARGE_INTEGER PerformanceTimer::frequency_;
TEST(BluetoothClassicServerSocketTest,
DISABLED_SingleRunWithTimeoutReproStuck) {
ServiceControllerRouter router;
Core core(&router);
ConnectionListener listener;
ConnectionRequestInfo request_info;
request_info.endpoint_info = ByteArray(std::string(device_name));
request_info.listener = listener;
Status request_result;
absl::Notification notification;
PerformanceTimer::start();
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
{.result_cb = [&](Status status) {
request_result = status;
notification.Notify();
}});
if (notification.WaitForNotificationWithTimeout(
absl::Seconds(TimeoutSeconds))) {
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Started advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Started advertising elapsed time: "
<< std::to_string(ElapsedMilliseconds);
#endif
std::cout << "StartAdvertising started once:" << request_result.ToString()
<< std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising started once:"
<< request_result.ToString();
} else {
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Timeout on starting advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
EXPECT_TRUE(false) << "Timeout on starting advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
std::cout << "StartAdvertising failed to start once:"
<< request_result.ToString() << std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising failed to start once:"
<< request_result.ToString();
}
absl::Notification notification2;
PerformanceTimer::start();
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
{.result_cb = [&](Status status) {
request_result = status;
notification2.Notify();
}});
if (notification2.WaitForNotificationWithTimeout(
absl::Seconds(TimeoutSeconds))) {
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Started advertising second time elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Started advertising elapsed time: "
<< std::to_string(ElapsedMilliseconds);
#endif
std::cout << "StartAdvertising started twice:" << request_result.ToString()
<< std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising started twice:"
<< request_result.ToString();
} else {
PerformanceTimer::stop();
NEARBY_LOGS(INFO)
<< "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Timeout on starting advertising the second time elapsed time: "
<< std::to_string(PerformanceTimer::ElapsedMilliseconds());
EXPECT_TRUE(false) << "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Timeout for started advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
std::cout << "StartAdvertising failed to start twice:"
<< request_result.ToString() << std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising failed to start twice:"
<< request_result.ToString();
}
absl::Notification notification3;
PerformanceTimer::start();
core.StopAdvertising({.result_cb = [&](Status status) {
request_result = status;
notification3.Notify();
}});
if (notification3.WaitForNotificationWithTimeout(
absl::Seconds(TimeoutSeconds))) {
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Stopped advertising first time elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Started advertising elapsed time: "
<< std::to_string(elapsed_microseconds);
#endif
std::cout << "StopAdvertising called once:" << request_result.ToString()
<< std::endl;
NEARBY_LOGS(INFO) << "StopAdvertising called once:"
<< request_result.ToString();
} else {
PerformanceTimer::stop();
NEARBY_LOGS(INFO)
<< "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Timeout on stopping advertising the first time elapsed time: "
<< std::to_string(PerformanceTimer::ElapsedMilliseconds());
EXPECT_TRUE(false) << "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Timeout on stop advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
std::cout << "StopAdvertising failed to stop once:"
<< request_result.ToString() << std::endl;
NEARBY_LOGS(INFO) << "StopAdvertising failed to stop once:"
<< request_result.ToString();
}
std::cout << "Test completed." << std::endl;
NEARBY_LOGS(INFO) << "Test completed.";
}
TEST(BluetoothClassicServerSocketTest, DISABLED_MultiRunWithTimeoutReproStuck) {
ServiceControllerRouter router;
Core core(&router);
ConnectionListener listener;
ConnectionRequestInfo request_info;
request_info.endpoint_info = ByteArray(std::string(device_name));
request_info.listener = listener;
for (int loop_count = 0; loop_count < LoopCount; ++loop_count) {
Status request_result;
absl::Notification notification;
PerformanceTimer::start();
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
{.result_cb = [&](Status status) {
request_result = status;
notification.Notify();
}});
if (notification.WaitForNotificationWithTimeout(
absl::Seconds(TimeoutSeconds))) {
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Started advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Started advertising elapsed time : "
<< std::to_string(ElapsedMilliseconds);
#endif
std::cout << "StartAdvertising started once:" << request_result.ToString()
<< std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising started once:"
<< request_result.ToString();
} else {
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Timeout on starting advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
EXPECT_TRUE(false) << "Timeout on starting advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
std::cout << "StartAdvertising failed to start once:"
<< request_result.ToString() << std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising failed to start once:"
<< request_result.ToString();
}
absl::Notification notification2;
PerformanceTimer::start();
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
{.result_cb = [&](Status status) {
request_result = status;
notification2.Notify();
}});
if (notification2.WaitForNotificationWithTimeout(
absl::Seconds(TimeoutSeconds))) {
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Started advertising second time elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
// EXPECT_TRUE(false)
// << "Started advertising elapsed time: "
// << std::to_string(ElapsedMilliseconds);
std::cout << "StartAdvertising started twice:"
<< request_result.ToString() << std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising started twice:"
<< request_result.ToString();
} else {
PerformanceTimer::stop();
NEARBY_LOGS(INFO)
<< "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Timeout on starting advertising the second time elapsed time: "
<< std::to_string(PerformanceTimer::ElapsedMilliseconds());
EXPECT_TRUE(false)
<< "Timeout on starting advertising the second time elapsed time: "
<< std::to_string(PerformanceTimer::ElapsedMilliseconds());
std::cout << "StartAdvertising failed to start twice:"
<< request_result.ToString() << std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising failed to start twice:"
<< request_result.ToString();
}
absl::Notification notification3;
PerformanceTimer::start();
core.StopAdvertising({.result_cb = [&](Status status) {
request_result = status;
notification3.Notify();
}});
if (notification3.WaitForNotificationWithTimeout(
absl::Seconds(TimeoutSeconds))) {
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Stopped advertising first time elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Started advertising elapsed time: "
<< std::to_string(ElapsedMilliseconds);
#endif
std::cout << "StopAdvertising called once:" << request_result.ToString()
<< std::endl;
NEARBY_LOGS(INFO) << "StopAdvertising called once:"
<< request_result.ToString();
} else {
PerformanceTimer::stop();
NEARBY_LOGS(INFO)
<< "SingleRunWithTimeoutReproStuck Line: " << __LINE__
<< " Timeout on stopping advertising the first time elapsed time: "
<< std::to_string(PerformanceTimer::ElapsedMilliseconds());
EXPECT_TRUE(false) << "Timeout on started advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
std::cout << "StopAdvertising failed to stop once:"
<< request_result.ToString() << std::endl;
NEARBY_LOGS(INFO) << "StopAdvertising failed to stop once:"
<< request_result.ToString();
}
}
std::cout << "Test completed." << std::endl;
NEARBY_LOGS(INFO) << "Test completed.";
}
TEST(BluetoothClassicServerSocketTest, DISABLED_SingleRunNoTimeoutReproStuck) {
ServiceControllerRouter router;
Core core(&router);
ConnectionListener listener;
ConnectionRequestInfo request_info;
request_info.endpoint_info = ByteArray(std::string(device_name));
request_info.listener = listener;
Status request_result;
absl::Notification notification;
PerformanceTimer::start();
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
{.result_cb = [&](Status status) {
request_result = status;
notification.Notify();
}});
notification.WaitForNotification();
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunNoTimeoutReproStuck Line: " << __LINE__
<< " Started advertising first time elapsed time: "
<< std::to_string(PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Started advertising first time elapsed time: "
<< std::to_string(ElapsedMilliseconds);
#endif
std::cout << "StartAdvertising started once:" << request_result.ToString()
<< std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising started once:"
<< request_result.ToString();
absl::Notification notification2;
PerformanceTimer::start();
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
{.result_cb = [&](Status status) {
request_result = status;
notification2.Notify();
}});
notification2.WaitForNotification();
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunNoTimeoutReproStuck Line: " << __LINE__
<< " Started advertising first time elapsed time: "
<< std::to_string(PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Started advertising first time elapsed time: "
<< std::to_string(ElapsedMilliseconds);
#endif
std::cout << "StartAdvertising started twice:" << request_result.ToString()
<< std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising started twice:"
<< request_result.ToString();
absl::Notification notification3;
PerformanceTimer::start();
core.StopAdvertising({.result_cb = [&](Status status) {
request_result = status;
notification3.Notify();
}});
notification3.WaitForNotification();
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "SingleRunNoTimeoutReproStuck " << __LINE__
<< "Stopped advertising elapsed time: "
<< std::to_string(PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Stopped advertising elapsed time: "
<< std::to_string(ElapsedMilliseconds);
#endif
std::cout << "StopAdvertising called once:" << request_result.ToString()
<< std::endl;
NEARBY_LOGS(INFO) << "StopAdvertising called once:"
<< request_result.ToString();
std::cout << "Test completed." << std::endl;
NEARBY_LOGS(INFO) << "Test completed.";
}
TEST(BluetoothClassicServerSocketTest, DISABLED_MultiRunNoTimeoutReproStuck) {
ServiceControllerRouter router;
Core core(&router);
ConnectionListener listener;
ConnectionRequestInfo request_info;
request_info.endpoint_info = ByteArray(std::string(device_name));
request_info.listener = listener;
for (int loop_count = 0; loop_count < LoopCount; ++loop_count) {
Status request_result;
absl::Notification notification;
PerformanceTimer::start();
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
{.result_cb = [&](Status status) {
request_result = status;
notification.Notify();
}});
notification.WaitForNotification();
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "MultiRunNoTimeoutReproStuck " << __LINE__
<< "Started advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Started advertising elapsed time: "
<< std::to_string(ElapsedMilliseconds);
#endif
std::cout << "MultiRunNoTimeoutReproStuck " << __LINE__
<< " : StartAdvertising started once: "
<< request_result.ToString() << std::endl;
NEARBY_LOGS(INFO) << "StartAdvertising started once:"
<< request_result.ToString();
absl::Notification notification2;
PerformanceTimer::start();
core.StartAdvertising(SERVICE_ID, AdvertiseOptions, request_info,
{.result_cb = [&](Status status) {
request_result = status;
notification2.Notify();
}});
notification2.WaitForNotification();
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "MultiRunNoTimeoutReproStuck " << __LINE__
<< "Started advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Started advertising elapsed time: "
<< std::to_string(ElapsedMilliseconds);
#endif
std::cout << "MultiRunNoTimeoutReproStuck " << __LINE__
<< "StartAdvertising started twice:" << request_result.ToString()
<< std::endl;
NEARBY_LOGS(INFO) << "MultiRunNoTimeoutReproStuck " << __LINE__
<< "StartAdvertising started twice:"
<< request_result.ToString();
absl::Notification notification3;
PerformanceTimer::start();
core.StopAdvertising({.result_cb = [&](Status status) {
request_result = status;
notification3.Notify();
}});
notification3.WaitForNotification();
PerformanceTimer::stop();
NEARBY_LOGS(INFO) << "MultiRunNoTimeoutReproStuck " << __LINE__
<< "Stopped advertising elapsed time: "
<< std::to_string(
PerformanceTimer::ElapsedMilliseconds());
#ifdef TEST_OUTPUT
EXPECT_TRUE(false) << "Stop advertising elapsed time: "
<< std::to_string(ElapsedMilliseconds);
#endif
std::cout << "StopAdvertising called once:" << request_result.ToString()
<< std::endl;
NEARBY_LOGS(INFO) << "MultiRunNoTimeoutReproStuck " << __LINE__
<< "StopAdvertising called once:"
<< request_result.ToString();
}
std::cout << "Test completed." << std::endl;
NEARBY_LOGS(INFO) << "Test completed.";
}
} // namespace location::nearby::windows
@@ -0,0 +1,35 @@
// Copyright 2021-2022 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 "connections/clients/windows/connection_options_w.h"
#include <string>
namespace location::nearby::windows {
void ConnectionOptionsW::GetMediums(const MediumW* mediums,
size_t mediums_size) const {
// Create a collection of enabled mediums
auto allowedMediums = allowed.GetMediums(true);
auto iter = allowedMediums.begin();
int index = 0;
// There is a fixed buffer of 5 for these, fill it up and leave.
while (iter != allowedMediums.end() && index < MAX_MEDIUMS) {
*mediums_[index++] = iter[index];
}
mediums_size = allowed.GetMediums(true).size();
return;
}
} // namespace location::nearby::windows
@@ -0,0 +1,54 @@
// Copyright 2021-2022 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_CONNECTIONS_CLIENTS_WINDOWS_CONNECTION_OPTIONS_W_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_CONNECTION_OPTIONS_W_H_
#include <string>
#include "connections/clients/windows/medium_selector_w.h"
#include "connections/clients/windows/options_base_w.h"
namespace location::nearby::windows {
extern "C" {
#define MAX_MEDIUMS 5
// Feature On/Off switch for mediums.
using BooleanMediumSelector = MediumSelectorW<bool>;
// Connection Options: used for both Advertising and Discovery.
// All fields are mutable, to make the type copy-assignable.
struct DLL_API ConnectionOptionsW : public OptionsBaseW {
bool auto_upgrade_bandwidth = true;
bool enforce_topology_constraints;
bool low_power;
// Whether this is intended to be used in conjunction with InjectEndpoint().
bool is_out_of_band_connection = false;
const char* remote_bluetooth_mac_address;
const char* fast_advertisement_service_uuid;
int keep_alive_interval_millis = 0;
int keep_alive_timeout_millis = 0;
void GetMediums(const MediumW*, size_t) const;
private:
MediumW* mediums_[MAX_MEDIUMS];
size_t mediums_size;
};
} // extern "C"
} // namespace location::nearby::windows
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_CONNECTION_OPTIONS_W_H_
+222 -79
View File
@@ -1,4 +1,4 @@
// Copyright 2021 Google LLC
// Copyright 2021-2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -11,143 +11,286 @@
// 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 "connections/clients/windows/core_adapter.h"
#include "absl/strings/str_format.h"
#include "connections/core.h"
#include "internal/platform/bluetooth_utils.h"
#include "internal/platform/logging.h"
namespace location {
namespace nearby {
namespace connections {
namespace windows {
namespace location::nearby::windows {
Core *InitCore(ServiceControllerRouter *router) { return new Core(router); }
Core *InitCore(connections::ServiceControllerRouter *router) {
#if defined(LOG_SEVERITY_VERBOSE)
NEARBY_LOG_SET_SEVERITY(VERBOSE);
#endif // LOG_SEVERITY_VERBOSE;
return new nearby::connections::Core(router);
}
void CloseCore(Core *pCore) {
if (pCore) {
pCore->StopAllEndpoints(
{.result_cb = std::function<void(Status)>{[](Status) {}}});
delete pCore;
if (pCore == nullptr) {
return;
}
pCore->StopAllEndpoints(
{.result_cb = std::function<void(Status)>{[](Status) {}}});
delete pCore;
}
void StartAdvertising(Core *pCore, const char *service_id,
AdvertisingOptions advertising_options,
ConnectionRequestInfo info, ResultCallback callback) {
if (pCore) {
pCore->StartAdvertising(service_id, advertising_options, info, callback);
AdvertisingOptionsW advertising_options_w,
ConnectionRequestInfoW info, ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
connections::ConnectionRequestInfo crInfo;
crInfo.endpoint_info = ByteArray(info.endpoint_info);
crInfo.listener = std::move(*(info.listener.GetImpl()));
connections::AdvertisingOptions advertising_options;
advertising_options.allowed.bluetooth =
advertising_options_w.allowed.bluetooth;
advertising_options.allowed.ble = advertising_options_w.allowed.ble;
advertising_options.allowed.wifi_lan = advertising_options_w.allowed.wifi_lan;
advertising_options.allowed.web_rtc = advertising_options_w.allowed.web_rtc;
advertising_options.allowed.wifi_hotspot =
advertising_options_w.allowed.wifi_hotspot;
advertising_options.enable_bluetooth_listening = false;
advertising_options.enable_webrtc_listening = false;
advertising_options.auto_upgrade_bandwidth =
advertising_options_w.auto_upgrade_bandwidth;
advertising_options.enforce_topology_constraints =
advertising_options_w.enforce_topology_constraints;
if (advertising_options_w.fast_advertisement_service_uuid != nullptr) {
advertising_options.fast_advertisement_service_uuid =
std::string(advertising_options_w.fast_advertisement_service_uuid);
}
advertising_options.is_out_of_band_connection =
advertising_options_w.is_out_of_band_connection;
advertising_options.low_power = advertising_options_w.low_power;
if (advertising_options_w.strategy == StrategyW::kNone)
advertising_options.strategy = connections::Strategy::kNone;
if (advertising_options_w.strategy == StrategyW::kP2pCluster)
advertising_options.strategy = connections::Strategy::kP2pCluster;
if (advertising_options_w.strategy == StrategyW::kP2pPointToPoint)
advertising_options.strategy = connections::Strategy::kP2pPointToPoint;
if (advertising_options_w.strategy == StrategyW::kP2pStar)
advertising_options.strategy = connections::Strategy::kP2pStar;
pCore->StartAdvertising(service_id, advertising_options, crInfo,
*callback.GetImpl());
}
void StopAdvertising(Core *pCore, ResultCallback callback) {
if (pCore) {
pCore->StopAdvertising(callback);
void StopAdvertising(connections::Core *pCore, ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
pCore->StopAdvertising(*callback.GetImpl());
}
void StartDiscovery(Core *pCore, const char *service_id,
DiscoveryOptions discovery_options,
DiscoveryListener listener, ResultCallback callback) {
if (pCore) {
pCore->StartDiscovery(service_id, discovery_options, listener, callback);
void StartDiscovery(connections::Core *pCore, const char *service_id,
DiscoveryOptionsW discovery_options_w,
DiscoveryListenerW listener, ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
connections::DiscoveryListener discoveryListener =
std::move(*listener.GetImpl());
connections::DiscoveryOptions discovery_options;
if (discovery_options_w.strategy == StrategyW::kNone)
discovery_options.strategy = connections::Strategy::kNone;
if (discovery_options_w.strategy == StrategyW::kP2pCluster)
discovery_options.strategy = connections::Strategy::kP2pCluster;
if (discovery_options_w.strategy == StrategyW::kP2pPointToPoint)
discovery_options.strategy = connections::Strategy::kP2pPointToPoint;
if (discovery_options_w.strategy == StrategyW::kP2pStar)
discovery_options.strategy = connections::Strategy::kP2pStar;
discovery_options.auto_upgrade_bandwidth =
discovery_options_w.auto_upgrade_bandwidth;
discovery_options.enforce_topology_constraints =
discovery_options_w.enforce_topology_constraints;
discovery_options.keep_alive_interval_millis =
discovery_options_w.keep_alive_interval_millis;
discovery_options.keep_alive_timeout_millis =
discovery_options_w.keep_alive_timeout_millis;
discovery_options.is_out_of_band_connection =
discovery_options_w.is_out_of_band_connection;
if (discovery_options_w.fast_advertisement_service_uuid) {
discovery_options.fast_advertisement_service_uuid =
std::string(discovery_options_w.fast_advertisement_service_uuid);
}
discovery_options.allowed.bluetooth = discovery_options_w.allowed.bluetooth;
discovery_options.allowed.ble = discovery_options_w.allowed.ble;
discovery_options.allowed.wifi_lan = discovery_options_w.allowed.wifi_lan;
discovery_options.allowed.wifi_hotspot =
discovery_options_w.allowed.wifi_hotspot;
discovery_options.allowed.web_rtc = discovery_options_w.allowed.web_rtc;
pCore->StartDiscovery(service_id, discovery_options, discoveryListener,
std::move(*callback.GetImpl()));
}
void StopDiscovery(Core *pCore, ResultCallback callback) {
if (pCore) {
pCore->StopDiscovery(callback);
void StopDiscovery(connections::Core *pCore, ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
pCore->StopDiscovery(*callback.GetImpl());
}
void InjectEndpoint(Core *pCore, char *service_id,
OutOfBandConnectionMetadata metadata,
ResultCallback callback) {
if (pCore) {
pCore->InjectEndpoint(service_id, metadata, callback);
void InjectEndpoint(connections::Core *pCore, char *service_id,
OutOfBandConnectionMetadataW metadata,
ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
connections::OutOfBandConnectionMetadata outOfBandConnectionMetadata;
outOfBandConnectionMetadata.endpoint_id = metadata.endpoint_id;
outOfBandConnectionMetadata.endpoint_info = {metadata.endpoint_info,
metadata.endpoint_info_size};
outOfBandConnectionMetadata.medium = metadata.medium;
outOfBandConnectionMetadata.remote_bluetooth_mac_address = {
metadata.remote_bluetooth_mac_address,
metadata.remote_bluetooth_mac_address_size};
pCore->InjectEndpoint(service_id, outOfBandConnectionMetadata,
*callback.GetImpl());
}
void RequestConnection(Core *pCore, const char *endpoint_id,
ConnectionRequestInfo info,
ConnectionOptions connection_options,
ResultCallback callback) {
if (pCore) {
pCore->RequestConnection(endpoint_id, info, connection_options, callback);
void RequestConnection(connections::Core *pCore, const char *endpoint_id,
ConnectionRequestInfoW info,
ConnectionOptionsW connection_options_w,
ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
connections::ConnectionRequestInfo connectionRequestInfo =
connections::ConnectionRequestInfo();
connectionRequestInfo.endpoint_info = ByteArray(info.endpoint_info);
connectionRequestInfo.listener = std::move(*info.listener.GetImpl());
connections::ConnectionOptions connection_options;
connection_options.allowed.ble = connection_options_w.allowed.ble;
connection_options.allowed.bluetooth = connection_options_w.allowed.bluetooth;
connection_options.allowed.web_rtc = connection_options_w.allowed.web_rtc;
connection_options.allowed.wifi_lan = connection_options_w.allowed.wifi_lan;
connection_options.auto_upgrade_bandwidth =
connection_options_w.auto_upgrade_bandwidth;
connection_options.enforce_topology_constraints =
connection_options_w.enforce_topology_constraints;
if (connection_options_w.fast_advertisement_service_uuid) {
connection_options.fast_advertisement_service_uuid =
std::string(connection_options_w.fast_advertisement_service_uuid);
}
connection_options.is_out_of_band_connection =
connection_options_w.is_out_of_band_connection;
connection_options.keep_alive_interval_millis =
connection_options_w.keep_alive_interval_millis;
connection_options.keep_alive_timeout_millis =
connection_options_w.keep_alive_timeout_millis;
connection_options.low_power = connection_options_w.low_power;
if (connection_options_w.remote_bluetooth_mac_address) {
connection_options.remote_bluetooth_mac_address =
BluetoothUtils::FromString(
connection_options_w.remote_bluetooth_mac_address);
}
if (connection_options_w.strategy == StrategyW::kNone)
connection_options.strategy = connections::Strategy::kNone;
if (connection_options_w.strategy == StrategyW::kP2pCluster)
connection_options.strategy = connections::Strategy::kP2pCluster;
if (connection_options_w.strategy == StrategyW::kP2pPointToPoint)
connection_options.strategy = connections::Strategy::kP2pPointToPoint;
if (connection_options_w.strategy == StrategyW::kP2pStar)
connection_options.strategy = connections::Strategy::kP2pStar;
pCore->RequestConnection(endpoint_id, connectionRequestInfo,
connection_options, *callback.GetImpl());
}
void AcceptConnection(Core *pCore, const char *endpoint_id,
PayloadListener listener, ResultCallback callback) {
if (pCore) {
pCore->AcceptConnection(endpoint_id, listener, callback);
void AcceptConnection(connections::Core *pCore, const char *endpoint_id,
PayloadListenerW listener, ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
connections::PayloadListener payload_listener =
std::move(*listener.GetImpl());
pCore->AcceptConnection(endpoint_id, payload_listener, *callback.GetImpl());
}
void RejectConnection(Core *pCore, const char *endpoint_id,
ResultCallback callback) {
if (pCore) {
pCore->RejectConnection(endpoint_id, callback);
void RejectConnection(connections::Core *pCore, const char *endpoint_id,
ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
pCore->RejectConnection(endpoint_id, *callback.GetImpl());
}
void SendPayload(Core *pCore,
void SendPayload(connections::Core *pCore,
// todo(jfcarroll) this is being exported, needs to be
// refactored to return a plain old c type
absl::Span<const std::string> endpoint_ids, Payload payload,
ResultCallback callback) {
if (pCore) {
pCore->SendPayload(endpoint_ids, std::move(payload), callback);
const char **endpoint_ids, size_t endpoint_ids_size,
PayloadW payloadw, ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
std::string payloadData = std::string(*endpoint_ids);
absl::Span<const std::string> span{&payloadData, 1};
pCore->SendPayload(span, std::move(*payloadw.GetImpl()), *callback.GetImpl());
}
void CancelPayload(Core *pCore, std::int64_t payload_id,
ResultCallback callback) {
if (pCore) {
pCore->CancelPayload(payload_id, callback);
void CancelPayload(connections::Core *pCore, std::int64_t payload_id,
ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
pCore->CancelPayload(payload_id, *callback.GetImpl());
}
void DisconnectFromEndpoint(Core *pCore, char *endpoint_id,
ResultCallback callback) {
if (pCore) {
pCore->DisconnectFromEndpoint(endpoint_id, callback);
void DisconnectFromEndpoint(connections::Core *pCore, const char *endpoint_id,
ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
pCore->DisconnectFromEndpoint(endpoint_id, *callback.GetImpl());
}
void StopAllEndpoints(Core *pCore, ResultCallback callback) {
if (pCore) {
pCore->StopAllEndpoints(callback);
void StopAllEndpoints(connections::Core *pCore, ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
pCore->StopAllEndpoints(*callback.GetImpl());
}
void InitiateBandwidthUpgrade(Core *pCore, char *endpoint_id,
ResultCallback callback) {
if (pCore) {
pCore->InitiateBandwidthUpgrade(endpoint_id, callback);
void InitiateBandwidthUpgrade(connections::Core *pCore, char *endpoint_id,
ResultCallbackW callback) {
if (pCore == nullptr) {
return;
}
pCore->InitiateBandwidthUpgrade(endpoint_id, *callback.GetImpl());
}
const char *GetLocalEndpointId(Core *pCore) {
if (pCore) {
std::string endpoint_id = pCore->GetLocalEndpointId();
char *result = new char[endpoint_id.length() + 1];
absl::SNPrintF(result, endpoint_id.length() + 1, "%s", endpoint_id);
return result;
const char *GetLocalEndpointId(connections::Core *pCore) {
if (pCore == nullptr) {
return "Null-Core";
}
return "Null-Core";
std::string endpoint_id = pCore->GetLocalEndpointId();
char *result = new char[endpoint_id.length() + 1];
absl::SNPrintF(result, endpoint_id.length() + 1, "%s", endpoint_id);
return result;
}
ServiceControllerRouter *InitServiceControllerRouter() {
return new ServiceControllerRouter();
connections::ServiceControllerRouter *InitServiceControllerRouter() {
return new connections::ServiceControllerRouter();
}
void CloseServiceControllerRouter(ServiceControllerRouter *pRouter) {
if (pRouter) {
void CloseServiceControllerRouter(
connections::ServiceControllerRouter *pRouter) {
if (pRouter != nullptr) {
delete pRouter;
}
}
} // namespace windows
} // namespace connections
} // namespace nearby
} // namespace location
} // namespace location::nearby::windows
+61 -68
View File
@@ -1,4 +1,4 @@
// Copyright 2021 Google LLC
// Copyright 2021-2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -11,43 +11,50 @@
// 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 LOCATION_NEARBY_CONNECTIONS_WINDOWS_CORE_ADAPTER_H_
#define LOCATION_NEARBY_CONNECTIONS_WINDOWS_CORE_ADAPTER_H_
#ifndef THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_CORE_ADAPTER_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_CORE_ADAPTER_H_
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "connections/clients/windows/advertising_options_w.h"
#include "connections/clients/windows/connection_options_w.h"
#include "connections/clients/windows/discovery_options_w.h"
#include "connections/clients/windows/listeners_w.h"
#include "connections/clients/windows/out_of_band_connection_metadata_w.h"
#include "connections/clients/windows/params_w.h"
#include "connections/clients/windows/payload_w.h"
// todo(jfcarroll) This cannot remain. It exposes stuff the client doesn't need.
#include "connections/advertising_options.h"
#include "connections/connection_options.h"
#include "connections/discovery_options.h"
#include "connections/implementation/offline_service_controller.h"
#define DLL_EXPORT extern "C" __declspec(dllexport)
namespace location {
namespace nearby {
namespace connections {
namespace location::nearby::connections {
class Core;
class ServiceController;
class ServiceControllerRouter;
class OfflineServiceController;
} // namespace location::nearby::connections
namespace location::nearby::windows {
namespace windows {
extern "C" {
// Initizlizes a Core instance, providing the ServiceController factory from
using Core = connections::Core;
using ServiceControllerRouter = connections::ServiceControllerRouter;
// Initializes a Core instance, providing the ServiceController factory from
// app side. If no factory is provided, it will initialize a new
// factory creating OffilineServiceController.
// factory creating OfflineServiceController.
// Returns the instance handle to c# client.
DLL_EXPORT connections::Core *__stdcall InitCoreWithServiceControllerFactory(
std::function<connections::ServiceController *()> factory = []() {
return new connections::OfflineServiceController;
});
// TODO(jfcarroll): Is this method needed? The trouble is we can't
// new up a forward declared class (OfflineServiceController). If this
// is necessary, must find another way to implement it.
// DLL_API Core *__stdcall InitCoreWithServiceControllerFactory(
// std::function<ServiceController *()> factory = []() {
// return new OfflineServiceController;
// });
// Initializes a default Core instance.
// Returns the instance handle to c# client.
DLL_EXPORT Core *__stdcall InitCore(ServiceControllerRouter *router);
DLL_API Core* __stdcall InitCore(ServiceControllerRouter*);
// Closes the core with stopping all endpoints, then free the memory.
DLL_EXPORT void __stdcall CloseCore(Core *pCore);
DLL_API void __stdcall CloseCore(Core*);
// Starts advertising an endpoint for a local app.
//
@@ -67,9 +74,9 @@ DLL_EXPORT void __stdcall CloseCore(Core *pCore);
// Status::STATUS_ALREADY_ADVERTISING if the app is already advertising.
// Status::STATUS_OUT_OF_ORDER_API_CALL if the app is currently
// connected to remote endpoints; call StopAllEndpoints first.
DLL_EXPORT void __stdcall StartAdvertising(
Core *pCore, const char *service_id, AdvertisingOptions advertising_options,
connections::ConnectionRequestInfo info, ResultCallback callback);
DLL_API void __stdcall StartAdvertising(Core*, const char*, AdvertisingOptionsW,
ConnectionRequestInfoW,
ResultCallbackW);
// Stops advertising a local endpoint. Should be called after calling
// StartAdvertising, as soon as the application no longer needs to advertise
@@ -79,7 +86,7 @@ DLL_EXPORT void __stdcall StartAdvertising(
// result_cb - to access the status of the operation when available.
// Possible status codes include:
// Status::STATUS_OK if none of the above errors occurred.
DLL_EXPORT void __stdcall StopAdvertising(Core *pCore, ResultCallback callback);
DLL_API void __stdcall StopAdvertising(Core*, ResultCallbackW);
// Starts discovery for remote endpoints with the specified service ID.
//
@@ -94,10 +101,8 @@ DLL_EXPORT void __stdcall StopAdvertising(Core *pCore, ResultCallback callback);
// discovering the specified service.
// Status::STATUS_OUT_OF_ORDER_API_CALL if the app is currently
// connected to remote endpoints; call StopAllEndpoints first.
DLL_EXPORT void __stdcall StartDiscovery(Core *pCore, const char *service_id,
DiscoveryOptions discovery_options,
DiscoveryListener listener,
ResultCallback callback);
DLL_API void __stdcall StartDiscovery(Core*, const char*, DiscoveryOptionsW,
DiscoveryListenerW, ResultCallbackW);
// Stops discovery for remote endpoints, after a previous call to
// StartDiscovery, when the client no longer needs to discover endpoints or
@@ -107,8 +112,7 @@ DLL_EXPORT void __stdcall StartDiscovery(Core *pCore, const char *service_id,
// result_cb - to access the status of the operation when available.
// Possible status codes include:
// Status::STATUS_OK if none of the above errors occurred.
DLL_EXPORT void __stdcall StopDiscovery(connections::Core *pCore,
connections::ResultCallback callback);
DLL_API void __stdcall StopDiscovery(Core*, ResultCallbackW);
// Invokes the discovery callback from a previous call to StartDiscovery()
// with the given endpoint info. The previous call to StartDiscovery() must
@@ -125,9 +129,9 @@ DLL_EXPORT void __stdcall StopDiscovery(connections::Core *pCore,
// Status::kError if endpoint_id, endpoint_info, or
// remote_bluetooth_mac_address are malformed.
// Status::kOutOfOrderApiCall if the app is not discovering.
DLL_EXPORT void __stdcall InjectEndpoint(Core *pCore, char *service_id,
OutOfBandConnectionMetadata metadata,
ResultCallback callback);
DLL_API void __stdcall InjectEndpoint(Core*, char*,
OutOfBandConnectionMetadataW,
ResultCallbackW);
// Sends a request to connect to a remote endpoint.
//
@@ -148,9 +152,9 @@ DLL_EXPORT void __stdcall InjectEndpoint(Core *pCore, char *service_id,
// Status::STATUS_RADIO_ERROR if we failed to connect because of an
// issue with Bluetooth/WiFi.
// Status::STATUS_ERROR if we failed to connect for any other reason.
DLL_EXPORT void __stdcall RequestConnection(
Core *pCore, const char *endpoint_id, ConnectionRequestInfo info,
ConnectionOptions connection_options, ResultCallback callback);
DLL_API void __stdcall RequestConnection(Core*, const char*,
ConnectionRequestInfoW,
ConnectionOptionsW, ResultCallbackW);
// Accepts a connection to a remote endpoint. This method must be called
// before Payloads can be exchanged with the remote endpoint.
@@ -164,9 +168,8 @@ DLL_EXPORT void __stdcall RequestConnection(
// Status::STATUS_OK if the connection request was accepted.
// Status::STATUS_ALREADY_CONNECTED_TO_ENDPOINT if the app already.
// has a connection to the specified endpoint.
DLL_EXPORT void __stdcall AcceptConnection(Core *pCore, const char *endpoint_id,
PayloadListener listener,
ResultCallback callback);
DLL_API void __stdcall AcceptConnection(Core*, const char*, PayloadListenerW,
ResultCallbackW);
// Rejects a connection to a remote endpoint.
//
@@ -178,8 +181,7 @@ DLL_EXPORT void __stdcall AcceptConnection(Core *pCore, const char *endpoint_id,
// Status::STATUS_OK} if the connection request was rejected.
// Status::STATUS_ALREADY_CONNECTED_TO_ENDPOINT} if the app already
// has a connection to the specified endpoint.
DLL_EXPORT void __stdcall RejectConnection(Core *pCore, const char *endpoint_id,
ResultCallback callback);
DLL_API void __stdcall RejectConnection(Core*, const char*, ResultCallbackW);
// Sends a Payload to a remote endpoint. Payloads can only be sent to remote
// endpoints once a notice of connection acceptance has been delivered via
@@ -200,9 +202,8 @@ DLL_EXPORT void __stdcall RejectConnection(Core *pCore, const char *endpoint_id,
// still occur during transmission (and at different times for
// different endpoints), and will be delivered via
// PayloadCallback#onPayloadTransferUpdate.
DLL_EXPORT void __stdcall SendPayload(
Core *pCore, absl::Span<const std::string> endpoint_ids, Payload payload,
ResultCallback callback);
DLL_API void __stdcall SendPayload(Core*, const char**, size_t, PayloadW,
ResultCallbackW);
// Cancels a Payload currently in-flight to or from remote endpoint(s).
//
@@ -210,8 +211,7 @@ DLL_EXPORT void __stdcall SendPayload(
// result_cb - to access the status of the operation when available.
// Possible status codes include:
// Status::STATUS_OK if none of the above errors occurred.
DLL_EXPORT void __stdcall CancelPayload(Core *pCore, int64_t payload_id,
ResultCallback callback);
DLL_API void __stdcall CancelPayload(Core*, int64_t, ResultCallbackW);
// Disconnects from a remote endpoint. {@link Payload}s can no longer be sent
// to or received from the endpoint after this method is called.
@@ -220,20 +220,18 @@ DLL_EXPORT void __stdcall CancelPayload(Core *pCore, int64_t payload_id,
// result_cb - to access the status of the operation when available.
// Possible status codes include:
// Status::STATUS_OK - finished successfully.
DLL_EXPORT void __stdcall DisconnectFromEndpoint(Core *pCore, char *endpoint_id,
ResultCallback callback);
DLL_API void __stdcall DisconnectFromEndpoint(Core*, const char*,
ResultCallbackW);
// Disconnects from, and removes all traces of, all connected and/or
// discovered endpoints. This call is expected to be preceded by a call to
// StopAdvertising or StartDiscovery as needed. After calling
// StopAllEndpoints, no further operations with remote endpoints will be
// discovered endpoints. This call also stops advertising and discovery. After
// calling StopAllEndpoints, no further operations with remote endpoints will be
// possible until a new call to one of StartAdvertising() or StartDiscovery().
//
// result_cb - to access the status of the operation when available.
// Possible status codes include:
// Status::STATUS_OK - finished successfully.
DLL_EXPORT void __stdcall StopAllEndpoints(Core *pCore,
ResultCallback callback);
DLL_API void __stdcall StopAllEndpoints(Core*, ResultCallbackW);
// Sends a request to initiate connection bandwidth upgrade.
//
@@ -244,24 +242,19 @@ DLL_EXPORT void __stdcall StopAllEndpoints(Core *pCore,
// result_cb - to access the status of the operation when available.
// Possible status codes include:
// Status::STATUS_OK - finished successfully.
DLL_EXPORT void __stdcall InitiateBandwidthUpgrade(Core *pCore,
char *endpoint_id,
ResultCallback callback);
DLL_API void __stdcall InitiateBandwidthUpgrade(Core*, char*, ResultCallbackW);
// Gets the local endpoint generated by Nearby Connections.
DLL_EXPORT const char *__stdcall GetLocalEndpointId(Core *pCore);
DLL_API const char* __stdcall GetLocalEndpointId(Core*);
// Initializes a default ServiceControllerRouter instance.
// Returns the instance handle to c# client.
DLL_EXPORT ServiceControllerRouter *__stdcall InitServiceControllerRouter();
DLL_API ServiceControllerRouter* __stdcall InitServiceControllerRouter();
// Close a ServiceControllerRouter instance.
DLL_EXPORT void __stdcall CloseServiceControllerRouter(
ServiceControllerRouter *pRouter);
DLL_API void __stdcall CloseServiceControllerRouter(ServiceControllerRouter*);
} // namespace windows
} // namespace connections
} // namespace nearby
} // namespace location
} // extern "C"
} // namespace location::nearby::windows
#endif // LOCATION_NEARBY_CONNECTIONS_WINDOWS_CORE_ADAPTER_H_
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_CORE_ADAPTER_H_
File diff suppressed because it is too large Load Diff
@@ -19,66 +19,153 @@
#include "third_party/dart_lang/v2/runtime/include/dart_native_api.h"
#include "connections/clients/windows/core_adapter.h"
namespace location {
namespace nearby {
namespace connections {
namespace windows {
namespace location::nearby::windows {
enum StrategyDart {
enum class StrategyDart {
P2P_CLUSTER = 0,
P2P_STAR,
P2P_POINT_TO_POINT,
};
enum PayloadType {
// LINT.IfChange
UNKNOWN = 0,
BYTE,
STREAM,
FILE,
// LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/flutter/lib/payload.dart)
};
struct ConnectionOptionsDart {
struct Mediums {
// LINT.IfChange
int64_t bluetooth;
int64_t ble;
int64_t wifi_lan;
int64_t wifi_hotspot;
int64_t web_rtc;
// LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/flutter/lib/mediums.dart)
};
extern "C" {
struct AdvertisingOptionsDart {
// LINT.IfChange
StrategyDart strategy;
int64_t auto_upgrade_bandwidth;
int64_t enforce_topology_constraints;
int64_t enable_bluetooth;
int64_t enable_ble;
int64_t advertise_nearby_notifications_beacon;
int64_t use_low_power_mode;
int64_t discover_fast_advertisements;
int64_t enable_wifi_lan;
int64_t enable_nfc;
int64_t enable_wifi_aware;
int64_t enable_web_rtc;
int64_t low_power;
// Whether this is intended to be used in conjunction with InjectEndpoint().
int64_t is_out_of_band_connection = false;
const char *fast_advertisement_service_uuid;
// The information about this device (eg. name, device type),
// to appear on the remote device.
// Defined by client/application.
const char *device_info;
Mediums mediums;
// LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/flutter/lib/advertising_options.dart)
};
struct ConnectionRequestInfoDart {
char *endpoint_info;
int64_t initiated_cb;
int64_t accepted_cb;
int64_t rejected_cb;
int64_t disconnected_cb;
int64_t bandwidth_changed_cb;
struct ConnectionOptionsDart {
// LINT.IfChange
StrategyDart strategy;
// Whether this is intended to be used in conjunction with InjectEndpoint().
int64_t auto_upgrade_bandwidth;
int64_t enforce_topology_constraints;
int64_t low_power;
// Whether this is intended to be used in conjunction with InjectEndpoint().
int64_t is_out_of_band_connection = false;
char *remote_bluetooth_mac_address;
char *fast_advertisement_service_uuid;
int64_t keep_alive_interval_millis;
int64_t keep_alive_timeout_millis;
Mediums mediums;
// LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/flutter/lib/connection_options.dart)
};
struct DiscoveryOptionsDart {
// LINT.IfChange
StrategyDart strategy;
int64_t auto_upgrade_bandwidth;
int64_t enforce_topology_constraints;
int64_t keep_alive_interval_millis = 0;
int64_t keep_alive_timeout_millis = 0;
// Whether this is intended to be used in conjunction with InjectEndpoint().
int64_t is_out_of_band_connection = false;
const char *fast_advertisement_service_uuid;
const char *remote_bluetooth_mac_address;
Mediums mediums;
// LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/flutter/lib/discovery_options.dart)
};
struct DiscoveryListenerDart {
int64_t found_cb;
int64_t lost_cb;
int64_t distance_changed_cb;
// LINT.IfChange
int64_t found_dart_port;
int64_t lost_dart_port;
int64_t distance_changed_dart_port;
// LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/flutter/lib/discovery_listener.dart)
};
struct PayloadListenerDart {
int64_t payload_cb;
int64_t payload_progress_cb;
// LINT.IfChange
int64_t payload_dart_port;
int64_t payload_progress_dart_port;
// LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/flutter/lib/payload_listener.dart)
};
struct ConnectionListenerDart {
// LINT.IfChange
int64_t initiated_dart_port;
int64_t accepted_dart_port;
int64_t rejected_dart_port;
int64_t disconnected_dart_port;
int64_t bandwidth_changed_dart_port;
// LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/flutter/lib/connection_listener.dart)
};
struct ConnectionRequestInfoDart {
// LINT.IfChange
char *endpoint_info;
ConnectionListenerDart connection_listener;
// LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/flutter/lib/connection_request_info.dart)
};
struct PayloadDart {
// LINT.IfChange
int64_t id;
PayloadType type;
int64_t size;
char *data;
// LINT.ThenChange(//depot/google3/location/nearby/apps/helloconnections/flutter/lib/payload.dart)
};
static void ResultCB(Status status);
static void ListenerInitiatedCB(const char *endpoint_id,
const ConnectionResponseInfoW &connection_info);
static void ListenerAcceptedCB(const char *endpoint_id);
static void ListenerRejectedCB(const char *endpoint_id,
connections::Status status);
static void ListenerDisconnectedCB(const char *endpoint_id);
static void ListenerBandwidthChangedCB(const char *endpoint_id, MediumW medium);
static void ListenerEndpointFoundCB(const char *endpoint_id,
const char *endpoint_info,
size_t endpoint_info_size,
const char *str_service_id);
static void ListenerEndpointLostCB(const char *endpoint_id);
static void ListenerEndpointDistanceChangedCB(const char *endpoint_id,
DistanceInfoW info);
static void ListenerPayloadCB(const char *endpoint_id, PayloadW &payload);
static void ListenerPayloadProgressCB(const char *endpoint_id,
const PayloadProgressInfoW &info);
// Starts advertising an endpoint for a local app.
//
// service_id - An identifier to advertise your app to other endpoints.
@@ -94,9 +181,10 @@ struct PayloadDart {
// Status::STATUS_ALREADY_ADVERTISING if the app is already advertising.
// Status::STATUS_OUT_OF_ORDER_API_CALL if the app is currently
// connected to remote endpoints; call StopAllEndpoints first.
DLL_EXPORT void __stdcall StartAdvertisingDart(
Core *pCore, const char *service_id, ConnectionOptionsDart options_dart,
ConnectionRequestInfoDart info_dart, Dart_Port result_cb);
DLL_API void __stdcall StartAdvertisingDart(Core *pCore, const char *service_id,
AdvertisingOptionsDart options_dart,
ConnectionRequestInfoDart info_dart,
Dart_Port result_cb);
// Stops advertising a local endpoint. Should be called after calling
// StartAdvertising, as soon as the application no longer needs to advertise
@@ -106,7 +194,7 @@ DLL_EXPORT void __stdcall StartAdvertisingDart(
// result_cb - to access the status of the operation when available.
// Possible status codes include:
// Status::STATUS_OK if none of the above errors occurred.
DLL_EXPORT void __stdcall StopAdvertisingDart(Core *pCore, Dart_Port result_cb);
DLL_API void __stdcall StopAdvertisingDart(Core *pCore, Dart_Port result_cb);
// Starts discovery for remote endpoints with the specified service ID.
//
@@ -121,9 +209,10 @@ DLL_EXPORT void __stdcall StopAdvertisingDart(Core *pCore, Dart_Port result_cb);
// discovering the specified service.
// Status::STATUS_OUT_OF_ORDER_API_CALL if the app is currently
// connected to remote endpoints; call StopAllEndpoints first.
DLL_EXPORT void __stdcall StartDiscoveryDart(
Core *pCore, const char *service_id, ConnectionOptionsDart options_dart,
DiscoveryListenerDart listener_dart, Dart_Port result_cb);
DLL_API void __stdcall StartDiscoveryDart(Core *pCore, const char *service_id,
DiscoveryOptionsDart options_dart,
DiscoveryListenerDart listener_dart,
Dart_Port result_cb);
// Stops discovery for remote endpoints, after a previous call to
// StartDiscovery, when the client no longer needs to discover endpoints or
@@ -133,7 +222,7 @@ DLL_EXPORT void __stdcall StartDiscoveryDart(
// result_cb - to access the status of the operation when available.
// Possible status codes include:
// Status::STATUS_OK if none of the above errors occurred.
DLL_EXPORT void __stdcall StopDiscoveryDart(Core *pCore, Dart_Port result_cb);
DLL_API void __stdcall StopDiscoveryDart(Core *pCore, Dart_Port result_cb);
// Sends a request to connect to a remote endpoint.
//
@@ -155,7 +244,7 @@ DLL_EXPORT void __stdcall StopDiscoveryDart(Core *pCore, Dart_Port result_cb);
// Status::STATUS_RADIO_ERROR if we failed to connect because of an
// issue with Bluetooth/WiFi.
// Status::STATUS_ERROR if we failed to connect for any other reason.
DLL_EXPORT void __stdcall RequestConnectionDart(
DLL_API void __stdcall RequestConnectionDart(
Core *pCore, const char *endpoint_id, ConnectionOptionsDart options_dart,
ConnectionRequestInfoDart info_dart, Dart_Port result_cb);
@@ -171,9 +260,14 @@ DLL_EXPORT void __stdcall RequestConnectionDart(
// Status::STATUS_OK if the connection request was accepted.
// Status::STATUS_ALREADY_CONNECTED_TO_ENDPOINT if the app already.
// has a connection to the specified endpoint.
DLL_EXPORT void __stdcall AcceptConnectionDart(
Core *pCore, const char *endpoint_id, PayloadListenerDart listener_dart,
Dart_Port result_cb);
DLL_API void __stdcall AcceptConnectionDart(Core *pCore,
const char *endpoint_id,
PayloadListenerDart listener_dart,
Dart_Port result_cb);
DLL_API void __stdcall RejectConnectionDart(Core *pCore,
const char *endpoint_id,
Dart_Port result_cb);
// Disconnects from a remote endpoint. {@link Payload}s can no longer be sent
// to or received from the endpoint after this method is called.
@@ -181,9 +275,9 @@ DLL_EXPORT void __stdcall AcceptConnectionDart(
// result_cb - to access the status of the operation when available.
// Possible status codes include:
// Status::STATUS_OK - finished successfully.
DLL_EXPORT void __stdcall DisconnectFromEndpointDart(Core *pCore,
char *endpoint_id,
Dart_Port result_cb);
DLL_API void __stdcall DisconnectFromEndpointDart(Core *pCore,
char *endpoint_id,
Dart_Port result_cb);
// Sends a Payload to a remote endpoint. Payloads can only be sent to remote
// endpoints once a notice of connection acceptance has been delivered via
@@ -204,13 +298,10 @@ DLL_EXPORT void __stdcall DisconnectFromEndpointDart(Core *pCore,
// still occur during transmission (and at different times for
// different endpoints), and will be delivered via
// PayloadCallback#onPayloadTransferUpdate.
DLL_EXPORT void __stdcall SendPayloadDart(Core *pCore, const char *endpoint_id,
PayloadDart payload_dart,
Dart_Port result_cb);
} // namespace windows
} // namespace connections
} // namespace nearby
} // namespace location
DLL_API void __stdcall SendPayloadDart(Core *pCore, const char *endpoint_id,
PayloadDart payload_dart,
Dart_Port result_cb);
} // extern "C"
} // namespace location::nearby::windows
#endif // LOCATION_NEARBY_CONNECTIONS_WINDOWS_CORE_ADAPTER_DART_H_
@@ -0,0 +1,48 @@
// Copyright 2022 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 "connections/clients/windows/discovery_options_w.h"
#include <string>
namespace location::nearby::windows {
// Returns a copy and normalizes allowed mediums:
// (1) If is_out_of_band_connection is true, verifies that there is only one
// medium allowed, defaulting to only Bluetooth if unspecified.
// (2) If no mediums are allowed, allow all mediums.
DiscoveryOptionsW DiscoveryOptionsW::CompatibleOptions() const {
DiscoveryOptionsW result = *this;
// Out-of-band connections initiate connections via an injected endpoint
// rather than through the normal discovery flow. These types of connections
// can only be injected via a single medium.
if (is_out_of_band_connection) {
int num_enabled = result.allowed.Count(true);
// Default to allow only Bluetooth if no single medium is specified.
if (num_enabled != 1) {
result.allowed.SetAll(false);
result.allowed.bluetooth = true;
}
return result;
}
// Normal connections (i.e., not out-of-band) connections can specify
// multiple mediums. If none are specified, default to allowing all mediums.
if (!allowed.Any(true)) result.allowed.SetAll(true);
return result;
}
} // namespace location::nearby::windows
@@ -0,0 +1,46 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_DISCOVERY_OPTIONS_W_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_DISCOVERY_OPTIONS_W_H_
#include <string>
#include "connections/clients/windows/options_base_w.h"
namespace location::nearby::windows {
extern "C" {
// Connection Options: used for both Advertising and Discovery.
// All fields are mutable, to make the type copy-assignable.
struct DLL_API DiscoveryOptionsW : public OptionsBaseW {
bool auto_upgrade_bandwidth = true;
bool enforce_topology_constraints;
int keep_alive_interval_millis = 0;
int keep_alive_timeout_millis = 0;
// Whether this is intended to be used in conjunction with InjectEndpoint().
bool is_out_of_band_connection = false;
const char* fast_advertisement_service_uuid;
// Returns a copy and normalizes allowed mediums:
// (1) If is_out_of_band_connection is true, verifies that there is only one
// medium allowed, defaulting to only Bluetooth if unspecified.
// (2) If no mediums are allowed, allow all mediums.
DiscoveryOptionsW CompatibleOptions() const;
};
} // extern "C"
} // namespace location::nearby::windows
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_DISCOVERY_OPTIONS_W_H_
+34
View File
@@ -0,0 +1,34 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_CONFIG_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_CONFIG_H_
namespace location::nearby::windows {
#ifdef _WIN32 // These storage class specifiers only matter to win32 dll
// builds.
#ifdef CORE_ADAPTER_DLL
#define DLL_API \
__declspec(dllexport) // If we're building the core, we're exporting.
#else // !CORE_ADAPTER_DLL
#define DLL_API \
__declspec(dllimport) // If we're not building the core, we're importing.
#endif // CORE_ADAPTER_DLL
#else // !_WIN32
#define DLL_API // We're not building a win32 dll, leave the source unchanged.
#endif // _WIN32
} // namespace location::nearby::windows
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_CONFIG_H_
@@ -0,0 +1,44 @@
"""Rule for specialized expansion of template files. This performs a simple search over the template
file for the keys $VERSION and $VS_VERSION and replaces them with the corresponding values, derived
from the version provided. Supports make variables.
Typical usage:
load("expand_version_template.bzl", "expand_version_template")
expand_version_template(
name = "ExpandMyTemplate",
out = "my.txt",
template = "my.template",
version = varref("VERSION"),
)
Args:
name: The name of the rule.
out: The destination of the expanded file
template: The template file to expand
version: A string containing the version number. Supports make variables.
"""
def expand_version_template_impl(ctx):
version = ctx.expand_make_variables(
"expand_version_template",
ctx.attr.version,
{},
)
vs_version = version.replace(".", ",")
ctx.actions.expand_template(
template = ctx.file.template,
output = ctx.outputs.out,
substitutions = {
"$VERSION": version,
"$VS_VERSION": vs_version,
},
)
expand_version_template = rule(
implementation = expand_version_template_impl,
attrs = {
"template": attr.label(mandatory = True, allow_single_file = True),
"version": attr.string(mandatory = False),
"out": attr.output(mandatory = True),
},
)
+67
View File
@@ -0,0 +1,67 @@
// Copyright 2022 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 "connections/clients/windows/file_w.h"
#include <string>
#include "internal/platform/file.h"
namespace location::nearby {
void InputFileDeleter::operator()(nearby::InputFile* p) { delete p; }
void OutputFileDeleter::operator()(nearby::OutputFile* p) { delete p; }
namespace windows {
InputFileW::InputFileW(InputFile* input_file)
: impl_(std::unique_ptr<nearby::InputFile, nearby::InputFileDeleter>(
new nearby::InputFile(std::move(*input_file)))) {}
InputFileW::InputFileW(PayloadId payload_id, size_t size)
: impl_(std::unique_ptr<nearby::InputFile, nearby::InputFileDeleter>(
new nearby::InputFile(payload_id, size))) {}
InputFileW::InputFileW(const char* file_path, size_t size)
: impl_(std::unique_ptr<nearby::InputFile, nearby::InputFileDeleter>(
new nearby::InputFile(file_path, size))) {}
InputFileW::InputFileW(InputFileW&& other) noexcept
: impl_(std::move(other.impl_)) {}
// Returns a string that uniquely identifies this file.
// Caller allocates buffer[MAX_PATH] and is responsible
// for freeing.
void InputFileW::GetFilePath(char* file_path) const {
std::string fp = impl_->GetFilePath();
strncpy(file_path, fp.c_str(), fp.length());
}
// Returns total size of this file in bytes.
size_t InputFileW::GetTotalSize() const { return impl_->GetTotalSize(); }
std::unique_ptr<nearby::InputFile, nearby::InputFileDeleter>
InputFileW::GetImpl() {
return std::move(impl_);
}
OutputFileW::OutputFileW(PayloadId payload_id) {}
OutputFileW::OutputFileW(const char* file_path) {}
OutputFileW::OutputFileW(OutputFileW&&) noexcept {}
OutputFileW& OutputFileW::operator=(OutputFileW&& other) noexcept {
impl_ = std::move(other.impl_);
return *this;
}
std::unique_ptr<nearby::OutputFile, nearby::OutputFileDeleter>
OutputFileW::GetImpl() {
return std::move(impl_);
}
} // namespace windows
} // namespace location::nearby
+86
View File
@@ -0,0 +1,86 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_FILE_W_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_FILE_W_H_
#include <memory>
#include <string>
#include "connections/clients/windows/dll_config.h"
#include "internal/platform/payload_id.h"
namespace location {
namespace nearby {
class InputFile;
struct DLL_API InputFileDeleter {
void operator()(InputFile* p);
};
class OutputFile;
struct DLL_API OutputFileDeleter {
void operator()(OutputFile* p);
};
} // namespace nearby
} // namespace location
namespace location {
namespace nearby {
namespace windows {
class DLL_API InputFileW {
public:
explicit InputFileW(location::nearby::InputFile* input_file);
InputFileW(location::nearby::PayloadId payload_id, size_t size);
InputFileW(const char* file_path, size_t size);
InputFileW(InputFileW&&) noexcept;
// Returns a string that uniquely identifies this file.
void GetFilePath(char* file_path) const;
// Returns total size of this file in bytes.
size_t GetTotalSize() const;
std::unique_ptr<location::nearby::InputFile,
location::nearby::InputFileDeleter>
GetImpl();
private:
std::unique_ptr<location::nearby::InputFile,
location::nearby::InputFileDeleter>
impl_;
};
class DLL_API OutputFileW {
public:
explicit OutputFileW(location::nearby::PayloadId payload_id);
explicit OutputFileW(const char* file_path);
OutputFileW(OutputFileW&&) noexcept;
OutputFileW& operator=(OutputFileW&&) noexcept;
std::unique_ptr<location::nearby::OutputFile,
location::nearby::OutputFileDeleter>
GetImpl();
private:
std::unique_ptr<location::nearby::OutputFile,
location::nearby::OutputFileDeleter>
impl_;
};
} // namespace windows
} // namespace nearby
} // namespace location
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_FILE_W_H_
@@ -0,0 +1,52 @@
// Copyright 2022 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 "connections/clients/windows/input_stream_w.h"
#include "internal/platform/input_stream.h"
namespace location::nearby {
void InputStreamDeleter::operator()(nearby::InputStream* p) { delete p; }
} // namespace location::nearby
namespace location {
namespace nearby {
namespace windows {
char* InputStreamW::Read(size_t size) {
auto result = impl_->Read(size);
if (result.ok()) {
return result.GetResult().data();
}
return nullptr;
}
int64_t InputStreamW::Skip(size_t offset) {
auto result = impl_->Skip(offset);
if (result.ok()) {
return result.GetResult();
}
return -1;
}
int64_t InputStreamW::Close() {
auto result = impl_->Close();
if (result.Ok()) {
return 0;
}
return -1;
}
} // namespace windows
} // namespace nearby
} // namespace location
@@ -0,0 +1,51 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_INPUT_STREAM_W_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_INPUT_STREAM_W_H_
#include <memory>
namespace location {
namespace nearby {
class InputStream;
struct InputStreamDeleter {
void operator()(InputStream* p);
};
} // namespace nearby
} // namespace location
namespace location {
namespace nearby {
namespace windows {
class InputStreamW {
public:
char* Read(size_t size);
// throws Exception::kIo
int64_t Skip(size_t offset);
// throws Exception::kIo
int64_t Close();
private:
std::unique_ptr<nearby::InputStream, nearby::InputStreamDeleter> impl_;
};
} // namespace windows
} // namespace nearby
} // namespace location
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_INPUT_STREAM_W_H_
+270
View File
@@ -0,0 +1,270 @@
// Copyright 2022 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 "connections/clients/windows/listeners_w.h"
#include "connections/listeners.h"
namespace location::nearby {
// Must implement Deleters, since the connections classes weren't
// fully defined in the header
namespace connections {
void ResultCallbackDeleter::operator()(connections::ResultCallback *p) {
delete p;
}
void ConnectionListenerDeleter::operator()(connections::ConnectionListener *p) {
delete p;
}
void DiscoveryListenerDeleter::operator()(connections::DiscoveryListener *p) {
delete p;
}
void PayloadListenerDeleter::operator()(connections::PayloadListener *p) {
delete p;
}
} // namespace connections
namespace windows {
static ResultCallbackW *ResultCallbackImpl;
void ResultCB(Status status) { ResultCallbackImpl->result_cb(status); }
ResultCallbackW::ResultCallbackW()
: impl_(std::unique_ptr<connections::ResultCallback,
connections::ResultCallbackDeleter>(
new connections::ResultCallback())) {
ResultCallbackImpl = this;
impl_->result_cb = ResultCB;
}
ResultCallbackW::~ResultCallbackW() {}
ResultCallbackW::ResultCallbackW(ResultCallbackW &other) {
impl_ = std::move(other.impl_);
}
ResultCallbackW::ResultCallbackW(ResultCallbackW &&other) noexcept {
impl_ = std::move(other.impl_);
}
ConnectionListenerW::ConnectionListenerW(InitiatedCB initiatedCB,
AcceptedCB acceptedCB,
RejectedCB rejectedCB,
DisconnectedCB disconnectedCB,
BandwidthChangedCB bandwidthChangedCB)
: initiated_cb(initiatedCB),
accepted_cb(acceptedCB),
rejected_cb(rejectedCB),
disconnected_cb(disconnectedCB),
bandwidth_changed_cb(bandwidthChangedCB),
impl_(std::unique_ptr<connections::ConnectionListener,
connections::ConnectionListenerDeleter>(
new connections::ConnectionListener())) {
CHECK(initiated_cb != nullptr);
auto i = initiated_cb;
impl_->initiated_cb =
[i](const std::string &endpoint_id,
const connections::ConnectionResponseInfo connection_response_info) {
ConnectionResponseInfoW connection_response_info_w{
connection_response_info.remote_endpoint_info.data(),
connection_response_info.remote_endpoint_info.size(),
connection_response_info.authentication_token.c_str(),
connection_response_info.raw_authentication_token.data(),
connection_response_info.raw_authentication_token.size(),
connection_response_info.is_incoming_connection,
connection_response_info.is_connection_verified};
i(endpoint_id.c_str(), connection_response_info_w);
};
CHECK(accepted_cb != nullptr);
auto a = accepted_cb;
impl_->accepted_cb = [a](const std::string &endpoint_id) {
a(endpoint_id.c_str());
};
CHECK(rejected_cb != nullptr);
auto r = rejected_cb;
impl_->rejected_cb = [r](const std::string &endpoint_id, Status status) {
r(endpoint_id.c_str(), status);
};
CHECK(disconnected_cb != nullptr);
auto d = disconnected_cb;
impl_->disconnected_cb = [d](const std::string &endpoint_id) {
d(endpoint_id.c_str());
};
CHECK(bandwidth_changed_cb != nullptr);
auto bwc = bandwidth_changed_cb;
impl_->bandwidth_changed_cb = [bwc](const std::string &endpoint_id,
connections::Medium medium) {
bwc(endpoint_id.c_str(), medium);
};
}
ConnectionListenerW::ConnectionListenerW(ConnectionListenerW &other) {
impl_ = std::move(other.impl_);
accepted_cb = other.accepted_cb;
bandwidth_changed_cb = other.bandwidth_changed_cb;
disconnected_cb = other.disconnected_cb;
initiated_cb = other.initiated_cb;
rejected_cb = other.rejected_cb;
}
ConnectionListenerW::ConnectionListenerW(ConnectionListenerW &&other) noexcept =
default;
DiscoveryListenerW::DiscoveryListenerW(
EndpointFoundCB endpointFoundCB, EndpointLostCB endpointLostCB,
EndpointDistanceChangedCB endpointDistanceChangedCB)
: endpoint_found_cb(endpointFoundCB),
endpoint_lost_cb(endpointLostCB),
endpoint_distance_changed_cb(endpointDistanceChangedCB),
impl_(new connections::DiscoveryListener()) {
CHECK(endpoint_distance_changed_cb != nullptr);
auto epdc = endpoint_distance_changed_cb;
impl_->endpoint_distance_changed_cb =
[epdc](const std::string &endpoint_id,
connections::DistanceInfo distance_info) {
DistanceInfoW distanceInfoW = DistanceInfoW::kUnknown;
switch (distance_info) {
case connections::DistanceInfo::kFar:
distanceInfoW = DistanceInfoW::kFar;
break;
case connections::DistanceInfo::kClose:
distanceInfoW = DistanceInfoW::kFar;
break;
case connections::DistanceInfo::kVeryClose:
distanceInfoW = DistanceInfoW::kVeryClose;
break;
case connections::DistanceInfo::kUnknown:
break;
}
epdc(endpoint_id.c_str(), distanceInfoW);
};
CHECK(endpoint_found_cb != nullptr);
auto epf = endpoint_found_cb;
impl_->endpoint_found_cb = [epf](const std::string &endpoint_id,
ByteArray endpoint_info,
const std::string &service_id) {
epf(endpoint_id.c_str(), endpoint_info.data(), endpoint_info.size(),
service_id.c_str());
};
CHECK(endpoint_lost_cb != nullptr);
auto epl = endpoint_lost_cb;
impl_->endpoint_lost_cb = [epl](const std::string &endpoint_id) {
epl(endpoint_id.c_str());
};
}
DiscoveryListenerW::DiscoveryListenerW(DiscoveryListenerW &other) {
endpoint_distance_changed_cb = other.endpoint_distance_changed_cb;
endpoint_found_cb = other.endpoint_found_cb;
endpoint_lost_cb = other.endpoint_lost_cb;
impl_ = std::move(other.impl_);
}
DiscoveryListenerW::DiscoveryListenerW(DiscoveryListenerW &&other) noexcept {
endpoint_distance_changed_cb = other.endpoint_distance_changed_cb;
endpoint_found_cb = other.endpoint_found_cb;
endpoint_lost_cb = other.endpoint_lost_cb;
impl_ = std::move(other.impl_);
}
PayloadListenerW::PayloadListenerW(PayloadCB payloadCB,
PayloadProgressCB payloadProgressCB)
: payload_cb(payloadCB),
payload_progress_cb(payloadProgressCB),
impl_(std::unique_ptr<connections::PayloadListener,
connections::PayloadListenerDeleter>(
new connections::PayloadListener())) {
CHECK(payload_cb != nullptr);
auto pcb = payload_cb;
impl_->payload_cb = [pcb](const std::string &endpoint_id,
connections::Payload payload) {
PayloadW payloadW;
switch (payload.GetType()) {
case connections::PayloadType::kBytes: {
payloadW = PayloadW(payload.GetId(), payload.AsBytes().data(),
payload.AsBytes().size());
break;
}
case connections::PayloadType::kFile: {
InputFileW file(std::move(payload.AsFile()));
payloadW = PayloadW(payload.GetId(), std::move(file));
} break;
// TODO(jfcarroll): Figure out how to capture type kStream.
// case connections::PayloadType::kStream: {
// payloadW = PayloadW(payload.AsStream());
//}
case connections::PayloadType::kStream: {
InputFileW file(std::move(payload.AsFile()));
payloadW = PayloadW(payload.GetId(), std::move(file));
} break;
case connections::PayloadType::kUnknown: {
// Throw exception here?
break;
}
}
pcb(endpoint_id.c_str(), payloadW);
};
CHECK(payload_progress_cb != nullptr);
auto ppcb = payload_progress_cb;
impl_->payload_progress_cb =
[ppcb](const std::string &endpoint_id,
connections::PayloadProgressInfo payload_progress_info) {
PayloadProgressInfoW payload_progress_info_w;
payload_progress_info_w.payload_id = payload_progress_info.payload_id;
payload_progress_info_w.total_bytes = payload_progress_info.total_bytes;
payload_progress_info_w.bytes_transferred =
payload_progress_info.bytes_transferred;
switch (payload_progress_info.status) {
case connections::PayloadProgressInfo::Status::kCanceled:
payload_progress_info_w.status =
PayloadProgressInfoW::Status::kCanceled;
break;
case connections::PayloadProgressInfo::Status::kFailure:
payload_progress_info_w.status =
PayloadProgressInfoW::Status::kFailure;
break;
case connections::PayloadProgressInfo::Status::kInProgress:
payload_progress_info_w.status =
PayloadProgressInfoW::Status::kInProgress;
break;
case connections::PayloadProgressInfo::Status::kSuccess:
payload_progress_info_w.status =
PayloadProgressInfoW::Status::kSuccess;
break;
}
ppcb(endpoint_id.c_str(), payload_progress_info_w);
};
}
PayloadListenerW::PayloadListenerW(PayloadListenerW &other) {
impl_ = std::move(other.impl_);
}
PayloadListenerW::PayloadListenerW(PayloadListenerW &&other) noexcept {
impl_ = std::move(other.impl_);
}
} // namespace windows
} // namespace location::nearby
+300
View File
@@ -0,0 +1,300 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_LISTENERS_W_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_LISTENERS_W_H_
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
// This file defines all the protocol listeners and their parameter structures.
// Listeners are defined as collections of std::function<T> instances, which is
// more flexible than a virtual function:
// - a subset of listener callbacks may be overridden, while others may remain
// default-initialized.
// - callbacks may be initialized with lambdas; lambda definitions are concize.
#include "connections/clients/windows/medium_selector_w.h"
#include "connections/clients/windows/payload_w.h"
#include "connections/status.h"
#include "internal/platform/payload_id.h"
namespace location::nearby {
// Forward declarations
namespace connections {
struct ConnectionListener;
struct DLL_API ConnectionListenerDeleter {
void operator()(connections::ConnectionListener* p);
};
struct DiscoveryListener;
struct DLL_API DiscoveryListenerDeleter {
void operator()(connections::DiscoveryListener* p);
};
struct PayloadListener;
struct DLL_API PayloadListenerDeleter {
void operator()(connections::PayloadListener* p);
};
struct ResultCallback;
struct ResultCallbackDeleter {
void operator()(connections::ResultCallback* p);
};
struct ConnectionResponseInfo;
struct PayloadProgressInfo;
} // namespace connections
namespace windows {
using ::location::nearby::connections::Status;
template <class T>
T DefaultConstructor() {
return T();
}
template <class T>
void DefaultConstructor(T t) {}
template <class T, class C>
void DefaultConstructor(T t, C c) {}
template <class T, class C, class D>
void DefaultConstructor(T t, C c, size_t size, D d) {}
extern "C" {
// Common callback for asynchronously invoked methods.
// Called after a job scheduled for execution is completed.
// This is not the same as completion of the associated process,
// which may have many states, and multiple async jobs, and be still ongoing.
// Progress on the overall process is reported by the associated listener.
struct DLL_API ResultCallbackW {
// Callback to access the status of the operation when available.
// status - result of job execution;
// Status::kSuccess, if successful; anything else indicates failure.
ResultCallbackW();
~ResultCallbackW();
ResultCallbackW(ResultCallbackW& other);
ResultCallbackW(ResultCallbackW&& other) noexcept;
void (*result_cb)(Status status) = DefaultConstructor;
std::unique_ptr<connections::ResultCallback,
connections::ResultCallbackDeleter>
GetImpl() {
return std::move(impl_);
}
private:
std::unique_ptr<connections::ResultCallback,
connections::ResultCallbackDeleter>
impl_;
};
struct DLL_API ConnectionResponseInfoW {
const char* remote_endpoint_info;
size_t remote_endpoint_info_size;
const char* authentication_token;
const char* raw_authentication_token;
size_t raw_authentication_token_size;
bool is_incoming_connection = false;
bool is_connection_verified = false;
};
struct DLL_API PayloadProgressInfoW {
PayloadId payload_id = 0;
enum class Status {
kSuccess,
kFailure,
kInProgress,
kCanceled,
} status = Status::kSuccess;
size_t total_bytes = 0;
size_t bytes_transferred = 0;
};
enum class DLL_API DistanceInfoW {
kUnknown = 1,
kVeryClose = 2,
kClose = 3,
kFar = 4,
};
struct DLL_API ConnectionListenerW {
typedef void (*InitiatedCB)(const char* endpoint_id,
const ConnectionResponseInfoW& info);
typedef void (*AcceptedCB)(const char* endpoint_id);
typedef void (*RejectedCB)(const char* endpoint_id, Status status);
typedef void (*DisconnectedCB)(const char* endpoint_id);
typedef void (*BandwidthChangedCB)(const char* endpoint_id, MediumW medium);
ConnectionListenerW(InitiatedCB, AcceptedCB, RejectedCB, DisconnectedCB,
BandwidthChangedCB);
ConnectionListenerW(ConnectionListenerW& other);
ConnectionListenerW(ConnectionListenerW&& other) noexcept;
// A basic encrypted channel has been created between you and the endpoint.
// Both sides are now asked if they wish to accept or reject the connection
// before any data can be sent over this channel.
//
// This is your chance, before you accept the connection, to confirm that you
// connected to the correct device. Both devices are given an identical token;
// it's up to you to decide how to verify it before proceeding. Typically this
// involves showing the token on both devices and having the users manually
// compare and confirm; however, this is only required if you desire a secure
// connection between the devices.
//
// Whichever route you decide to take (including not authenticating the other
// device), call Core::AcceptConnection() when you're ready to talk, or
// Core::RejectConnection() to close the connection.
//
// endpoint_id - The identifier for the remote endpoint.
// info - Other relevant information about the connection.
InitiatedCB initiated_cb = DefaultConstructor;
// Called after both sides have accepted the connection.
// Both sides may now send Payloads to each other.
// Call Core::SendPayload() or wait for incoming PayloadListener::OnPayload().
//
// endpoint_id - The identifier for the remote endpoint.
AcceptedCB accepted_cb = DefaultConstructor;
// Called when either side rejected the connection.
// Payloads can not be exchanged. Call Core::DisconnectFromEndpoint()
// to terminate connection.
//
// endpoint_id - The identifier for the remote endpoint.
RejectedCB rejected_cb = DefaultConstructor;
// Called when a remote endpoint is disconnected or has become unreachable.
// At this point service (re-)discovery may start again.
//
// endpoint_id - The identifier for the remote endpoint.
DisconnectedCB disconnected_cb = DefaultConstructor;
// Called when the connection's available bandwidth has changed.
//
// endpoint_id - The identifier for the remote endpoint.
// medium - Medium we upgraded to.
BandwidthChangedCB bandwidth_changed_cb = DefaultConstructor;
std::unique_ptr<connections::ConnectionListener,
connections::ConnectionListenerDeleter>
GetImpl() {
return std::move(impl_);
}
private:
std::unique_ptr<connections::ConnectionListener,
connections::ConnectionListenerDeleter>
impl_;
};
struct DLL_API DiscoveryListenerW {
typedef void (*EndpointFoundCB)(const char* endpoint_id,
const char* endpoint_info,
size_t endpoint_info_size,
const char* service_id);
typedef void (*EndpointLostCB)(const char* endpoint_id);
typedef void (*EndpointDistanceChangedCB)(const char* endpoint_id,
DistanceInfoW info);
DiscoveryListenerW(EndpointFoundCB endpointFoundCB,
EndpointLostCB endpointLostCB,
EndpointDistanceChangedCB endpointDistanceChangedCB);
DiscoveryListenerW(DiscoveryListenerW& other);
DiscoveryListenerW(DiscoveryListenerW&& other) noexcept;
// Called when a remote endpoint is discovered.
//
// endpoint_id - The ID of the remote endpoint that was discovered.
// endpoint_info - The info of the remote endpoint represented by ByteArray.
// service_id - The ID of the service advertised by the remote endpoint.
EndpointFoundCB endpoint_found_cb = DefaultConstructor;
// Called when a remote endpoint is no longer discoverable; only called for
// endpoints that previously had been passed to {@link
// #onEndpointFound(String, DiscoveredEndpointInfo)}.
//
// endpoint_id - The ID of the remote endpoint that was lost.
EndpointLostCB endpoint_lost_cb = DefaultConstructor;
// Called when a remote endpoint is found with an updated distance.
//
// arguments:
// endpoint_id - The ID of the remote endpoint that was lost.
// info - The distance info, encoded as enum value.
EndpointDistanceChangedCB endpoint_distance_changed_cb = DefaultConstructor;
std::unique_ptr<connections::DiscoveryListener,
connections::DiscoveryListenerDeleter>
GetImpl() {
return std::move(impl_);
}
private:
std::unique_ptr<connections::DiscoveryListener,
connections::DiscoveryListenerDeleter>
impl_;
};
struct DLL_API PayloadListenerW {
typedef void (*PayloadCB)(const char* endpoint_id, PayloadW& payload);
typedef void (*PayloadProgressCB)(const char* endpoint_id,
const PayloadProgressInfoW& info);
PayloadListenerW(PayloadCB, PayloadProgressCB);
PayloadListenerW(PayloadListenerW& other);
PayloadListenerW(PayloadListenerW&& other) noexcept;
// Called when a Payload is received from a remote endpoint. Depending
// on the type of the Payload, all of the data may or may not have been
// received at the time of this call. Use OnPayloadProgress() to
// get updates on the status of the data received.
//
// endpoint_id - The identifier for the remote endpoint that sent the
// payload.
// payload - The Payload object received.
PayloadCB payload_cb = DefaultConstructor;
// Called with progress information about an active Payload transfer, either
// incoming or outgoing.
//
// endpoint_id - The identifier for the remote endpoint that is sending or
// receiving this payload.
// info - The PayloadProgressInfo structure describing the status of
// the transfer.
PayloadProgressCB payload_progress_cb = DefaultConstructor;
std::unique_ptr<connections::PayloadListener,
connections::PayloadListenerDeleter>
GetImpl() {
return std::move(impl_);
}
private:
std::unique_ptr<connections::PayloadListener,
connections::PayloadListenerDeleter>
impl_;
};
} // extern "C"
} // namespace windows
} // namespace location::nearby
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_LISTENERS_W_H_
@@ -0,0 +1,81 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_MEDIUM_SELECTOR_W_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_MEDIUM_SELECTOR_W_H_
#include "proto/connections_enums.pb.h"
namespace location::nearby::windows {
using MediumW = ::location::nearby::proto::connections::Medium;
// Generic type: allows definition of a feature T for every Medium.
template <typename T>
struct MediumSelectorW {
T bluetooth;
T ble;
T web_rtc;
T wifi_lan;
T wifi_hotspot;
constexpr MediumSelectorW() = default;
constexpr MediumSelectorW(const MediumSelectorW&) = default;
constexpr MediumSelectorW& operator=(const MediumSelectorW&) = default;
constexpr bool Any(const T& value) const {
return bluetooth == value || ble == value || web_rtc == value ||
wifi_lan == value || wifi_hotspot == value;
}
constexpr bool All(const T& value) const {
return bluetooth == value && ble == value && web_rtc == value &&
wifi_lan == value && wifi_hotspot == value;
}
constexpr int Count(const T& value) const {
int count = 0;
if (bluetooth == value) ++count;
if (ble == value) ++count;
if (wifi_lan == value) ++count;
if (wifi_hotspot == value) ++count;
if (web_rtc == value) ++count;
return count;
}
constexpr MediumSelectorW& SetAll(const T& value) {
bluetooth = value;
ble = value;
web_rtc = value;
wifi_lan = value;
wifi_hotspot = value;
return *this;
}
std::vector<MediumW> GetMediums(const T& value) const {
std::vector<MediumW> mediums;
// Mediums are sorted in order of decreasing preference.
if (wifi_lan == value) mediums.push_back(MediumW::WIFI_LAN);
if (wifi_hotspot == value) mediums.push_back(MediumW::WIFI_HOTSPOT);
if (web_rtc == value) mediums.push_back(MediumW::WEB_RTC);
if (bluetooth == value) mediums.push_back(MediumW::BLUETOOTH);
if (ble == value) mediums.push_back(MediumW::BLE);
return mediums;
}
};
// Feature On/Off switch for mediums.
using BooleanMediumSelectorW = MediumSelectorW<bool>;
} // namespace location::nearby::windows
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_MEDIUM_SELECTOR_W_H_
@@ -0,0 +1,34 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_OPTIONS_BASE_W_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_OPTIONS_BASE_W_H_
#include "connections/clients/windows/medium_selector_w.h"
#include "connections/clients/windows/strategy_w.h"
namespace location::nearby::windows {
extern "C" {
// Connection Options: used for both Advertising and Discovery.
// All fields are mutable, to make the type copy-assignable.
struct OptionsBaseW {
location::nearby::windows::StrategyW strategy;
BooleanMediumSelectorW allowed{BooleanMediumSelectorW().SetAll(true)};
};
} // extern "C"
} // namespace location::nearby::windows
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_OPTIONS_BASE_W_H_
@@ -0,0 +1,58 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_OUT_OF_BAND_CONNECTION_METADATA_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_OUT_OF_BAND_CONNECTION_METADATA_H_
#include <string>
#include "connections/clients/windows/medium_selector_w.h"
#include "connections/clients/windows/strategy_w.h"
#include "internal/platform/byte_array.h"
#include "proto/connections_enums.pb.h"
namespace location::nearby::windows {
extern "C" {
// Metadata injected to facilitate out-of-band connections. The medium field is
// required, and the other fields are only specified for a specific medium.
// Currently, Bluetooth is the only supported medium for out-of-band
// connections.
struct DLL_API OutOfBandConnectionMetadataW {
// Medium to use for the out-of-band connection.
MediumW medium;
// Endpoint ID to use for the injected connection; will be included in the
// endpoint_found_cb callback. Must be exactly 4 bytes and should be randomly-
// generated such that no two IDs are identical.
const char* endpoint_id;
// Endpoint info to use for the injected connection; will be included in the
// endpoint_found_cb callback. Should uniquely identify the InjectEndpoint()
// call so that the client which made the call can verify the endpoint
// that was found is the one that was injected.
//
// Cannot be empty, and must be <131 bytes.
const char* endpoint_info;
size_t endpoint_info_size;
// Used for Bluetooth connections.
const char* remote_bluetooth_mac_address;
size_t remote_bluetooth_mac_address_size;
};
} // extern "C"
} // namespace location::nearby::windows
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_OUT_OF_BAND_CONNECTION_METADATA_H_
+42
View File
@@ -0,0 +1,42 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_PARAMS_W_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_PARAMS_W_H_
#include <string>
#include "connections/clients/windows/listeners_w.h"
namespace location::nearby::windows {
extern "C" {
// Used by Discovery in Core::RequestConnection().
// Used by Advertising in Core::StartAdvertising().
struct DLL_API ConnectionRequestInfoW {
// endpoint_info - Identifying information about this endpoint (eg. name,
// device type).
// listener - A set of callbacks notified when remote endpoints request a
// connection to this endpoint.
// ByteArray endpoint_info;
const char* endpoint_info;
size_t endpoint_info_size;
ConnectionListenerW& listener;
};
} // extern "C"
} // namespace location::nearby::windows
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_PARAMS_W_H_
+132
View File
@@ -0,0 +1,132 @@
// Copyright 2022 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 "connections/clients/windows/payload_w.h"
#include "connections/clients/windows/file_w.h"
#include "connections/payload.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/payload_id.h"
namespace location::nearby {
// Must implement Deleter since Payload wasn't fully defined in
// the header
namespace connections {
class Payload;
void PayloadDeleter::operator()(connections::Payload *p) { delete p; }
} // namespace connections
namespace windows {
PayloadW::PayloadW()
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
new connections::Payload())) {}
PayloadW::~PayloadW() {}
PayloadW::PayloadW(PayloadW &&other) noexcept : impl_(std::move(other.impl_)) {}
PayloadW &PayloadW::operator=(PayloadW &&other) noexcept {
impl_ = std::move(other.impl_);
return *this;
}
// Constructors for outgoing payloads.
PayloadW::PayloadW(const char *bytes, const size_t bytes_size)
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
new connections::Payload(ByteArray(bytes, bytes_size)))) {}
PayloadW::PayloadW(InputFileW &file)
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
new connections::Payload(InputFile(std::move(*file.GetImpl()))))) {}
// TODO(jfcarroll): Convert std::function to function pointer
PayloadW::PayloadW(std::function<InputStream &()> stream)
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
new connections::Payload(stream))) {}
// Constructors for incoming payloads.
PayloadW::PayloadW(PayloadId id, const char *bytes, const size_t bytes_size)
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
new connections::Payload(id, ByteArray(bytes, bytes_size)))) {}
PayloadW::PayloadW(PayloadId id, InputFileW file)
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
new connections::Payload(id, std::move(*file.GetImpl())))) {}
PayloadW::PayloadW(const char *parent_folder, const char *file_name,
InputFileW file)
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
new connections::Payload(parent_folder, file_name,
std::move(*file.GetImpl())))) {}
PayloadW::PayloadW(PayloadId id, std::function<InputStream &()> stream)
: impl_(std::unique_ptr<connections::Payload, connections::PayloadDeleter>(
new connections::Payload(id, stream))) {}
// Returns ByteArray payload, if it has been defined, or empty ByteArray.
bool PayloadW::AsBytes(const char *bytes, size_t &bytes_size) const & {
auto byteArray = impl_->AsBytes();
if (bytes_size < byteArray.size()) {
bytes_size = byteArray.size();
bytes = nullptr;
return false;
}
bytes_size = byteArray.size();
bytes = byteArray.data();
return true;
}
bool PayloadW::AsBytes(const char *bytes, size_t &bytes_size) && {
auto byteArray = impl_->AsBytes();
if (bytes_size < byteArray.size()) {
bytes_size = byteArray.size();
bytes = nullptr;
return false;
}
bytes_size = byteArray.size();
bytes = byteArray.data();
return true;
}
// Returns InputStream* payload, if it has been defined, or nullptr.
InputStream *PayloadW::AsStream() { return impl_->AsStream(); }
// Returns InputFile* payload, if it has been defined, or nullptr.
InputFile *PayloadW::AsFile() const { return impl_->AsFile(); }
// Returns Payload unique ID.
int64_t PayloadW::GetId() const { return impl_->GetId(); }
// Returns Payload type.
const connections::PayloadType PayloadW::GetType() const {
return static_cast<connections::PayloadType>(impl_->GetType());
}
// Sets the payload offset in bytes
void PayloadW::SetOffset(size_t offset) { impl_->SetOffset(offset); }
size_t PayloadW::GetOffset() { return impl_->GetOffset(); }
// Generate Payload Id; to be passed to outgoing file constructor.
PayloadId PayloadW::GenerateId() { return connections::Payload::GenerateId(); }
const char *PayloadW::GetParentFolder() const { return nullptr; }
const char *PayloadW::GetFileName() const { return nullptr; }
std::unique_ptr<connections::Payload, connections::PayloadDeleter>
PayloadW::GetImpl() {
return std::move(impl_);
}
} // namespace windows
} // namespace location::nearby
+119
View File
@@ -0,0 +1,119 @@
// Copyright 2022 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_CONNECTIONS_CLIENTS_WINDOWS_PAYLOAD_W_H_
#define THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_PAYLOAD_W_H_
#include <cstdint>
#include <functional>
#include <memory>
#include <utility>
#include "connections/clients/windows/dll_config.h"
#include "connections/clients/windows/file_w.h"
#include "connections/payload_type.h"
#include "internal/platform/payload_id.h"
namespace location {
namespace nearby {
namespace connections {
class Payload;
struct PayloadDeleter {
void operator()(Payload* p);
};
} // namespace connections
} // namespace nearby
} // namespace location
namespace location {
namespace nearby {
class InputFile;
class InputStream;
} // namespace nearby
} // namespace location
namespace location {
namespace nearby {
namespace windows {
extern "C" {
// Payload is default-constructible, and moveable, but not copyable container
// that holds at most one instance of one of:
// ByteArray, InputStream, or InputFile.
class DLL_API PayloadW {
public:
PayloadW(PayloadW&& other) noexcept;
PayloadW& operator=(PayloadW&& other) noexcept;
// Default (invalid) payload.
PayloadW();
~PayloadW();
// Constructors for outgoing payloads.
explicit PayloadW(const char* bytes, const size_t size);
explicit PayloadW(InputFileW& file);
explicit PayloadW(std::function<InputStream&()> stream);
// Constructors for incoming payloads.
PayloadW(PayloadId id, const char* bytes, const size_t size);
PayloadW(PayloadId id, InputFileW file);
explicit PayloadW(const char* parent_folder, const char* file_name,
InputFileW file);
// TODO(jfcarroll): Convert std::function to function pointer
PayloadW(PayloadId id, std::function<InputStream&()> stream);
// Returns ByteArray payload, if it has
// been defined, or empty ByteArray.
bool AsBytes(const char* bytes, size_t& bytes_size) const&;
bool AsBytes(const char* bytes, size_t& bytes_size) &&;
// Returns InputStream* payload, if it has been defined, or nullptr.
InputStream* AsStream();
// Returns InputFile* payload, if it has been defined, or nullptr.
InputFile* AsFile() const;
// Returns Payload unique ID.
int64_t GetId() const;
// Returns Payload type.
const location::nearby::connections::PayloadType GetType() const;
// Sets the payload offset in bytes
void SetOffset(size_t offset);
size_t GetOffset();
// Generate Payload Id; to be passed to outgoing file constructor.
static PayloadId GenerateId();
const char* GetFileName() const;
const char* GetParentFolder() const;
std::unique_ptr<connections::Payload, connections::PayloadDeleter> GetImpl();
private:
std::unique_ptr<connections::Payload, connections::PayloadDeleter> impl_;
};
} // extern "C"
} // namespace windows
} // namespace nearby
} // namespace location
#endif // THIRD_PARTY_NEARBY_CONNECTIONS_CLIENTS_WINDOWS_PAYLOAD_W_H_
+79
View File
@@ -0,0 +1,79 @@
// Copyright 2022 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 "connections/clients/windows/strategy_w.h"
#include <string>
namespace location::nearby::windows {
const StrategyW StrategyW::kNone = {StrategyW::ConnectionType::kNone,
StrategyW::TopologyType::kUnknown};
const StrategyW StrategyW::kP2pCluster{StrategyW::ConnectionType::kPointToPoint,
StrategyW::TopologyType::kManyToMany};
const StrategyW StrategyW::kP2pStar{StrategyW::ConnectionType::kPointToPoint,
StrategyW::TopologyType::kOneToMany};
const StrategyW StrategyW::kP2pPointToPoint{
StrategyW::ConnectionType::kPointToPoint,
StrategyW::TopologyType::kOneToOne};
// static
const StrategyW& StrategyW::GetStrategyNone() { return StrategyW::kNone; }
// static
const StrategyW& StrategyW::GetStrategyP2pCluster() {
return StrategyW::kP2pCluster;
}
// static
const StrategyW& StrategyW::GetStrategyP2pStar() { return StrategyW::kP2pStar; }
// static
const StrategyW& StrategyW::GetStrategyPointToPoint() {
return StrategyW::kP2pPointToPoint;
}
constexpr StrategyW::StrategyW() : StrategyW(kNone) {}
bool StrategyW::IsNone() const { return *this == kNone; }
bool StrategyW::IsValid() const {
return *this == kP2pStar || *this == kP2pCluster || *this == kP2pPointToPoint;
}
std::string StrategyW::GetName() const {
if (*this == StrategyW::kP2pCluster) {
return "P2P_CLUSTER";
}
if (*this == StrategyW::kP2pStar) {
return "P2P_STAR";
}
if (*this == StrategyW::kP2pPointToPoint) {
return "P2P_POINT_TO_POINT";
}
return "UNKNOWN";
}
void StrategyW::Clear() { *this = kNone; }
bool operator==(const StrategyW& lhs, const StrategyW& rhs) {
return lhs.connection_type_ == rhs.connection_type_ &&
lhs.topology_type_ == rhs.topology_type_;
}
bool operator!=(const StrategyW& lhs, const StrategyW& rhs) {
return !(lhs == rhs);
}
} // namespace location::nearby::windows

Some files were not shown because too many files have changed in this diff Show More