mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 22:56:12 -04:00
138 lines
5.1 KiB
C++
138 lines
5.1 KiB
C++
// 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_INTERNAL_BASE_ENDPOINT_CHANNEL_H_
|
|
#define CORE_INTERNAL_BASE_ENDPOINT_CHANNEL_H_
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "securegcm/d2d_connection_context_v1.h"
|
|
#include "absl/base/thread_annotations.h"
|
|
#include "core/internal/endpoint_channel.h"
|
|
#include "platform/base/byte_array.h"
|
|
#include "platform/base/input_stream.h"
|
|
#include "platform/base/output_stream.h"
|
|
#include "platform/public/atomic_reference.h"
|
|
#include "platform/public/condition_variable.h"
|
|
#include "platform/public/mutex.h"
|
|
#include "platform/public/system_clock.h"
|
|
|
|
namespace location {
|
|
namespace nearby {
|
|
namespace connections {
|
|
|
|
class BaseEndpointChannel : public EndpointChannel {
|
|
public:
|
|
BaseEndpointChannel(const std::string& channel_name, InputStream* reader,
|
|
OutputStream* writer);
|
|
~BaseEndpointChannel() override = default;
|
|
|
|
ExceptionOr<ByteArray> Read()
|
|
ABSL_LOCKS_EXCLUDED(reader_mutex_, crypto_mutex_,
|
|
last_read_mutex_) override;
|
|
|
|
Exception Write(const ByteArray& data)
|
|
ABSL_LOCKS_EXCLUDED(writer_mutex_, crypto_mutex_) override;
|
|
|
|
// Closes this EndpointChannel, without tracking the closure in analytics.
|
|
void Close() ABSL_LOCKS_EXCLUDED(is_paused_mutex_) override;
|
|
|
|
// Closes this EndpointChannel and records the closure with the given reason.
|
|
void Close(proto::connections::DisconnectionReason reason) override;
|
|
|
|
// Returns a one-word type descriptor for the concrete EndpointChannel
|
|
// implementation that can be used in log messages; eg: BLUETOOTH, BLE,
|
|
// WIFI.
|
|
std::string GetType() const override;
|
|
|
|
// Returns the name of the EndpointChannel.
|
|
std::string GetName() const override;
|
|
|
|
// Returns the maximum supported transmit packet size(MTU) for the underlying
|
|
// transport.
|
|
int GetMaxTransmitPacketSize() const override;
|
|
|
|
// Enables encryption on the EndpointChannel.
|
|
// Should be called after connection is accepted by both parties, and
|
|
// before entering data phase, where Payloads may be exchanged.
|
|
void EnableEncryption(std::shared_ptr<EncryptionContext> context) override;
|
|
|
|
// Disables encryption on the EndpointChannel.
|
|
void DisableEncryption() override;
|
|
|
|
// True if the EndpointChannel is currently pausing all writes.
|
|
bool IsPaused() const ABSL_LOCKS_EXCLUDED(is_paused_mutex_) override;
|
|
|
|
// Pauses all writes on this EndpointChannel until resume() is called.
|
|
void Pause() ABSL_LOCKS_EXCLUDED(is_paused_mutex_) override;
|
|
|
|
// Resumes any writes on this EndpointChannel that were suspended when pause()
|
|
// was called.
|
|
void Resume() ABSL_LOCKS_EXCLUDED(is_paused_mutex_) override;
|
|
|
|
// Returns the timestamp (returned by ElapsedRealtime) of the last read from
|
|
// this endpoint, or -1 if no reads have occurred.
|
|
absl::Time GetLastReadTimestamp() const
|
|
ABSL_LOCKS_EXCLUDED(last_read_mutex_) override;
|
|
|
|
protected:
|
|
virtual void CloseImpl() = 0;
|
|
|
|
private:
|
|
// Used to sanity check that our frame sizes are reasonable.
|
|
static constexpr std::int32_t kMaxAllowedReadBytes = 1048576; // 1MB
|
|
|
|
// The default maximum transmit unit/packet size.
|
|
static constexpr int kDefaultMaxTransmitPacketSize = 65536; // 64 KB
|
|
|
|
bool IsEncryptionEnabledLocked() const
|
|
ABSL_EXCLUSIVE_LOCKS_REQUIRED(crypto_mutex_);
|
|
void UnblockPausedWriter() ABSL_EXCLUSIVE_LOCKS_REQUIRED(is_paused_mutex_);
|
|
void BlockUntilUnpaused() ABSL_EXCLUSIVE_LOCKS_REQUIRED(is_paused_mutex_);
|
|
void CloseIo() ABSL_NO_THREAD_SAFETY_ANALYSIS;
|
|
|
|
// We need a separate mutex to pritect read timestamp, because if a read
|
|
// blocks on IO, we don't want timestamp read access to block too.
|
|
mutable Mutex last_read_mutex_;
|
|
absl::Time last_read_timestamp_ ABSL_GUARDED_BY(last_read_mutex_) =
|
|
absl::InfinitePast();
|
|
const std::string channel_name_;
|
|
|
|
// The reader and writer are synchronized independently since we can't have
|
|
// writes waiting on reads that might potentially block forever.
|
|
Mutex reader_mutex_;
|
|
InputStream* reader_ ABSL_PT_GUARDED_BY(reader_mutex_);
|
|
|
|
Mutex writer_mutex_;
|
|
OutputStream* writer_ ABSL_PT_GUARDED_BY(writer_mutex_);
|
|
|
|
// An encryptor/decryptor. May be null.
|
|
mutable Mutex crypto_mutex_;
|
|
std::shared_ptr<EncryptionContext> crypto_context_
|
|
ABSL_GUARDED_BY(crypto_mutex_) ABSL_PT_GUARDED_BY(crypto_mutex_);
|
|
|
|
mutable Mutex is_paused_mutex_;
|
|
ConditionVariable is_paused_cond_{&is_paused_mutex_};
|
|
// If true, writes should block until this has been set to false.
|
|
bool is_paused_ ABSL_GUARDED_BY(is_paused_mutex_) = false;
|
|
};
|
|
|
|
} // namespace connections
|
|
} // namespace nearby
|
|
} // namespace location
|
|
|
|
#endif // CORE_INTERNAL_BASE_ENDPOINT_CHANNEL_H_
|