diff --git a/cpp/core/listeners.h b/cpp/core/listeners.h index 9ef5d2da..f9c0208d 100644 --- a/cpp/core/listeners.h +++ b/cpp/core/listeners.h @@ -33,6 +33,7 @@ #include "platform/base/byte_array.h" #include "platform/base/byte_utils.h" #include "platform/base/listeners.h" +#include "platform/public/core_config.h" namespace location { namespace nearby { @@ -43,14 +44,14 @@ namespace connections { // 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 ResultCallback { +struct DLL_API ResultCallback { // Callback to access the status of the operation when available. // status - result of job execution; // Status::kSuccess, if successful; anything else indicates failure. std::function result_cb = DefaultCallback(); }; -struct ConnectionResponseInfo { +struct DLL_API ConnectionResponseInfo { std::string GetAuthenticationDigits() { return ByteUtils::ToFourDigitString(raw_authentication_token); } @@ -62,7 +63,7 @@ struct ConnectionResponseInfo { bool is_connection_verified = false; }; -struct PayloadProgressInfo { +struct DLL_API PayloadProgressInfo { std::int64_t payload_id = 0; enum class Status { kSuccess, @@ -74,14 +75,14 @@ struct PayloadProgressInfo { std::int64_t bytes_transferred = 0; }; -enum class DistanceInfo { +enum class DLL_API DistanceInfo { kUnknown = 1, kVeryClose = 2, kClose = 3, kFar = 4, }; -struct ConnectionListener { +struct DLL_API ConnectionListener { // 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. @@ -135,7 +136,7 @@ struct ConnectionListener { bandwidth_changed_cb = DefaultCallback(); }; -struct DiscoveryListener { +struct DLL_API DiscoveryListener { // Called when a remote endpoint is discovered. // // endpoint_id - The ID of the remote endpoint that was discovered. @@ -165,7 +166,7 @@ struct DiscoveryListener { DefaultCallback(); }; -struct PayloadListener { +struct DLL_API PayloadListener { // 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 diff --git a/cpp/core/params.h b/cpp/core/params.h index c34fc13f..3843cee9 100644 --- a/cpp/core/params.h +++ b/cpp/core/params.h @@ -19,6 +19,7 @@ #include "core/listeners.h" #include "platform/base/byte_array.h" +#include "platform/public/core_config.h" namespace location { namespace nearby { @@ -26,7 +27,7 @@ namespace connections { // Used by Discovery in Core::RequestConnection(). // Used by Advertising in Core::StartAdvertising(). -struct ConnectionRequestInfo { +struct DLL_API ConnectionRequestInfo { // endpoint_info - Identifing information about this endpoint (eg. name, // device type). // listener - A set of callbacks notified when remote endpoints request a diff --git a/cpp/core/payload.h b/cpp/core/payload.h index 9a93e4bc..997eb41f 100644 --- a/cpp/core/payload.h +++ b/cpp/core/payload.h @@ -25,6 +25,7 @@ #include "platform/base/input_stream.h" #include "platform/base/payload_id.h" #include "platform/base/prng.h" +#include "platform/public/core_config.h" #include "platform/public/file.h" #include "platform/public/logging.h" @@ -35,7 +36,7 @@ namespace connections { // Payload is default-constructible, and moveable, but not copyable container // that holds at most one instance of one of: // ByteArray, InputStream, or InputFile. -class Payload { +class DLL_API Payload { public: using Id = PayloadId; // Order of types in variant, and values in Type enum is important. diff --git a/cpp/core/strategy.h b/cpp/core/strategy.h index 7f741572..f85d7d60 100644 --- a/cpp/core/strategy.h +++ b/cpp/core/strategy.h @@ -16,18 +16,7 @@ #include -#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 +#include "platform/public/core_config.h" namespace location { namespace nearby { diff --git a/cpp/platform/impl/windows/bluetooth_classic_socket.cc b/cpp/platform/impl/windows/bluetooth_classic_socket.cc index 786ad8b7..d18dc2fd 100644 --- a/cpp/platform/impl/windows/bluetooth_classic_socket.cc +++ b/cpp/platform/impl/windows/bluetooth_classic_socket.cc @@ -14,6 +14,7 @@ #include "platform/impl/windows/bluetooth_classic_socket.h" +#include "platform/base/logging.h" #include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h" namespace location { @@ -123,8 +124,11 @@ Exception BluetoothSocket::BluetoothOutputStream::Write(const ByteArray& data) { buffer.Length(data.size()); try { - winrt_stream_.WriteAsync(buffer).get(); - } catch (std::exception exception) { + auto hresult = winrt_stream_.WriteAsync(buffer).get(); + } catch (winrt::hresult_error const& ex) { + NEARBY_LOGS(ERROR) << __func__ << ": winrt exception: " << ex.code() << ": " + << winrt::to_string(ex.message()); + return {Exception::kFailed}; } diff --git a/cpp/platform/public/BUILD b/cpp/platform/public/BUILD index 3d36102d..78f8a998 100644 --- a/cpp/platform/public/BUILD +++ b/cpp/platform/public/BUILD @@ -29,6 +29,7 @@ cc_library( "cancelable_alarm.h", "cancellable_task.h", "condition_variable.h", + "core_config.h", "count_down_latch.h", "crypto.h", "file.h", @@ -75,6 +76,7 @@ cc_library( srcs = [ "ble.cc", "bluetooth_classic.cc", + "file.cc", "wifi_lan.cc", ], hdrs = [ diff --git a/cpp/platform/public/core_config.h b/cpp/platform/public/core_config.h new file mode 100644 index 00000000..3afa60fc --- /dev/null +++ b/cpp/platform/public/core_config.h @@ -0,0 +1,38 @@ +// Copyright 2020 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 CORE_CONFIG_H_ +#define CORE_CONFIG_H_ + +namespace location { +namespace nearby { +namespace connections { + +#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 connections +} // namespace nearby +} // namespace location + +#endif // CORE_CONFIG_H_ diff --git a/cpp/platform/public/file.cc b/cpp/platform/public/file.cc new file mode 100644 index 00000000..4ea9bd99 --- /dev/null +++ b/cpp/platform/public/file.cc @@ -0,0 +1,92 @@ +// Copyright 2020 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 "platform/public/file.h" + +namespace location { +namespace nearby { + +InputFile::InputFile(PayloadId payload_id, std::int64_t size) + : impl_(Platform::CreateInputFile(payload_id, size)), id_(payload_id) {} +InputFile::~InputFile() = default; +InputFile::InputFile(InputFile&&) noexcept = default; +InputFile& InputFile::operator=(InputFile&&) noexcept = default; + +// Reads up to size bytes and returns as a ByteArray object wrapped by +// ExceptionOr. +// Returns Exception::kIo on error, or end of file. +ExceptionOr InputFile::Read(std::int64_t size) { + return impl_->Read(size); +} + +// Returns a string that uniqely identifies this file. +std::string InputFile::GetFilePath() const { return impl_->GetFilePath(); } + +// Returns total size of this file in bytes. +std::int64_t InputFile::GetTotalSize() const { return impl_->GetTotalSize(); } + +ExceptionOr InputFile::Skip(size_t offset) { + return impl_->Skip(offset); +} + +// Disallows further reads from the file and frees system resources, +// associated with it. +Exception InputFile::Close() { return impl_->Close(); } + +// Returns a handle to the underlying input stream. +// +// Returned handle will remain valid even if InputFile is moved, for as long +// as original InputFile lifetime continues. +// Side effects of any non-const operation invoked for InputFile (such as +// Read, or Close will be observable through InputStream& handle, and vice +// versa. +InputStream& InputFile::GetInputStream() { return *impl_; } + +// Returns payload id of this file. The closest "file" equivalent is inode. +PayloadId InputFile::GetPayloadId() const { return id_; } + +OutputFile::OutputFile(PayloadId payload_id) + : impl_(Platform::CreateOutputFile(payload_id)), id_(payload_id) {} +OutputFile::~OutputFile() = default; +OutputFile::OutputFile(OutputFile&&) noexcept = default; +OutputFile& OutputFile::operator=(OutputFile&&) noexcept = default; + +// Writes all data from ByteArray object to the underlying stream. +// Returns Exception::kIo on error, Exception::kSuccess otherwise. +Exception OutputFile::Write(const ByteArray& data) { + return impl_->Write(data); +} + +// Ensures that all data written by previous calls to Write() is passed +// down to the applicable transport layer. +Exception OutputFile::Flush() { return impl_->Flush(); } + +// Disallows further writes to the file and frees system resources, +// associated with it. +Exception OutputFile::Close() { return impl_->Close(); } + +// Returns a handle to the underlying output stream. +// +// Returned handle will remain valid even if OutputFile is moved, for as long +// as original OutputFile lifetime continues. +// Side effects of any non-const operation invoked for OutputFile (such as +// Write, or Close will be observable through OutputStream& handle, and vice +// versa. +OutputStream& OutputFile::GetOutputStream() { return *impl_; } + +// Returns payload id of this file. The closest "file" equivalent is inode. +PayloadId OutputFile::GetPayloadId() const { return id_; } + +} // namespace nearby +} // namespace location diff --git a/cpp/platform/public/file.h b/cpp/platform/public/file.h index 15b70868..80e1ce58 100644 --- a/cpp/platform/public/file.h +++ b/cpp/platform/public/file.h @@ -26,35 +26,35 @@ #include "platform/base/exception.h" #include "platform/base/input_stream.h" #include "platform/base/output_stream.h" +#include "platform/public/core_config.h" namespace location { namespace nearby { -class InputFile final { +class DLL_API InputFile final { public: using Platform = api::ImplementationPlatform; - InputFile(PayloadId payload_id, std::int64_t size) - : impl_(Platform::CreateInputFile(payload_id, size)), id_(payload_id) {} - ~InputFile() = default; - InputFile(InputFile&&) = default; - InputFile& operator=(InputFile&&) = default; + InputFile(PayloadId payload_id, std::int64_t size); + ~InputFile(); + InputFile(InputFile&&) noexcept; + InputFile& operator=(InputFile&&) noexcept; // Reads up to size bytes and returns as a ByteArray object wrapped by // ExceptionOr. // Returns Exception::kIo on error, or end of file. - ExceptionOr Read(std::int64_t size) { return impl_->Read(size); } + ExceptionOr Read(std::int64_t size); // Returns a string that uniqely identifies this file. - std::string GetFilePath() const { return impl_->GetFilePath(); } + std::string GetFilePath() const; // Returns total size of this file in bytes. - std::int64_t GetTotalSize() const { return impl_->GetTotalSize(); } + std::int64_t GetTotalSize() const; - ExceptionOr Skip(size_t offset) { return impl_->Skip(offset); } + ExceptionOr Skip(size_t offset); // Disallows further reads from the file and frees system resources, // associated with it. - Exception Close() { return impl_->Close(); } + Exception Close(); // Returns a handle to the underlying input stream. // @@ -63,36 +63,35 @@ class InputFile final { // Side effects of any non-const operation invoked for InputFile (such as // Read, or Close will be observable through InputStream& handle, and vice // versa. - InputStream& GetInputStream() { return *impl_; } + InputStream& GetInputStream(); // Returns payload id of this file. The closest "file" equivalent is inode. - PayloadId GetPayloadId() const { return id_; } + PayloadId GetPayloadId() const; private: std::unique_ptr impl_; PayloadId id_; }; -class OutputFile final { +class DLL_API OutputFile final { public: using Platform = api::ImplementationPlatform; - explicit OutputFile(PayloadId payload_id) - : impl_(Platform::CreateOutputFile(payload_id)), id_(payload_id) {} - ~OutputFile() = default; - OutputFile(OutputFile&&) = default; - OutputFile& operator=(OutputFile&&) = default; + explicit OutputFile(PayloadId payload_id); + ~OutputFile(); + OutputFile(OutputFile&&) noexcept; + OutputFile& operator=(OutputFile&&) noexcept; // Writes all data from ByteArray object to the underlying stream. // Returns Exception::kIo on error, Exception::kSuccess otherwise. - Exception Write(const ByteArray& data) { return impl_->Write(data); } + Exception Write(const ByteArray& data); // Ensures that all data written by previous calls to Write() is passed // down to the applicable transport layer. - Exception Flush() { return impl_->Flush(); } + Exception Flush(); // Disallows further writes to the file and frees system resources, // associated with it. - Exception Close() { return impl_->Close(); } + Exception Close(); // Returns a handle to the underlying output stream. // @@ -101,10 +100,10 @@ class OutputFile final { // Side effects of any non-const operation invoked for OutputFile (such as // Write, or Close will be observable through OutputStream& handle, and vice // versa. - OutputStream& GetOutputStream() { return *impl_; } + OutputStream& GetOutputStream(); // Returns payload id of this file. The closest "file" equivalent is inode. - PayloadId GetPayloadId() const { return id_; } + PayloadId GetPayloadId() const; private: std::unique_ptr impl_; diff --git a/windows/core_adapter.cc b/windows/core_adapter.cc index 37c0939e..c2c8d154 100644 --- a/windows/core_adapter.cc +++ b/windows/core_adapter.cc @@ -14,6 +14,7 @@ #include "third_party/nearby_connections/windows/core_adapter.h" #include "absl/strings/str_format.h" +#include "core/core.h" namespace location { namespace nearby { @@ -71,7 +72,7 @@ DLL_API void InjectEndpoint(Core* pCore, char* service_id, } } -DLL_API void RequestConnection(Core* pCore, char* endpoint_id, +DLL_API void RequestConnection(Core* pCore, const char* endpoint_id, ConnectionRequestInfo info, ConnectionOptions options, ResultCallback callback) { @@ -80,7 +81,7 @@ DLL_API void RequestConnection(Core* pCore, char* endpoint_id, } } -DLL_API void AcceptConnection(Core* pCore, char* endpoint_id, +DLL_API void AcceptConnection(Core* pCore, const char* endpoint_id, PayloadListener listener, ResultCallback callback) { if (pCore) { @@ -88,7 +89,7 @@ DLL_API void AcceptConnection(Core* pCore, char* endpoint_id, } } -DLL_API void RejectConnection(Core* pCore, char* endpoint_id, +DLL_API void RejectConnection(Core* pCore, const char* endpoint_id, ResultCallback callback) { if (pCore) { pCore->RejectConnection(endpoint_id, callback); diff --git a/windows/core_adapter.h b/windows/core_adapter.h index 578ec470..ff1175b5 100644 --- a/windows/core_adapter.h +++ b/windows/core_adapter.h @@ -17,19 +17,16 @@ #include "absl/strings/string_view.h" #include "absl/types/span.h" -#include "core/core.h" -#include "core/internal/client_proxy.h" +// todo(jfcarroll) This cannot remain. It exposes stuff the client doesn't need. #include "core/internal/offline_service_controller.h" -#include "core/internal/service_controller.h" -#include "core/internal/service_controller_router.h" -#include "core/listeners.h" -#include "core/options.h" -#include "core/params.h" namespace location { namespace nearby { namespace connections { +class Core; +class ServiceControllerRouter; + // Initizlizes a Core instance, providing the ServiceController factory from // app side. If no factory is provided, it will initialize a new // factory creating OffilineServiceController. @@ -145,7 +142,7 @@ DLL_API 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_API void __stdcall RequestConnection(Core* pCore, char* endpoint_id, +DLL_API void __stdcall RequestConnection(Core* pCore, const char* endpoint_id, ConnectionRequestInfo info, ConnectionOptions options, ResultCallback callback); @@ -162,7 +159,7 @@ DLL_API void __stdcall RequestConnection(Core* pCore, char* endpoint_id, // 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_API void __stdcall AcceptConnection(Core* pCore, char* endpoint_id, +DLL_API void __stdcall AcceptConnection(Core* pCore, const char* endpoint_id, PayloadListener listener, ResultCallback callback); @@ -176,7 +173,7 @@ DLL_API void __stdcall AcceptConnection(Core* pCore, 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_API void __stdcall RejectConnection(Core* pCore, char* endpoint_id, +DLL_API void __stdcall RejectConnection(Core* pCore, const char* endpoint_id, ResultCallback callback); // Sends a Payload to a remote endpoint. Payloads can only be sent to remote