Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci-cd-multi-platforms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
name: "Windows MSVC x64",
os: windows-latest,
shell: "powershell",
generator: "Visual Studio 17 2022",
generator: "Visual Studio 18 2026",
arch: "x64",
cc: "cl",
cxx: "cl",
Expand All @@ -40,7 +40,7 @@ jobs:
name: "Windows MSVC x86",
os: windows-latest,
shell: "powershell",
generator: "Visual Studio 17 2022",
generator: "Visual Studio 18 2026",
arch: "Win32",
cc: "cl",
cxx: "cl",
Expand Down
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,9 @@ target_compile_options(${TARGET_NAME} PUBLIC

# setup release build options
if (CMAKE_BUILD_TYPE STREQUAL "Release")
if (NOT MINGW AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if (NOT MINGW AND
(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))

target_compile_options(${TARGET_NAME} PUBLIC
-ffast-math
Expand Down
12 changes: 7 additions & 5 deletions aether/ae_actions/ping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@
*/

#include "aether/ae_actions/ping.h"
#if AE_ENABLE_PING

#include <optional>
# include <optional>

#include "aether/channels/channel.h"
#include "aether/server_connections/client_server_connection.h"
#include "aether/work_cloud_api/work_server_api/authorized_api.h"
# include "aether/channels/channel.h"
# include "aether/server_connections/client_server_connection.h"
# include "aether/work_cloud_api/work_server_api/authorized_api.h"

#include "aether/ae_actions/ae_actions_tele.h"
# include "aether/ae_actions/ae_actions_tele.h"

namespace ae {
Ping::Ping(AeContext const& ae_context, Ptr<Channel> const& channel,
Expand Down Expand Up @@ -125,3 +126,4 @@ void Ping::PingResponseTimeout(RequestId request_id) {
}

} // namespace ae
#endif // AE_ENABLE_PING
28 changes: 15 additions & 13 deletions aether/ae_actions/ping.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,26 @@
#ifndef AETHER_AE_ACTIONS_PING_H_
#define AETHER_AE_ACTIONS_PING_H_

#include <cstdint>
#include <optional>
#include "aether/config.h"

#include "aether/warning_disable.h"
#if AE_ENABLE_PING

# include <cstdint>
# include <optional>

# include "aether/warning_disable.h"

DISABLE_WARNING_PUSH()
IGNORE_IMPLICIT_CONVERSION()
#include <etl/circular_buffer.h>
# include <etl/circular_buffer.h>
DISABLE_WARNING_POP()

#include "aether/common.h"
#include "aether/ptr/ptr.h"
#include "aether/ae_context.h"
#include "aether/ptr/ptr_view.h"
#include "aether/events/events.h"
#include "aether/api_protocol/request_id.h"
#include "aether/events/event_subscription.h"
#include "aether/events/multi_subscription.h"
# include "aether/ptr/ptr.h"
# include "aether/ae_context.h"
# include "aether/ptr/ptr_view.h"
# include "aether/events/events.h"
# include "aether/api_protocol/request_id.h"
# include "aether/events/multi_subscription.h"

namespace ae {
class Channel;
Expand Down Expand Up @@ -81,5 +83,5 @@ class Ping {
TaskSubscription timeout_sub_;
};
} // namespace ae

#endif // AE_ENABLE_PING
#endif // AETHER_AE_ACTIONS_PING_H_
2 changes: 1 addition & 1 deletion aether/ae_actions/time_sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ TimeSyncRequest::TimeSyncRequest(AeContext const& ae_context,
AE_TELED_ERROR("Time sync failed");
}
if (res && *res) {
AE_TELED_ERROR("Time sync succeeded");
AE_TELED_INFO("Time sync succeeded");
}
Finish();
});
Expand Down
39 changes: 20 additions & 19 deletions aether/channels/wifi_channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,28 +85,29 @@ ex::sender auto TransportConnect(std::unique_ptr<ByteIStream>&& stream) {
ex::set_error_t(int)>(
[s{std::move(stream)},
link_sub{Subscription{}}](auto& ctx) mutable noexcept {
// if already linked return stream
switch (s->stream_info().link_state) {
case LinkState::kLinked: {
ex::set_value(std::move(ctx.receiver), std::move(s));
return;
}
case LinkState::kLinkError: {
ex::set_error(std::move(ctx.receiver), 1);
return;
auto handle_link_state = [&]() noexcept {
link_sub.Reset(); // ensure subscribed only to one event
auto link_state = s->stream_info().link_state;
switch (link_state) {
case LinkState::kLinked: {
ex::set_value(std::move(ctx.receiver), std::move(s));
return true;
}
case LinkState::kLinkError: {
ex::set_error(std::move(ctx.receiver), 1);
return true;
}
default:
return false;
}
default:
break;
};

// if already linked return stream
if (handle_link_state()) {
return;
}
// wait till linked
link_sub = s->stream_update_event().Subscribe([&]() mutable noexcept {
link_sub.Reset();
if (s->stream_info().link_state == LinkState::kLinked) {
ex::set_value(std::move(ctx.receiver), std::move(s));
} else {
ex::set_error(std::move(ctx.receiver), 2);
}
});
link_sub = s->stream_update_event().Subscribe(handle_link_state);
});
}

Expand Down
5 changes: 5 additions & 0 deletions aether/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,11 @@
# define AE_DEFAULT_RESPONSE_TIMEOUT_MS 10000
#endif

// Is periodic ping messages enabled
#ifndef AE_ENABLE_PING
# define AE_ENABLE_PING 1
#endif

// Send ping interval, ms
#ifndef AE_PING_INTERVAL_MS
# define AE_PING_INTERVAL_MS AE_DEFAULT_RESPONSE_TIMEOUT_MS + 1000
Expand Down
45 changes: 22 additions & 23 deletions aether/server_connections/channel_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,44 +24,43 @@
#include "aether/tele/tele.h"

namespace ae {
ChannelConnection::ChannelConnection(AeContext const& ae_context,
Ptr<Channel> const& channel,
ConnectionStateCb&& connection_state_cb)
: ae_context_{ae_context},
connection_state_cb_{std::move(connection_state_cb)} {
BuildTransport(channel);
}
ChannelConnection::ChannelConnection(AeContext const& ae_context)
: ae_context_{ae_context} {}

ByteIStream* ChannelConnection::stream() const {
return transport_stream_.get();
}

void ChannelConnection::BuildTransport(Ptr<Channel> const& channel) {
void ChannelConnection::BuildTransport(
Ptr<Channel> const& channel, ConnectionStateCb&& connection_state_cb) {
transport_build_start_ = Now();
auto sender = channel->TransportBuilder();
transport_waiter_.emplace(
ae_context_,
std::move(sender) |
ex::with_timeout(ae_context_, channel->TransportBuildTimeout()),
[&, c_ = PtrView<Channel>{channel}](auto&& result) {
assert(!!result);
[&, c_ = PtrView<Channel>{channel},
cb_ = std::move(connection_state_cb)](auto&& result) {
// the result must exists
assert(!!result && "The result must exists");
if (result->IsOk()) {
UpdateTransportBuildTime(c_);
transport_stream_ = std::move(result->value());
assert(transport_stream_ && "Transport should be created");
connection_state_cb_(Ok<ByteIStream&>{*transport_stream_});
cb_(Ok<ByteIStream&>{*transport_stream_});
} else {
std::visit(
Override{[&](ex::TimeoutError) {
AE_TELED_ERROR("Transport build timeout");
connection_state_cb_(Error{-1});
},
[&](int e) {
AE_TELED_ERROR(
"Transport build failed with error code: {}", e);
connection_state_cb_(Error{e});
}},
result->error());
std::visit(Override{
[&](ex::TimeoutError) {
AE_TELED_ERROR("Transport build timeout");
cb_(Error{-1});
},
[&](int e) {
AE_TELED_ERROR(
"Transport build failed with error code: {}", e);
cb_(Error{e});
},
},
result->error());
}
transport_waiter_.reset();
});
Expand All @@ -72,7 +71,7 @@ void ChannelConnection::UpdateTransportBuildTime(PtrView<Channel> const& c) {
assert(channel && "Channel not loaded");
auto build_time =
std::chrono::duration_cast<Duration>(Now() - transport_build_start_);
AE_TELED_ERROR("Transport built for {:%S}", build_time);
AE_TELED_INFO("Transport built for {:%S}", build_time);
channel->channel_statistics().AddConnectionTime(build_time);
}

Expand Down
7 changes: 3 additions & 4 deletions aether/server_connections/channel_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,18 @@ class ChannelConnection {
using ConnectionStateCb =
SmallFunction<void(Result<ByteIStream&, int> result)>;

ChannelConnection(AeContext const& ae_context, Ptr<Channel> const& channel,
ConnectionStateCb&& connection_state_cb);
explicit ChannelConnection(AeContext const& ae_context);

AE_CLASS_NO_COPY_MOVE(ChannelConnection)

void BuildTransport(Ptr<Channel> const& channel,
ConnectionStateCb&& connection_state_cb);
ByteIStream* stream() const;

private:
void BuildTransport(Ptr<Channel> const& channel);
void UpdateTransportBuildTime(PtrView<Channel> const& c);

AeContext ae_context_;
ConnectionStateCb connection_state_cb_;

std::optional<
ex::AnyWaiter<ex::set_value_t(std::unique_ptr<ByteIStream>),
Expand Down
2 changes: 2 additions & 0 deletions aether/server_connections/client_server_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ void ClientServerConnection::ChannelChanged() {
AE_TELED_DEBUG("Channel is updated, make new ping");

auto make_ping = [&] {
#if AE_ENABLE_PING
auto& server_conn = server_connection_.server_connection;
auto channel = server_conn.current_channel();
// Create new ping if channel is updated
Expand All @@ -221,6 +222,7 @@ void ClientServerConnection::ChannelChanged() {
AE_TELED_ERROR("Ping failed");
server_connection_.Restream();
});
#endif
};

if (server_connection_.stream_info().link_state == LinkState::kLinked) {
Expand Down
2 changes: 2 additions & 0 deletions aether/server_connections/client_server_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ class ClientServerConnection {
client_server_connection_internal ::BufferedServerConnection
server_connection_;

#if AE_ENABLE_PING
std::optional<Ping> ping_;
#endif

Subscription ping_sub_;
Subscription wait_connection_sub_;
Expand Down
18 changes: 8 additions & 10 deletions aether/server_connections/server_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ ServerConnection::ServerConnection(AeContext const& ae_context,
}

WriteAction& ServerConnection::Write(DataBuffer&& in_data) {
assert(channel_connection_.has_value() &&
"channel connection is not available");
assert((top_channel_ != nullptr) && "channel connection is not available");

auto* stream = channel_connection_->stream();
auto* stream = top_channel_->connection.stream();
assert((stream != nullptr) && "channel stream is not available");

return stream->Write(std::move(in_data));
Expand Down Expand Up @@ -112,18 +111,17 @@ void ServerConnection::InitChannels() {

channels_.reserve(channels.size());
for (auto const& c : channels) {
channels_.emplace_back(ChannelEntry{c, false});
channels_.emplace_back(std::make_unique<ChannelEntry>(ae_context_, c));
}
}

ServerConnection::ChannelEntry* ServerConnection::TopChannel() {
auto it =
std::find_if(std::begin(channels_), std::end(channels_),
[](ChannelEntry const& entry) { return !entry.failed; });
auto it = std::find_if(std::begin(channels_), std::end(channels_),
[](auto const& entry) { return !entry->failed; });
if (it == std::end(channels_)) {
return nullptr;
}
return &(*it);
return it->get();
}

void ServerConnection::SelectChannel() {
Expand All @@ -150,7 +148,7 @@ void ServerConnection::SelectChannel() {
stream_info_.link_state = LinkState::kUnlinked;
stream_info_.is_writable = false;

channel_connection_.emplace(ae_context_, channel, [this](auto&& res) {
top_channel_->connection.BuildTransport(channel, [this](auto&& res) {
if (res) {
ChannelUpdated(res.value());
} else {
Expand Down Expand Up @@ -187,7 +185,7 @@ void ServerConnection::ServerError() {
AE_TELED_ERROR("Server error");
channel_stream_update_sub_.Reset();
channel_stream_out_data_sub_.Reset();
channel_connection_.reset();
// TODO: should we also reset connection.stream()

stream_info_.link_state = LinkState::kLinkError;
stream_info_.is_writable = false;
Expand Down
6 changes: 4 additions & 2 deletions aether/server_connections/server_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ class Channel;

class ServerConnection final : public ByteIStream {
struct ChannelEntry {
ChannelEntry(AeContext const& ae_context, PtrView<Channel> const& c): channel{c}, connection{ae_context} {}

PtrView<Channel> channel;
ChannelConnection connection;
bool failed = false;
};

Expand Down Expand Up @@ -72,8 +75,7 @@ class ServerConnection final : public ByteIStream {

bool full_connected_;
ChannelEntry* top_channel_;
std::vector<ChannelEntry> channels_;
std::optional<ChannelConnection> channel_connection_;
std::vector<std::unique_ptr<ChannelEntry>> channels_;

StreamInfo stream_info_;
OutDataEvent out_data_event_;
Expand Down
1 change: 1 addition & 0 deletions aether/tele/env/compilation_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ constexpr inline auto _compile_options_list = std::array{
_OPTION(AE_SUPPORT_GATEWAY),
_OPTION(AE_SUPPORT_REGISTRATION),
_OPTION(AE_SUPPORT_REGISTRATION_DYNAMIC_IP),
_OPTION(AE_ENABLE_PING),
_OPTION(AE_PING_INTERVAL_MS),
_OPTION(AE_BCRYPT_CRC32),
_OPTION(AE_POW),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,13 @@ void LwipCBTcpSocket::Disconnect() {
}

LOCK_TCPIP_CORE();
ae_defer[]() { UNLOCK_TCPIP_CORE(); };
// set null so because we are not interested in events anymore
tcp_arg(pcb_, nullptr);
tcp_err(pcb_, nullptr);
tcp_recv(pcb_, nullptr);

tcp_close(pcb_);
UNLOCK_TCPIP_CORE();
pcb_ = nullptr;
}

Expand Down
Loading
Loading