diff --git a/cpp/platform/impl/windows/bluetooth_classic_socket.cc b/cpp/platform/impl/windows/bluetooth_classic_socket.cc index dbc8ab7e..2a4613bf 100644 --- a/cpp/platform/impl/windows/bluetooth_classic_socket.cc +++ b/cpp/platform/impl/windows/bluetooth_classic_socket.cc @@ -19,6 +19,14 @@ namespace location { namespace nearby { namespace windows { +BluetoothSocket::BluetoothSocket() { + windows_socket_ = IStreamSocket(); + input_stream_ = + std::make_unique(windows_socket_.InputStream()); + output_stream_ = + std::make_unique(windows_socket_.OutputStream()); +} + BluetoothSocket::~BluetoothSocket() {} // NOTE: @@ -26,19 +34,12 @@ BluetoothSocket::~BluetoothSocket() {} // called for a not-connected BluetoothSocket, i.e. any object that is not // returned by BluetoothClassicMedium::ConnectToService() for client side or // BluetoothServerSocket::Accept() for server side of connection. - -BluetoothSocket::BluetoothSocket() { windows_socket_ = StreamSocket(); } - // Returns the InputStream of this connected BluetoothSocket. -// TODO(b/184975123): replace with real implementation. -InputStream& BluetoothSocket::GetInputStream() { - return BluetoothSocket::fake_input_stream_; -} +InputStream& BluetoothSocket::GetInputStream() { return *input_stream_.get(); } // Returns the OutputStream of this connected BluetoothSocket. -// TODO(b/184975123): replace with real implementation. OutputStream& BluetoothSocket::GetOutputStream() { - return BluetoothSocket::fake_output_stream_; + return *output_stream_.get(); } // Closes both input and output streams, marks Socket as closed. @@ -63,6 +64,73 @@ winrt::Windows::Foundation::IAsyncAction BluetoothSocket::ConnectAsync( connectionServiceName); } +BluetoothSocket::BluetoothInputStream::BluetoothInputStream( + IInputStream stream) { + winrt_stream_ = stream; +} + +ExceptionOr BluetoothSocket::BluetoothInputStream::Read( + std::int64_t size) { + Buffer buffer = Buffer(size); + + winrt_stream_.ReadAsync(buffer, size, InputStreamOptions::None); + + DataReader dataReader = DataReader::FromBuffer(buffer); + + ByteArray data((char*)buffer.data(), buffer.Length()); + + return ExceptionOr(data); +} + +Exception BluetoothSocket::BluetoothInputStream::Close() { + try { + winrt_stream_.Close(); + } catch (std::exception exception) { + return {Exception::kFailed}; + } + + return {Exception::kSuccess}; +} + +BluetoothSocket::BluetoothOutputStream::BluetoothOutputStream( + IOutputStream stream) { + winrt_stream_ = stream; +} + +Exception BluetoothSocket::BluetoothOutputStream::Write(const ByteArray& data) { + Buffer buffer = Buffer(data.size()); + + std::memcpy(buffer.data(), data.data(), data.size()); + + try { + winrt_stream_.WriteAsync(buffer); + } catch (std::exception exception) { + return {Exception::kFailed}; + } + + return {Exception::kSuccess}; +} + +Exception BluetoothSocket::BluetoothOutputStream::Flush() { + try { + winrt_stream_.FlushAsync().get(); + } catch (std::exception exception) { + return {Exception::kFailed}; + } + + return {Exception::kSuccess}; +} + +Exception BluetoothSocket::BluetoothOutputStream::Close() { + try { + winrt_stream_.Close(); + } catch (std::exception exception) { + return {Exception::kFailed}; + } + + return {Exception::kSuccess}; +} + } // namespace windows } // namespace nearby } // namespace location diff --git a/cpp/platform/impl/windows/bluetooth_classic_socket.h b/cpp/platform/impl/windows/bluetooth_classic_socket.h index 5c8d9ac0..34421153 100644 --- a/cpp/platform/impl/windows/bluetooth_classic_socket.h +++ b/cpp/platform/impl/windows/bluetooth_classic_socket.h @@ -15,12 +15,11 @@ #ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_ #define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_SOCKET_H_ +#include "platform/api/bluetooth_classic.h" #include "platform/impl/windows/generated/winrt/Windows.Foundation.h" #include "platform/impl/windows/generated/winrt/Windows.Networking.Sockets.h" #include "platform/impl/windows/generated/winrt/Windows.Storage.Streams.h" -#include "platform/api/bluetooth_classic.h" - namespace location { namespace nearby { namespace windows { @@ -31,12 +30,37 @@ using winrt::Windows::Networking::HostName; // Supports network communication using a stream socket over Bluetooth RFCOMM. // https://docs.microsoft.com/en-us/uwp/api/windows.networking.sockets.streamsocket?view=winrt-20348 +using winrt::Windows::Networking::Sockets::IStreamSocket; using winrt::Windows::Networking::Sockets::StreamSocket; +// Provides a default implementation of the IBuffer interface and its related +// interfaces. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.buffer?view=winrt-20348 +using winrt::Windows::Storage::Streams::Buffer; + +// Represents a sequential stream of bytes to be read. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.iinputstream?view=winrt-20348 +using winrt::Windows::Storage::Streams::IInputStream; + +// Represents a sequential stream of bytes to be written. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.ioutputstream?view=winrt-20348 +using winrt::Windows::Storage::Streams::IOutputStream; + +// Specifies the read options for an input stream. +// This enumeration has a FlagsAttribute attribute that allows a bitwise +// combination of its member values. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.inputstreamoptions?view=winrt-20348 +using winrt::Windows::Storage::Streams::InputStreamOptions; + +// Reads data from an input stream. +// https://docs.microsoft.com/en-us/uwp/api/windows.storage.streams.datareader?view=winrt-20348 +using winrt::Windows::Storage::Streams::DataReader; + // https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html. class BluetoothSocket : public api::BluetoothSocket { public: BluetoothSocket(); + // TODO(b/184975123): replace with real implementation. ~BluetoothSocket() override; @@ -47,11 +71,9 @@ class BluetoothSocket : public api::BluetoothSocket { // BluetoothServerSocket::Accept() for server side of connection. // Returns the InputStream of this connected BluetoothSocket. - // TODO(b/184975123): replace with real implementation. InputStream& GetInputStream() override; // Returns the OutputStream of this connected BluetoothSocket. - // TODO(b/184975123): replace with real implementation. OutputStream& GetOutputStream() override; // Closes both input and output streams, marks Socket as closed. @@ -63,7 +85,6 @@ class BluetoothSocket : public api::BluetoothSocket { // https://developer.android.com/reference/android/bluetooth/BluetoothSocket.html#getRemoteDevice() // Returns valid BluetoothDevice pointer if there is a connection, and // nullptr otherwise. - // TODO(b/184975123): replace with real implementation. api::BluetoothDevice* GetRemoteDevice() override; // Connect asynchronously to the target remote device @@ -71,28 +92,36 @@ class BluetoothSocket : public api::BluetoothSocket { HostName connectionHostName, winrt::hstring connectionServiceName); private: - class FakeInputStream : public InputStream { + class BluetoothInputStream : public InputStream { public: - ~FakeInputStream() override = default; - ExceptionOr Read(std::int64_t size) override { - return ExceptionOr(Exception::kFailed); - } - Exception Close() override { return {.value = Exception::kFailed}; } + BluetoothInputStream(IInputStream stream); + ~BluetoothInputStream() override = default; + + ExceptionOr Read(std::int64_t size) override; + Exception Close() override; + + private: + IInputStream winrt_stream_; }; - class FakeOutputStream : public OutputStream { + + class BluetoothOutputStream : public OutputStream { public: - ~FakeOutputStream() override = default; + BluetoothOutputStream(IOutputStream stream); + ~BluetoothOutputStream() override = default; - Exception Write(const ByteArray& data) override { - return {.value = Exception::kFailed}; - } - Exception Flush() override { return {.value = Exception::kFailed}; } - Exception Close() override { return {.value = Exception::kFailed}; } + Exception Write(const ByteArray& data) override; + Exception Flush() override; + + Exception Close() override; + + private: + IOutputStream winrt_stream_; }; - FakeInputStream fake_input_stream_; - FakeOutputStream fake_output_stream_; - StreamSocket windows_socket_; + std::unique_ptr input_stream_; + std::unique_ptr output_stream_; + + IStreamSocket windows_socket_; }; } // namespace windows