From 2aaaa03a17b44e853a28b9c7eec3b6299b226ab0 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Tue, 25 Nov 2025 17:49:05 +0300 Subject: [PATCH 01/32] Updating lora modules. --- aether/config.h | 6 +- aether/lora_modules/dx_smart_lr02_lm.cpp | 86 +++------------- aether/lora_modules/dx_smart_lr02_lm.h | 21 ++-- aether/lora_modules/ebyte_e22_lm.cpp | 4 + aether/lora_modules/ebyte_e22_lm.h | 6 +- aether/lora_modules/ilora_module_driver.h | 2 + .../lora_modules/lora_module_transport.cpp | 98 ++++--------------- .../lora_modules/lora_module_transport.h | 28 +++--- aether/types/address.h | 1 + 9 files changed, 60 insertions(+), 192 deletions(-) diff --git a/aether/config.h b/aether/config.h index 38c2f4f9..cd11963f 100644 --- a/aether/config.h +++ b/aether/config.h @@ -116,15 +116,15 @@ * \brief Is lora protocol supported. */ #ifndef AE_SUPPORT_LORA -# define AE_SUPPORT_LORA 0 +# define AE_SUPPORT_LORA 1 #endif #ifndef AE_ENABLE_EBYTE_E22_LM -# define AE_ENABLE_EBYTE_E22_LM 0 +# define AE_ENABLE_EBYTE_E22_LM 1 #endif #ifndef AE_ENABLE_DX_SMART_LR02_LM -# define AE_ENABLE_DX_SMART_LR02_LM 0 +# define AE_ENABLE_DX_SMART_LR02_LM 1 #endif // Registration functionality can be stripped-out for pre-registered clients. diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index ca6d64e1..df00d01f 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -38,57 +38,17 @@ static const AtRequest::Wait kWaitEntryAt{"Entry AT", kOneSecond}; static const AtRequest::Wait kWaitExitAt{"Exit AT", kOneSecond}; static const AtRequest::Wait kWaitPowerOn{"Power on", kOneSecond}; -class DxSmartLr02TcpOpenNetwork final - : public Action { +class DxSmartLr02LoraOpenNetwork final + : public Action { public: - DxSmartLr02TcpOpenNetwork(ActionContext action_context, + DxSmartLr02LoraOpenNetwork(ActionContext action_context, DxSmartLr02LoraModule& /* lora_module */, std::string host, std::uint16_t port) : Action{action_context}, action_context_{action_context}, host_{std::move(host)}, port_{port} { - AE_TELED_DEBUG("Open tcp connection for {}:{}", host_, port_); - } - - UpdateStatus Update() const { - if (success_) { - return UpdateStatus::Result(); - } - if (error_) { - return UpdateStatus::Error(); - } - if (stop_) { - return UpdateStatus::Stop(); - } - return {}; - } - - ConnectionLoraIndex connection_index() const { return connection_index_; } - - private: - ActionContext action_context_; - std::string host_; - std::uint16_t port_; - ActionPtr operation_pipeline_; - Subscription operation_sub_; - ConnectionLoraIndex connection_index_ = kInvalidConnectionLoraIndex; - bool success_{}; - bool error_{}; - bool stop_{}; -}; - -class DxSmartLr02UdpOpenNetwork final - : public Action { - public: - DxSmartLr02UdpOpenNetwork(ActionContext action_context, - DxSmartLr02LoraModule& /* lora_module */, - std::string host, std::uint16_t port) - : Action{action_context}, - action_context_{action_context}, - host_{std::move(host)}, - port_{port} { - AE_TELED_DEBUG("Open UDP connection for {}:{}", host_, port_); + AE_TELED_DEBUG("Open lora connection for {}:{}", host_, port_); } UpdateStatus Update() const { @@ -209,11 +169,8 @@ DxSmartLr02LoraModule::OpenNetwork(ae::Protocol protocol, operation_queue_->Push(Stage([this, open_network_operation, protocol, host{host}, port]() -> ActionPtr { - if (protocol == Protocol::kTcp) { - return OpenTcpConnection(open_network_operation, host, port); - } - if (protocol == Protocol::kUdp) { - return OpenUdpConnection(open_network_operation, host, port); + if (protocol == Protocol::kLora) { + return OpenLoraConnection(open_network_operation, host, port); } return {}; })); @@ -340,6 +297,10 @@ DxSmartLr02LoraModule::PowerOff() { return {}; } +std::uint16_t DxSmartLr02LoraModule::GetMtu(){ + return kLoraModuleMTU; +} + ActionPtr DxSmartLr02LoraModule::SetLoraModuleAddress(std::uint16_t const& address) { auto lora_module_operation = ActionPtr{action_context_}; @@ -486,37 +447,14 @@ void DxSmartLr02LoraModule::Init() { })); } -ActionPtr DxSmartLr02LoraModule::OpenTcpConnection( - ActionPtr open_network_operation, - std::string const& host, std::uint16_t port) { - return MakeActionPtr( - action_context_, - Stage([this, open_network_operation{std::move(open_network_operation)}, - host{host}, port]() { - auto open_operation = ActionPtr{ - action_context_, *this, host, port}; - - open_operation->StatusEvent().Subscribe(ActionHandler{ - OnResult{[open_network_operation](auto const& action) { - open_network_operation->SetValue(action.connection_index()); - }}, - OnError{[open_network_operation]() { - open_network_operation->Reject(); - }}, - }); - - return open_operation; - })); -} - -ActionPtr DxSmartLr02LoraModule::OpenUdpConnection( +ActionPtr DxSmartLr02LoraModule::OpenLoraConnection( ActionPtr open_network_operation, std::string const& host, std::uint16_t port) { return MakeActionPtr( action_context_, Stage([this, open_network_operation{std::move(open_network_operation)}, host{host}, port]() { - auto open_operation = ActionPtr{ + auto open_operation = ActionPtr{ action_context_, *this, host, port}; open_operation->StatusEvent().Subscribe(ActionHandler{ diff --git a/aether/lora_modules/dx_smart_lr02_lm.h b/aether/lora_modules/dx_smart_lr02_lm.h index 01ae3aa6..fc4d8105 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.h +++ b/aether/lora_modules/dx_smart_lr02_lm.h @@ -33,8 +33,7 @@ # include "aether/lora_modules/ilora_module_driver.h" namespace ae { -class DxSmartLr02TcpOpenNetwork; -class DxSmartLr02UdpOpenNetwork; +class DxSmartLr02LoraOpenNetwork; static const std::map baud_rate_commands_lr02 = { {kBaudRate::kBaudRate1200, "AT+BAUD1"}, @@ -48,9 +47,8 @@ static const std::map baud_rate_commands_lr02 = { {kBaudRate::kBaudRate128000, "AT+BAUD9"}}; class DxSmartLr02LoraModule final : public ILoraModuleDriver { - friend class DxSmartLr02TcpOpenNetwork; - friend class DxSmartLr02UdpOpenNetwork; - static constexpr std::uint16_t kLoraModuleMTU{400}; + friend class DxSmartLr02LoraOpenNetwork; + static constexpr std::uint16_t kLoraModuleMTU{200}; public: explicit DxSmartLr02LoraModule(ActionContext action_context, @@ -67,17 +65,16 @@ class DxSmartLr02LoraModule final : public ILoraModuleDriver { ConnectionLoraIndex connect_index) override; ActionPtr WritePacket(ConnectionLoraIndex connect_index, ae::DataBuffer const& data) override; - DataEvent::Subscriber data_event() override; - ActionPtr SetPowerSaveParam( LoraPowerSaveParam const& psp) override; - ActionPtr PowerOff() override; + ActionPtr PowerOff() override; + std::uint16_t GetMtu() override; + ActionPtr SetLoraModuleAddress( std::uint16_t const& address); // Module address ActionPtr SetLoraModuleChannel( std::uint8_t const& channel); // Module channel - ActionPtr SetLoraModuleCRCCheck( kLoraModuleCRCCheck const& crc_check); // Module crc check ActionPtr SetLoraModuleIQSignalInversion( @@ -87,11 +84,7 @@ class DxSmartLr02LoraModule final : public ILoraModuleDriver { private: void Init(); - ActionPtr OpenTcpConnection( - ActionPtr open_network_operation, - std::string const& host, std::uint16_t port); - - ActionPtr OpenUdpConnection( + ActionPtr OpenLoraConnection( ActionPtr open_network_operation, std::string const& host, std::uint16_t port); diff --git a/aether/lora_modules/ebyte_e22_lm.cpp b/aether/lora_modules/ebyte_e22_lm.cpp index c260cdb4..571f1c27 100644 --- a/aether/lora_modules/ebyte_e22_lm.cpp +++ b/aether/lora_modules/ebyte_e22_lm.cpp @@ -108,6 +108,10 @@ EbyteE22LoraModule::PowerOff() { return {}; } +std::uint16_t EbyteE22LoraModule::GetMtu(){ + return kLoraModuleMTU; +} + ActionPtr EbyteE22LoraModule::SetLoraModuleAddress(std::uint16_t const& /*address*/) { return {}; diff --git a/aether/lora_modules/ebyte_e22_lm.h b/aether/lora_modules/ebyte_e22_lm.h index 2bcad4fc..28fa59a6 100644 --- a/aether/lora_modules/ebyte_e22_lm.h +++ b/aether/lora_modules/ebyte_e22_lm.h @@ -54,12 +54,12 @@ class EbyteE22LoraModule final : public ILoraModuleDriver { ActionPtr WritePacket( ae::ConnectionLoraIndex connect_index, ae::DataBuffer const& data) override; - DataEvent::Subscriber data_event() override; - ActionPtr SetPowerSaveParam( LoraPowerSaveParam const& psp) override; - ActionPtr PowerOff() override; + ActionPtr PowerOff() override; + std::uint16_t GetMtu() override; + ActionPtr SetLoraModuleAddress( std::uint16_t const& address); // Module address ActionPtr SetLoraModuleChannel( diff --git a/aether/lora_modules/ilora_module_driver.h b/aether/lora_modules/ilora_module_driver.h index dccff6e4..4a03091f 100644 --- a/aether/lora_modules/ilora_module_driver.h +++ b/aether/lora_modules/ilora_module_driver.h @@ -57,6 +57,8 @@ class ILoraModuleDriver { virtual ActionPtr SetPowerSaveParam( LoraPowerSaveParam const& psp) = 0; virtual ActionPtr PowerOff() = 0; + + virtual std::uint16_t GetMtu() = 0; }; } /* namespace ae */ diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index af87ae77..683f8c8c 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -25,21 +25,21 @@ # include "aether/transport/transport_tele.h" namespace ae { -static constexpr auto kMaxPacketSize = 400; - LoraModuleTransport::LoraModuleSend::LoraModuleSend( ActionContext action_context, LoraModuleTransport& transport, DataBuffer data) : SocketPacketSendAction{action_context}, transport_{&transport}, - data_{std::move(data)} {} + data_{std::move(data)}, + max_packet_size_{std::move(transport_->lora_module_driver_->GetMtu())} {} -LoraModuleTransport::SendTcpAction::SendTcpAction( +LoraModuleTransport::SendLoraAction::SendLoraAction( ActionContext action_context, LoraModuleTransport& transport, DataBuffer data) - : LoraModuleSend{action_context, transport, std::move(data)} {} + : LoraModuleSend{action_context, transport, std::move(data)}, + max_packet_size_{std::move(transport_->lora_module_driver_->GetMtu())} {} -void LoraModuleTransport::SendTcpAction::Send() { +void LoraModuleTransport::SendLoraAction::Send() { if (state_ == State::kInProgress) { return; } @@ -49,7 +49,7 @@ void LoraModuleTransport::SendTcpAction::Send() { for (std::size_t sent_offset = 0; sent_offset < data_.size();) { auto remain_to_send = data_.size() - sent_offset; auto size_to_send = - remain_to_send > kMaxPacketSize ? kMaxPacketSize : remain_to_send; + remain_to_send > max_packet_size_ ? max_packet_size_ : remain_to_send; auto write_action = transport_->lora_module_driver_->WritePacket( transport_->connection_, @@ -80,42 +80,6 @@ void LoraModuleTransport::SendTcpAction::Send() { } } -LoraModuleTransport::SendUdpAction::SendUdpAction( - ActionContext action_context, LoraModuleTransport& transport, - DataBuffer data) - : LoraModuleSend{action_context, transport, std::move(data)} {} - -void LoraModuleTransport::SendUdpAction::Send() { - if (state_ == State::kInProgress) { - return; - } - state_ = State::kInProgress; - - auto write_action = transport_->lora_module_driver_->WritePacket( - transport_->connection_, data_); - - if (!write_action) { - state_ = State::kFailed; - Action::Trigger(); - return; - } - - send_sub_ = write_action->StatusEvent().Subscribe(ActionHandler{ - OnResult{[this]() { - state_ = State::kDone; - Action::Trigger(); - }}, - OnError{[this]() { - state_ = State::kFailed; - Action::Trigger(); - }}, - OnStop{[this]() { - state_ = State::kStopped; - Action::Trigger(); - }}, - }); -} - LoraModuleTransport::LoraModuleTransport(ActionContext action_context, ILoraModuleDriver& lora_module_driver, UnifiedAddress address) @@ -125,13 +89,14 @@ LoraModuleTransport::LoraModuleTransport(ActionContext action_context, protocol_{ std::visit([](auto const& arg) { return arg.protocol; }, address_)}, stream_info_{}, - send_action_queue_manager_{action_context_} { + send_action_queue_manager_{action_context_}, + max_packet_size_{lora_module_driver_->GetMtu()} { AE_TELE_INFO(kLoraModuleTransport, "Lora module transport created for {}", address_); stream_info_.link_state = LinkState::kUnlinked; stream_info_.is_reliable = (protocol_ == Protocol::kTcp); - stream_info_.max_element_size = 2 * kMaxPacketSize; - stream_info_.rec_element_size = kMaxPacketSize; + stream_info_.max_element_size = 2 * max_packet_size_; + stream_info_.rec_element_size = max_packet_size_; Connect(); } @@ -159,26 +124,9 @@ void LoraModuleTransport::Restream() { ActionPtr LoraModuleTransport::Write(DataBuffer&& in_data) { AE_TELE_DEBUG(kLoraModuleTransportSend, "Send data size {}", in_data.size()); - if (protocol_ == Protocol::kTcp) { - auto packet_data = std::vector{}; - VectorWriter vw{packet_data}; - auto os = omstream{vw}; - // copy data with size - os << in_data; - auto send_action = - send_action_queue_manager_->AddPacket(ActionPtr{ - action_context_, *this, std::move(packet_data)}); - send_action_subs_.Push( - send_action->StatusEvent().Subscribe(OnError{[this]() { - AE_TELED_ERROR("Send error, disconnect!"); - OnConnectionFailed(); - Disconnect(); - }})); - return send_action; - } - if (protocol_ == Protocol::kUdp) { + if (protocol_ == Protocol::kLora) { auto send_action = send_action_queue_manager_->AddPacket( - ActionPtr{action_context_, *this, std::move(in_data)}); + ActionPtr{action_context_, *this, std::move(in_data)}); send_action_subs_.Push( send_action->StatusEvent().Subscribe(OnError{[this]() { AE_TELED_ERROR("Send error, disconnect!"); @@ -250,24 +198,12 @@ void LoraModuleTransport::DataReceived(ConnectionLoraIndex connection, if (connection_ != connection) { return; } - if (protocol_ == Protocol::kTcp) { - DataReceivedTcp(data_in); - } else if (protocol_ == Protocol::kUdp) { - DataReceivedUdp(data_in); - } -} - -void LoraModuleTransport::DataReceivedTcp(DataBuffer const& data_in) { - data_packet_collector_.AddData(data_in.data(), data_in.size()); - for (auto data = data_packet_collector_.PopPacket(); !data.empty(); - data = data_packet_collector_.PopPacket()) { - AE_TELE_DEBUG(kLoraModuleTransportReceive, "Receive data size {}", - data.size()); - out_data_event_.Emit(data); - } + if (protocol_ == Protocol::kLora) { + DataReceivedLora(data_in); + } } -void LoraModuleTransport::DataReceivedUdp(DataBuffer const& data_in) { +void LoraModuleTransport::DataReceivedLora(DataBuffer const& data_in) { out_data_event_.Emit(data_in); } diff --git a/aether/transport/lora_modules/lora_module_transport.h b/aether/transport/lora_modules/lora_module_transport.h index d52f8011..a9c0a125 100644 --- a/aether/transport/lora_modules/lora_module_transport.h +++ b/aether/transport/lora_modules/lora_module_transport.h @@ -37,32 +37,25 @@ class LoraModuleTransport final : public ByteIStream { public: LoraModuleSend(ActionContext action_context, LoraModuleTransport& transport, DataBuffer data); + + private: + std::uint16_t max_packet_size_{0}; - protected: + protected: LoraModuleTransport* transport_; - DataBuffer data_; + DataBuffer data_; }; - class SendTcpAction final : public LoraModuleSend { + class SendLoraAction final : public LoraModuleSend { public: - SendTcpAction(ActionContext action_context, LoraModuleTransport& transport, + SendLoraAction(ActionContext action_context, LoraModuleTransport& transport, DataBuffer data); void Send() override; private: void SendPacket(DataBuffer const& data); MultiSubscription send_subs_; - }; - - class SendUdpAction final : public LoraModuleSend { - public: - SendUdpAction(ActionContext action_context, LoraModuleTransport& transport, - DataBuffer data); - - void Send() override; - - private: - Subscription send_sub_; + std::uint16_t max_packet_size_{0}; }; public: @@ -84,8 +77,7 @@ class LoraModuleTransport final : public ByteIStream { void Disconnect(); void DataReceived(ConnectionLoraIndex connection, DataBuffer const& data_in); - void DataReceivedTcp(DataBuffer const& data_in); - void DataReceivedUdp(DataBuffer const& data_in); + void DataReceivedLora(DataBuffer const& data_in); ActionContext action_context_; ILoraModuleDriver* lora_module_driver_; @@ -105,6 +97,8 @@ class LoraModuleTransport final : public ByteIStream { MultiSubscription send_action_subs_; Subscription connection_sub_; Subscription read_packet_sub_; + + std::uint16_t max_packet_size_{0}; }; } // namespace ae diff --git a/aether/types/address.h b/aether/types/address.h index dcf2109c..f5f061f2 100644 --- a/aether/types/address.h +++ b/aether/types/address.h @@ -111,6 +111,7 @@ enum class Protocol : std::uint8_t { kTcp, kUdp, kWebSocket, + kLora // TODO: rest does not supported yet /* kAny, From 345e556b3ce310dc78201fde72da40937663c1d2 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Fri, 28 Nov 2025 18:08:34 +0300 Subject: [PATCH 02/32] Updating lora modules. --- aether/lora_modules/dx_smart_lr02_lm.cpp | 144 +++------ aether/lora_modules/dx_smart_lr02_lm.h | 14 +- aether/lora_modules/ebyte_e22_lm.cpp | 306 +++++++++++++++--- aether/lora_modules/ebyte_e22_lm.h | 75 +++-- aether/lora_modules/ilora_module_driver.h | 5 - .../lora_modules/lora_module_transport.cpp | 6 +- 6 files changed, 364 insertions(+), 186 deletions(-) diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index df00d01f..2ab2ce75 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -85,11 +85,12 @@ DxSmartLr02LoraModule::DxSmartLr02LoraModule(ActionContext action_context, lora_module_init_{std::move(lora_module_init)}, serial_{SerialPortFactory::CreatePort(action_context_, poller, lora_module_init_.serial_init)}, - at_comm_support_{action_context_, *serial_}, + at_support_{action_context_, *serial_}, operation_queue_{action_context_}, initiated_{false}, started_{false} { Init(); + Start(); } DxSmartLr02LoraModule::~DxSmartLr02LoraModule() { Stop(); } @@ -143,7 +144,7 @@ DxSmartLr02LoraModule::Stop() { action_context_, // Enter AT command mode Stage([this]() { return EnterAtMode(); }), Stage([this]() { - return at_comm_support_.MakeRequest("AT+RESET", kWaitOk); + return at_support_.MakeRequest("AT+RESET", kWaitOk); }), // Exit AT command mode Stage([this]() { return ExitAtMode(); })); @@ -160,87 +161,32 @@ DxSmartLr02LoraModule::Stop() { return lora_module_operation; } -ActionPtr -DxSmartLr02LoraModule::OpenNetwork(ae::Protocol protocol, - std::string const& host, - std::uint16_t port) { - auto open_network_operation = - ActionPtr{action_context_}; - - operation_queue_->Push(Stage([this, open_network_operation, protocol, - host{host}, port]() -> ActionPtr { - if (protocol == Protocol::kLora) { - return OpenLoraConnection(open_network_operation, host, port); - } +ActionPtr +DxSmartLr02LoraModule::WritePacket(ae::ConnectionLoraIndex connect_index, + ae::DataBuffer const& data) { + if (data.size() > kLoraModuleMTU) { + assert(false); return {}; - })); + } - return open_network_operation; -} + auto write_notify = ActionPtr{action_context_}; -ActionPtr -DxSmartLr02LoraModule::CloseNetwork(ae::ConnectionLoraIndex /*connect_index*/) { - return {}; -} -// void DxSmartLr02LoraModule::CloseNetwork( -// ae::ConnectionLoraIndex connect_index) { -// if (connect_index >= connect_vec_.size()) { -// AE_TELED_ERROR("Connection index overflow"); -// return; -// } -// -// connect_vec_.erase(connect_vec_.begin() + connect_index); -//}; + AE_TELED_DEBUG("Queue write packet for data size {}", data.size()); -ActionPtr -DxSmartLr02LoraModule::WritePacket(ae::ConnectionLoraIndex /*connect_index*/, - ae::DataBuffer const& /*data*/) { - return {}; -} -// void DxSmartLr02LoraModule::WritePacket( -// ae::ConnectionLoraIndex connect_index, -// ae::DataBuffer const& data) { -// LoraPacket lora_packet{}; -// -// auto const& connection = -// connect_vec_.at(static_cast(connect_index)); -// -// lora_packet.connection = connection; -// lora_packet.length = data.size(); -// lora_packet.data = data; -// lora_packet.crc = 0; // Not implemented yet -// -// auto packet_data = std::vector{}; -// VectorWriter vw{packet_data}; -// auto os = omstream{vw}; -// // copy data with size -// os << lora_packet; -// -// serial_->Write(packet_data); -//}; + operation_queue_->Push( + Stage([this, write_notify, connect_index, data{data}]() { + auto write_pipeline = SendData(connect_index, data); + write_pipeline->StatusEvent().Subscribe(ActionHandler{ + OnResult{[write_notify]() { write_notify->Notify(); }}, + OnError{[write_notify]() { write_notify->Failed(); }}, + OnStop{[write_notify]() { write_notify->Stop(); }}, + }); + return write_pipeline; + })); -ActionPtr DxSmartLr02LoraModule::ReadPacket( - ConnectionLoraIndex /* connection */) { - return {}; + return write_notify; } -// DataBuffer DxSmartLr02LoraModule::ReadPacket( -// ae::ConnectionLoraIndex /* connect_index*/, ae::Duration /* timeout*/) { -// LoraPacket lora_packet{}; -// DataBuffer data{}; -// -// auto response = serial_->Read(); -// std::vector packet_data(response->begin(), response->end()); -// VectorReader vr(packet_data); -// auto is = imstream{vr}; -// // copy data with size -// is >> lora_packet; -// -// data = lora_packet.data; -// -// return data; -// }; - DxSmartLr02LoraModule::DataEvent::Subscriber DxSmartLr02LoraModule::data_event() { return EventSubscriber{data_event_}; @@ -310,7 +256,7 @@ DxSmartLr02LoraModule::SetLoraModuleAddress(std::uint16_t const& address) { action_context_, // Enter AT command mode Stage([this]() { return EnterAtMode(); }), Stage([this, address]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "AT+MAC" + AdressToString(address), kWaitOk); }), // Exit AT command mode @@ -341,7 +287,7 @@ DxSmartLr02LoraModule::SetLoraModuleChannel(std::uint8_t const& channel) { action_context_, // Enter AT command mode Stage([this]() { return EnterAtMode(); }), Stage([this, channel]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "AT+CHANNEL" + ChannelToString(channel), kWaitOk); }), // Exit AT command mode @@ -369,7 +315,7 @@ DxSmartLr02LoraModule::SetLoraModuleCRCCheck( action_context_, // Enter AT command mode Stage([this]() { return EnterAtMode(); }), Stage([this, crc_check]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "AT+CRC" + std::to_string(static_cast(crc_check)), kWaitOk); }), // Exit AT command mode @@ -399,7 +345,7 @@ DxSmartLr02LoraModule::SetLoraModuleIQSignalInversion( // Enter AT command mode Stage([this]() { return EnterAtMode(); }), Stage([this, signal_inversion]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "AT+IQ" + std::to_string(static_cast(signal_inversion)), kWaitOk); }), @@ -425,7 +371,7 @@ void DxSmartLr02LoraModule::Init() { action_context_, // Enter AT command mode Stage([this]() { return EnterAtMode(); }), - Stage([this]() { return at_comm_support_.MakeRequest("AT", kWaitOk); }), + Stage([this]() { return at_support_.MakeRequest("AT", kWaitOk); }), Stage([this]() { return SetupSerialPort(lora_module_init_.serial_init); }), @@ -470,8 +416,18 @@ ActionPtr DxSmartLr02LoraModule::OpenLoraConnection( })); } +ActionPtr DxSmartLr02LoraModule::SendData( + ConnectionLoraIndex /* connection */, DataBuffer const& /* data */) { + return {}; +} + +ActionPtr DxSmartLr02LoraModule::ReadPacket( + ConnectionLoraIndex /* connection */) { + return {}; +} + void DxSmartLr02LoraModule::SetupPoll() { - poll_listener_ = at_comm_support_.ListenForResponse( + poll_listener_ = at_support_.ListenForResponse( "#XPOLL: ", [this](auto& at_buffer, auto pos) { std::int32_t handle{}; std::string flags; @@ -499,7 +455,7 @@ ActionPtr DxSmartLr02LoraModule::Poll() { for (auto ci : connections_) { handles += "," + std::to_string(ci); } - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "#XPOLL=0" + handles, kWaitOk); })); } @@ -529,7 +485,7 @@ ActionPtr DxSmartLr02LoraModule::EnterAtMode() { if (at_mode_ == false) { at_mode_ = true; return MakeActionPtr(action_context_, Stage([this]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "+++", kWaitEntryAt); })); } @@ -541,7 +497,7 @@ ActionPtr DxSmartLr02LoraModule::ExitAtMode() { if (at_mode_ == true) { at_mode_ = false; return MakeActionPtr(action_context_, Stage([this]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "+++", kWaitExitAt, kWaitPowerOn); })); } @@ -553,7 +509,7 @@ ActionPtr DxSmartLr02LoraModule::SetLoraModuleMode( kLoraModuleMode const& mode) { return MakeActionPtr( action_context_, Stage([this, mode]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "AT+MODE" + std::to_string(static_cast(mode)), kWaitOk); })); } @@ -562,7 +518,7 @@ ActionPtr DxSmartLr02LoraModule::SetLoraModuleLevel( kLoraModuleLevel const& level) { return MakeActionPtr( action_context_, Stage([this, level]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "AT+LEVEL" + std::to_string(static_cast(level)), kWaitOk); })); } @@ -571,7 +527,7 @@ ActionPtr DxSmartLr02LoraModule::SetLoraModulePower( kLoraModulePower const& power) { return MakeActionPtr( action_context_, Stage([this, power]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "AT+POWE" + std::to_string(static_cast(power)), kWaitOk); })); } @@ -580,7 +536,7 @@ ActionPtr DxSmartLr02LoraModule::SetLoraModuleBandWidth( kLoraModuleBandWidth const& band_width) { return MakeActionPtr( action_context_, Stage([this, band_width]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "AT+BW" + std::to_string(static_cast(band_width)), kWaitOk); })); } @@ -589,7 +545,7 @@ ActionPtr DxSmartLr02LoraModule::SetLoraModuleCodingRate( kLoraModuleCodingRate const& coding_rate) { return MakeActionPtr( action_context_, Stage([this, coding_rate]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "AT+CR" + std::to_string(static_cast(coding_rate)), kWaitOk); })); } @@ -598,7 +554,7 @@ ActionPtr DxSmartLr02LoraModule::SetLoraModuleSpreadingFactor( kLoraModuleSpreadingFactor const& spreading_factor) { return MakeActionPtr( action_context_, Stage([this, spreading_factor]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( "AT+SF" + std::to_string(static_cast(spreading_factor)), kWaitOk); })); @@ -623,7 +579,7 @@ ActionPtr DxSmartLr02LoraModule::SetBaudRate(kBaudRate baud_rate) { } return MakeActionPtr(action_context_, Stage([this, it]() { - return at_comm_support_.MakeRequest( + return at_support_.MakeRequest( it->second, kWaitOk); })); } @@ -647,7 +603,7 @@ ActionPtr DxSmartLr02LoraModule::SetParity(kParity parity) { } return MakeActionPtr(action_context_, Stage([this, cmd]() { - return at_comm_support_.MakeRequest(cmd, + return at_support_.MakeRequest(cmd, kWaitOk); })); } @@ -670,7 +626,7 @@ ActionPtr DxSmartLr02LoraModule::SetStopBits(kStopBits stop_bits) { return MakeActionPtr(action_context_, Stage([this, cmd]() { - return at_comm_support_.MakeRequest(cmd, + return at_support_.MakeRequest(cmd, kWaitOk); })); } diff --git a/aether/lora_modules/dx_smart_lr02_lm.h b/aether/lora_modules/dx_smart_lr02_lm.h index fc4d8105..3b45852b 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.h +++ b/aether/lora_modules/dx_smart_lr02_lm.h @@ -58,19 +58,14 @@ class DxSmartLr02LoraModule final : public ILoraModuleDriver { ActionPtr Start() override; ActionPtr Stop() override; - ActionPtr OpenNetwork(Protocol protocol, - std::string const& host, - std::uint16_t port) override; - ActionPtr CloseNetwork( - ConnectionLoraIndex connect_index) override; ActionPtr WritePacket(ConnectionLoraIndex connect_index, - ae::DataBuffer const& data) override; + DataBuffer const& data) override; DataEvent::Subscriber data_event() override; ActionPtr SetPowerSaveParam( LoraPowerSaveParam const& psp) override; - ActionPtr PowerOff() override; + ActionPtr PowerOff() override; std::uint16_t GetMtu() override; - + ActionPtr SetLoraModuleAddress( std::uint16_t const& address); // Module address ActionPtr SetLoraModuleChannel( @@ -100,7 +95,7 @@ class DxSmartLr02LoraModule final : public ILoraModuleDriver { LoraModuleInit lora_module_init_; std::unique_ptr serial_; std::set connections_; - AtSupport at_comm_support_; + AtSupport at_support_; DataEvent data_event_; ActionPtr poll_task_; std::unique_ptr poll_listener_; @@ -125,6 +120,7 @@ class DxSmartLr02LoraModule final : public ILoraModuleDriver { ActionPtr SetLoraModuleSpreadingFactor( kLoraModuleSpreadingFactor const& spreading_factor); // Module spreading factor + ActionPtr SetupSerialPort(SerialInit& serial_init); ActionPtr SetBaudRate(kBaudRate baud_rate); ActionPtr SetParity(kParity parity); diff --git a/aether/lora_modules/ebyte_e22_lm.cpp b/aether/lora_modules/ebyte_e22_lm.cpp index 571f1c27..ec3fe2b9 100644 --- a/aether/lora_modules/ebyte_e22_lm.cpp +++ b/aether/lora_modules/ebyte_e22_lm.cpp @@ -33,6 +33,51 @@ namespace ae { static constexpr Duration kOneSecond = std::chrono::milliseconds{1000}; static constexpr Duration kTwoSeconds = std::chrono::milliseconds{2000}; static constexpr Duration kTenSeconds = std::chrono::milliseconds{10000}; +static const AtRequest::Wait kWaitOk{"OK", kOneSecond}; +static const AtRequest::Wait kWaitOkTwoSeconds{"OK", kTwoSeconds}; +static const AtRequest::Wait kWaitEntryAt{"Entry AT", kOneSecond}; +static const AtRequest::Wait kWaitExitAt{"Exit AT", kOneSecond}; +static const AtRequest::Wait kWaitPowerOn{"Power on", kOneSecond}; + +class EbyteE22LoraOpenNetwork final + : public Action { + public: + EbyteE22LoraOpenNetwork(ActionContext action_context, + EbyteE22LoraModule& /* lora_module */, + std::string host, std::uint16_t port) + : Action{action_context}, + action_context_{action_context}, + host_{std::move(host)}, + port_{port} { + AE_TELED_DEBUG("Open lora connection for {}:{}", host_, port_); + } + + UpdateStatus Update() const { + if (success_) { + return UpdateStatus::Result(); + } + if (error_) { + return UpdateStatus::Error(); + } + if (stop_) { + return UpdateStatus::Stop(); + } + return {}; + } + + ConnectionLoraIndex connection_index() const { return connection_index_; } + + private: + ActionContext action_context_; + std::string host_; + std::uint16_t port_; + ActionPtr operation_pipeline_; + Subscription operation_sub_; + ConnectionLoraIndex connection_index_ = kInvalidConnectionLoraIndex; + bool success_{}; + bool error_{}; + bool stop_{}; +}; EbyteE22LoraModule::EbyteE22LoraModule(ActionContext action_context, IPoller::ptr const& poller, @@ -41,7 +86,7 @@ EbyteE22LoraModule::EbyteE22LoraModule(ActionContext action_context, lora_module_init_{std::move(lora_module_init)}, serial_{SerialPortFactory::CreatePort(action_context_, std::move(poller), lora_module_init_.serial_init)}, - at_comm_support_{action_context_, *serial_}, + at_support_{action_context_, *serial_}, operation_queue_{action_context_}, initiated_{false}, started_{false} { @@ -59,39 +104,31 @@ ActionPtr EbyteE22LoraModule::Stop() { return {}; } -ActionPtr -EbyteE22LoraModule::OpenNetwork(ae::Protocol /* protocol*/, - std::string const& /*host*/, - std::uint16_t /* port*/) { - return {}; -} +ActionPtr +EbyteE22LoraModule::WritePacket(ae::ConnectionLoraIndex connect_index, + ae::DataBuffer const& data) { + if (data.size() > kLoraModuleMTU) { + assert(false); + return {}; + } -ActionPtr -EbyteE22LoraModule::CloseNetwork(ae::ConnectionLoraIndex /*connect_index*/) { - return {}; -} -// void EbyteE22LoraModule::CloseNetwork( -// ae::ConnectionLoraIndex /*connect_index*/){}; + auto write_notify = ActionPtr{action_context_}; -ActionPtr -EbyteE22LoraModule::WritePacket(ae::ConnectionLoraIndex /*connect_index*/, - ae::DataBuffer const& /*data*/) { - return {}; -} -// void EbyteE22LoraModule::WritePacket(ae::ConnectionLoraIndex -// /*connect_index*/, -// ae::DataBuffer const& /*data*/) {}; + AE_TELED_DEBUG("Queue write packet for data size {}", data.size()); -ActionPtr EbyteE22LoraModule::ReadPacket( - ConnectionLoraIndex /* connection */) { - return {}; + operation_queue_->Push( + Stage([this, write_notify, connect_index, data{data}]() { + auto write_pipeline = SendData(connect_index, data); + write_pipeline->StatusEvent().Subscribe(ActionHandler{ + OnResult{[write_notify]() { write_notify->Notify(); }}, + OnError{[write_notify]() { write_notify->Failed(); }}, + OnStop{[write_notify]() { write_notify->Stop(); }}, + }); + return write_pipeline; + })); + + return write_notify; } -// DataBuffer EbyteE22LoraModule::ReadPacket( -// ae::ConnectionLoraIndex /*connect_index*/, ae::Duration /*timeout*/) { -// DataBuffer data{}; -// -// return data; -// }; EbyteE22LoraModule::DataEvent::Subscriber EbyteE22LoraModule::data_event() { @@ -123,51 +160,220 @@ EbyteE22LoraModule::SetLoraModuleChannel(std::uint8_t const& /*channel*/) { } ActionPtr -EbyteE22LoraModule::SetLoraModuleMode(kLoraModuleMode const& /*mode*/) { +EbyteE22LoraModule::SetLoraModuleCRCCheck( + kLoraModuleCRCCheck const& /*crc_check*/) { return {}; } ActionPtr -EbyteE22LoraModule::SetLoraModuleLevel(kLoraModuleLevel const& /*level*/) { +EbyteE22LoraModule::SetLoraModuleIQSignalInversion( + kLoraModuleIQSignalInversion const& /*signal_inversion*/) { return {}; } -ActionPtr -EbyteE22LoraModule::SetLoraModulePower(kLoraModulePower const& /*power*/) { +// ============================private members=============================== // +void EbyteE22LoraModule::Init() {} + +ActionPtr EbyteE22LoraModule::OpenLoraConnection( + ActionPtr /* open_network_operation */, + std::string const& /* host */, std::uint16_t /* port */) { return {}; } -ActionPtr -EbyteE22LoraModule::SetLoraModuleBandWidth( - kLoraModuleBandWidth const& /*band_width*/) { +ActionPtr EbyteE22LoraModule::SendData(ConnectionLoraIndex /* connection */, + DataBuffer const& /* data */) { return {}; } -ActionPtr -EbyteE22LoraModule::SetLoraModuleCodingRate( - kLoraModuleCodingRate const& /*coding_rate*/) { +ActionPtr EbyteE22LoraModule::ReadPacket( + ConnectionLoraIndex /* connection */) { return {}; } -ActionPtr -EbyteE22LoraModule::SetLoraModuleSpreadingFactor( - kLoraModuleSpreadingFactor const& /*spreading_factor*/) { + +void EbyteE22LoraModule::SetupPoll() { + +} + +ActionPtr EbyteE22LoraModule::Poll() { return {}; } -ActionPtr -EbyteE22LoraModule::SetLoraModuleCRCCheck( - kLoraModuleCRCCheck const& /*crc_check*/) { +void EbyteE22LoraModule::PollEvent(std::int32_t /* handle */, + std::string_view /* flags */) { + +} + +ActionPtr EbyteE22LoraModule::EnterAtMode() { return {}; } -ActionPtr -EbyteE22LoraModule::SetLoraModuleIQSignalInversion( - kLoraModuleIQSignalInversion const& /*signal_inversion*/) { +ActionPtr EbyteE22LoraModule::ExitAtMode() { return {}; } -void EbyteE22LoraModule::Init() {} +ActionPtr EbyteE22LoraModule::SetLoraModuleMode( + kLoraModuleMode const& mode) { + return MakeActionPtr( + action_context_, Stage([this, mode]() { + return at_support_.MakeRequest( + "AT+MODE" + std::to_string(static_cast(mode)), kWaitOk); + })); +} + +ActionPtr EbyteE22LoraModule::SetLoraModuleLevel( + kLoraModuleLevel const& level) { + return MakeActionPtr( + action_context_, Stage([this, level]() { + return at_support_.MakeRequest( + "AT+LEVEL" + std::to_string(static_cast(level)), kWaitOk); + })); +} + +ActionPtr EbyteE22LoraModule::SetLoraModulePower( + kLoraModulePower const& power) { + return MakeActionPtr( + action_context_, Stage([this, power]() { + return at_support_.MakeRequest( + "AT+POWE" + std::to_string(static_cast(power)), kWaitOk); + })); +} + +ActionPtr EbyteE22LoraModule::SetLoraModuleBandWidth( + kLoraModuleBandWidth const& band_width) { + return MakeActionPtr( + action_context_, Stage([this, band_width]() { + return at_support_.MakeRequest( + "AT+BW" + std::to_string(static_cast(band_width)), kWaitOk); + })); +} + +ActionPtr EbyteE22LoraModule::SetLoraModuleCodingRate( + kLoraModuleCodingRate const& coding_rate) { + return MakeActionPtr( + action_context_, Stage([this, coding_rate]() { + return at_support_.MakeRequest( + "AT+CR" + std::to_string(static_cast(coding_rate)), kWaitOk); + })); +} + +ActionPtr EbyteE22LoraModule::SetLoraModuleSpreadingFactor( + kLoraModuleSpreadingFactor const& spreading_factor) { + return MakeActionPtr( + action_context_, Stage([this, spreading_factor]() { + return at_support_.MakeRequest( + "AT+SF" + std::to_string(static_cast(spreading_factor)), + kWaitOk); + })); +} + +ActionPtr EbyteE22LoraModule::SetupSerialPort( + SerialInit& serial_init) { + return MakeActionPtr( + action_context_, Stage([this, serial_init]() { + return SetBaudRate(serial_init.baud_rate); + }), + Stage([this, serial_init]() { return SetParity(serial_init.parity); }), + Stage([this, serial_init]() { + return SetStopBits(serial_init.stop_bits); + })); +} + +ActionPtr EbyteE22LoraModule::SetBaudRate(kBaudRate baud_rate) { + auto it = baud_rate_commands_e22.find(baud_rate); + if (it == baud_rate_commands_e22.end()) { + return {}; + } + + return MakeActionPtr(action_context_, Stage([this, it]() { + return at_support_.MakeRequest( + it->second, kWaitOk); + })); +} + +ActionPtr EbyteE22LoraModule::SetParity(kParity parity) { + std::string cmd{}; + + switch (parity) { + case kParity::kNoParity: + cmd = "AT+PARI0"; // Set no parity + break; + case kParity::kOddParity: + cmd = "AT+PARI1"; // Set odd parity + break; + case kParity::kEvenParity: + cmd = "AT+PARI2"; // Set even parity + break; + default: + return {}; + break; + } + + return MakeActionPtr(action_context_, Stage([this, cmd]() { + return at_support_.MakeRequest(cmd, + kWaitOk); + })); +} + +ActionPtr EbyteE22LoraModule::SetStopBits(kStopBits stop_bits) { + std::string cmd{}; + + switch (stop_bits) { + case kStopBits::kOneStopBit: + cmd = "AT+STOP1"; // 0 stop bits + break; + case kStopBits::kTwoStopBit: + cmd = "AT+STOP2"; // 2 stop bits + break; + default: + return {}; + break; + } + + return MakeActionPtr(action_context_, + + Stage([this, cmd]() { + return at_support_.MakeRequest(cmd, + kWaitOk); + })); +} +ActionPtr EbyteE22LoraModule::SetupLoraNet( + LoraModuleInit& lora_module_init) { + return MakeActionPtr( + action_context_, Stage([this, lora_module_init]() { + return SetLoraModuleAddress(lora_module_init.lora_module_my_adress); + }), + Stage([this, lora_module_init]() { + return SetLoraModuleChannel(lora_module_init.lora_module_channel); + }), + Stage([this, lora_module_init]() { + return SetLoraModuleCRCCheck(lora_module_init.lora_module_crc_check); + }), + Stage([this, lora_module_init]() { + return SetLoraModuleIQSignalInversion( + lora_module_init.lora_module_signal_inversion); + })); +} + +std::string EbyteE22LoraModule::AdressToString(uint16_t value) { + uint8_t high = static_cast((value >> 8)); // High byte + uint8_t low = static_cast(value & 0xFF); // Low byte + char buffer[7]; // Buffer for string + + // Formatting hex string + std::snprintf(buffer, sizeof(buffer), "%02x,%02x", high, low); + + return std::string(buffer); +} + +std::string EbyteE22LoraModule::ChannelToString(uint8_t value) { + char buffer[5]; // Buffer for string + + // Formatting hex string + std::snprintf(buffer, sizeof(buffer), "%02x", value); + + return std::string(buffer); +} } // namespace ae #endif diff --git a/aether/lora_modules/ebyte_e22_lm.h b/aether/lora_modules/ebyte_e22_lm.h index 28fa59a6..9297f0c4 100644 --- a/aether/lora_modules/ebyte_e22_lm.h +++ b/aether/lora_modules/ebyte_e22_lm.h @@ -34,8 +34,21 @@ # include "aether/lora_modules/ilora_module_driver.h" namespace ae { +class EbyteE22LoraOpenNetwork; + +static const std::map baud_rate_commands_e22 = { + {kBaudRate::kBaudRate1200, "AT+BAUD1"}, + {kBaudRate::kBaudRate2400, "AT+BAUD2"}, + {kBaudRate::kBaudRate4800, "AT+BAUD3"}, + {kBaudRate::kBaudRate9600, "AT+BAUD4"}, + {kBaudRate::kBaudRate19200, "AT+BAUD5"}, + {kBaudRate::kBaudRate38400, "AT+BAUD6"}, + {kBaudRate::kBaudRate57600, "AT+BAUD7"}, + {kBaudRate::kBaudRate115200, "AT+BAUD8"}, + {kBaudRate::kBaudRate128000, "AT+BAUD9"}}; class EbyteE22LoraModule final : public ILoraModuleDriver { + friend class EbyteE22LoraOpenNetwork; static constexpr std::uint16_t kLoraModuleMTU{400}; public: @@ -46,37 +59,18 @@ class EbyteE22LoraModule final : public ILoraModuleDriver { ActionPtr Start() override; ActionPtr Stop() override; - ActionPtr OpenNetwork(ae::Protocol protocol, - std::string const& host, - std::uint16_t port) override; - ActionPtr CloseNetwork( - ae::ConnectionLoraIndex connect_index) override; - ActionPtr WritePacket( - ae::ConnectionLoraIndex connect_index, - ae::DataBuffer const& data) override; + ActionPtr WritePacket(ConnectionLoraIndex connect_index, + DataBuffer const& data) override; DataEvent::Subscriber data_event() override; ActionPtr SetPowerSaveParam( LoraPowerSaveParam const& psp) override; - ActionPtr PowerOff() override; + ActionPtr PowerOff() override; std::uint16_t GetMtu() override; - + ActionPtr SetLoraModuleAddress( std::uint16_t const& address); // Module address ActionPtr SetLoraModuleChannel( std::uint8_t const& channel); // Module channel - ActionPtr SetLoraModuleMode( - kLoraModuleMode const& mode); // Module mode - ActionPtr SetLoraModuleLevel( - kLoraModuleLevel const& level); // Module level - ActionPtr SetLoraModulePower( - kLoraModulePower const& power); // Module power - ActionPtr SetLoraModuleBandWidth( - kLoraModuleBandWidth const& band_width); // Module BandWidth - ActionPtr SetLoraModuleCodingRate( - kLoraModuleCodingRate const& coding_rate); // Module CodingRate - ActionPtr SetLoraModuleSpreadingFactor( - kLoraModuleSpreadingFactor const& - spreading_factor); // Module spreading factor ActionPtr SetLoraModuleCRCCheck( kLoraModuleCRCCheck const& crc_check); // Module crc check ActionPtr SetLoraModuleIQSignalInversion( @@ -86,6 +80,10 @@ class EbyteE22LoraModule final : public ILoraModuleDriver { private: void Init(); + ActionPtr OpenLoraConnection( + ActionPtr open_network_operation, + std::string const& host, std::uint16_t port); + ActionPtr SendData(ConnectionLoraIndex connection, DataBuffer const& data); ActionPtr ReadPacket(ConnectionLoraIndex connection); @@ -97,8 +95,8 @@ class EbyteE22LoraModule final : public ILoraModuleDriver { ActionContext action_context_; LoraModuleInit lora_module_init_; std::unique_ptr serial_; - std::vector connect_vec_; - AtSupport at_comm_support_; + std::set connections_; + AtSupport at_support_; DataEvent data_event_; ActionPtr poll_task_; std::unique_ptr poll_listener_; @@ -106,6 +104,33 @@ class EbyteE22LoraModule final : public ILoraModuleDriver { bool initiated_; bool started_; bool at_mode_{false}; + + ActionPtr EnterAtMode(); + ActionPtr ExitAtMode(); + + ActionPtr SetLoraModuleMode( + kLoraModuleMode const& mode); // Module mode + ActionPtr SetLoraModuleLevel( + kLoraModuleLevel const& level); // Module level + ActionPtr SetLoraModulePower( + kLoraModulePower const& power); // Module power + ActionPtr SetLoraModuleBandWidth( + kLoraModuleBandWidth const& band_width); // Module BandWidth + ActionPtr SetLoraModuleCodingRate( + kLoraModuleCodingRate const& coding_rate); // Module CodingRate + ActionPtr SetLoraModuleSpreadingFactor( + kLoraModuleSpreadingFactor const& + spreading_factor); // Module spreading factor + + ActionPtr SetupSerialPort(SerialInit& serial_init); + ActionPtr SetBaudRate(kBaudRate baud_rate); + ActionPtr SetParity(kParity parity); + ActionPtr SetStopBits(kStopBits stop_bits); + + ActionPtr SetupLoraNet(LoraModuleInit& lora_module_init); + + std::string AdressToString(uint16_t value); + std::string ChannelToString(uint8_t value); }; } /* namespace ae */ diff --git a/aether/lora_modules/ilora_module_driver.h b/aether/lora_modules/ilora_module_driver.h index 4a03091f..59cb2089 100644 --- a/aether/lora_modules/ilora_module_driver.h +++ b/aether/lora_modules/ilora_module_driver.h @@ -45,11 +45,6 @@ class ILoraModuleDriver { virtual ActionPtr Start() = 0; virtual ActionPtr Stop() = 0; - virtual ActionPtr OpenNetwork(Protocol protocol, - std::string const& host, - std::uint16_t port) = 0; - virtual ActionPtr CloseNetwork( - ConnectionLoraIndex connect_index) = 0; virtual ActionPtr WritePacket( ConnectionLoraIndex connect_index, DataBuffer const& data) = 0; virtual DataEvent::Subscriber data_event() = 0; diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 683f8c8c..56151273 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -141,7 +141,7 @@ ActionPtr LoraModuleTransport::Write(DataBuffer&& in_data) { void LoraModuleTransport::Connect() { // open network depend on address type - auto connection_operation = std::visit( + /* auto connection_operation = std::visit( reflect::OverrideFunc{[&](IpAddressPortProtocol const& address) { return lora_module_driver_->OpenNetwork( address.protocol, Format("{}", address.ip), @@ -165,7 +165,7 @@ void LoraModuleTransport::Connect() { connection_sub_ = connection_operation->StatusEvent().Subscribe(ActionHandler{ OnResult{[this](auto const& action) { OnConnected(action.value()); }}, OnError{[this]() { OnConnectionFailed(); }}, - }); + });*/ } void LoraModuleTransport::OnConnected(ConnectionLoraIndex connection_index) { @@ -189,7 +189,7 @@ void LoraModuleTransport::Disconnect() { return; } - lora_module_driver_->CloseNetwork(connection_); + /* lora_module_driver_->CloseNetwork(connection_);*/ connection_ = kInvalidConnectionLoraIndex; } From 503a699dc74e68dee8bde9b90ab3c6da8ba34e0e Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Tue, 2 Dec 2025 15:27:33 +0300 Subject: [PATCH 03/32] Removing OpenNetwork from Connect function. --- .../lora_modules/lora_module_transport.cpp | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 56151273..1e7d501c 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -140,32 +140,7 @@ ActionPtr LoraModuleTransport::Write(DataBuffer&& in_data) { } void LoraModuleTransport::Connect() { - // open network depend on address type - /* auto connection_operation = std::visit( - reflect::OverrideFunc{[&](IpAddressPortProtocol const& address) { - return lora_module_driver_->OpenNetwork( - address.protocol, Format("{}", address.ip), - address.port); - } -# if AE_SUPPORT_CLOUD_DNS - , - [&](NameAddress const& address) { - return lora_module_driver_->OpenNetwork( - address.protocol, address.name, address.port); - } -# endif - }, - address_); - - if (!connection_operation) { - OnConnectionFailed(); - return; - } - connection_sub_ = connection_operation->StatusEvent().Subscribe(ActionHandler{ - OnResult{[this](auto const& action) { OnConnected(action.value()); }}, - OnError{[this]() { OnConnectionFailed(); }}, - });*/ } void LoraModuleTransport::OnConnected(ConnectionLoraIndex connection_index) { From 999907f29bd2d2172bc15421f2a55c85f8df02ea Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Tue, 2 Dec 2025 15:33:17 +0300 Subject: [PATCH 04/32] Fixing cpplint. --- aether/lora_modules/dx_smart_lr02_lm.cpp | 29 ++++----- aether/lora_modules/ebyte_e22_lm.cpp | 59 +++++++------------ .../lora_modules/lora_module_transport.cpp | 6 +- .../lora_modules/lora_module_transport.h | 10 ++-- 4 files changed, 39 insertions(+), 65 deletions(-) diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index 2ab2ce75..55d2f99a 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -42,8 +42,8 @@ class DxSmartLr02LoraOpenNetwork final : public Action { public: DxSmartLr02LoraOpenNetwork(ActionContext action_context, - DxSmartLr02LoraModule& /* lora_module */, - std::string host, std::uint16_t port) + DxSmartLr02LoraModule& /* lora_module */, + std::string host, std::uint16_t port) : Action{action_context}, action_context_{action_context}, host_{std::move(host)}, @@ -164,7 +164,7 @@ DxSmartLr02LoraModule::Stop() { ActionPtr DxSmartLr02LoraModule::WritePacket(ae::ConnectionLoraIndex connect_index, ae::DataBuffer const& data) { - if (data.size() > kLoraModuleMTU) { + if (data.size() > kLoraModuleMTU) { assert(false); return {}; } @@ -243,9 +243,7 @@ DxSmartLr02LoraModule::PowerOff() { return {}; } -std::uint16_t DxSmartLr02LoraModule::GetMtu(){ - return kLoraModuleMTU; -} +std::uint16_t DxSmartLr02LoraModule::GetMtu() { return kLoraModuleMTU; } ActionPtr DxSmartLr02LoraModule::SetLoraModuleAddress(std::uint16_t const& address) { @@ -256,8 +254,8 @@ DxSmartLr02LoraModule::SetLoraModuleAddress(std::uint16_t const& address) { action_context_, // Enter AT command mode Stage([this]() { return EnterAtMode(); }), Stage([this, address]() { - return at_support_.MakeRequest( - "AT+MAC" + AdressToString(address), kWaitOk); + return at_support_.MakeRequest("AT+MAC" + AdressToString(address), + kWaitOk); }), // Exit AT command mode Stage([this]() { return ExitAtMode(); })); @@ -579,8 +577,8 @@ ActionPtr DxSmartLr02LoraModule::SetBaudRate(kBaudRate baud_rate) { } return MakeActionPtr(action_context_, Stage([this, it]() { - return at_support_.MakeRequest( - it->second, kWaitOk); + return at_support_.MakeRequest(it->second, + kWaitOk); })); } @@ -603,8 +601,7 @@ ActionPtr DxSmartLr02LoraModule::SetParity(kParity parity) { } return MakeActionPtr(action_context_, Stage([this, cmd]() { - return at_support_.MakeRequest(cmd, - kWaitOk); + return at_support_.MakeRequest(cmd, kWaitOk); })); } @@ -623,12 +620,10 @@ ActionPtr DxSmartLr02LoraModule::SetStopBits(kStopBits stop_bits) { break; } - return MakeActionPtr(action_context_, + return MakeActionPtr( + action_context_, - Stage([this, cmd]() { - return at_support_.MakeRequest(cmd, - kWaitOk); - })); + Stage([this, cmd]() { return at_support_.MakeRequest(cmd, kWaitOk); })); } ActionPtr DxSmartLr02LoraModule::SetupLoraNet( diff --git a/aether/lora_modules/ebyte_e22_lm.cpp b/aether/lora_modules/ebyte_e22_lm.cpp index ec3fe2b9..8c2f8b57 100644 --- a/aether/lora_modules/ebyte_e22_lm.cpp +++ b/aether/lora_modules/ebyte_e22_lm.cpp @@ -39,12 +39,11 @@ static const AtRequest::Wait kWaitEntryAt{"Entry AT", kOneSecond}; static const AtRequest::Wait kWaitExitAt{"Exit AT", kOneSecond}; static const AtRequest::Wait kWaitPowerOn{"Power on", kOneSecond}; -class EbyteE22LoraOpenNetwork final - : public Action { +class EbyteE22LoraOpenNetwork final : public Action { public: EbyteE22LoraOpenNetwork(ActionContext action_context, - EbyteE22LoraModule& /* lora_module */, - std::string host, std::uint16_t port) + EbyteE22LoraModule& /* lora_module */, + std::string host, std::uint16_t port) : Action{action_context}, action_context_{action_context}, host_{std::move(host)}, @@ -104,9 +103,8 @@ ActionPtr EbyteE22LoraModule::Stop() { return {}; } -ActionPtr -EbyteE22LoraModule::WritePacket(ae::ConnectionLoraIndex connect_index, - ae::DataBuffer const& data) { +ActionPtr EbyteE22LoraModule::WritePacket( + ae::ConnectionLoraIndex connect_index, ae::DataBuffer const& data) { if (data.size() > kLoraModuleMTU) { assert(false); return {}; @@ -130,8 +128,7 @@ EbyteE22LoraModule::WritePacket(ae::ConnectionLoraIndex connect_index, return write_notify; } -EbyteE22LoraModule::DataEvent::Subscriber -EbyteE22LoraModule::data_event() { +EbyteE22LoraModule::DataEvent::Subscriber EbyteE22LoraModule::data_event() { return EventSubscriber{data_event_}; } @@ -145,9 +142,7 @@ EbyteE22LoraModule::PowerOff() { return {}; } -std::uint16_t EbyteE22LoraModule::GetMtu(){ - return kLoraModuleMTU; -} +std::uint16_t EbyteE22LoraModule::GetMtu() { return kLoraModuleMTU; } ActionPtr EbyteE22LoraModule::SetLoraModuleAddress(std::uint16_t const& /*address*/) { @@ -180,8 +175,8 @@ ActionPtr EbyteE22LoraModule::OpenLoraConnection( return {}; } -ActionPtr EbyteE22LoraModule::SendData(ConnectionLoraIndex /* connection */, - DataBuffer const& /* data */) { +ActionPtr EbyteE22LoraModule::SendData( + ConnectionLoraIndex /* connection */, DataBuffer const& /* data */) { return {}; } @@ -190,27 +185,16 @@ ActionPtr EbyteE22LoraModule::ReadPacket( return {}; } +void EbyteE22LoraModule::SetupPoll() {} -void EbyteE22LoraModule::SetupPoll() { - -} - -ActionPtr EbyteE22LoraModule::Poll() { - return {}; -} +ActionPtr EbyteE22LoraModule::Poll() { return {}; } void EbyteE22LoraModule::PollEvent(std::int32_t /* handle */, - std::string_view /* flags */) { + std::string_view /* flags */) {} -} +ActionPtr EbyteE22LoraModule::EnterAtMode() { return {}; } -ActionPtr EbyteE22LoraModule::EnterAtMode() { - return {}; -} - -ActionPtr EbyteE22LoraModule::ExitAtMode() { - return {}; -} +ActionPtr EbyteE22LoraModule::ExitAtMode() { return {}; } ActionPtr EbyteE22LoraModule::SetLoraModuleMode( kLoraModuleMode const& mode) { @@ -286,8 +270,8 @@ ActionPtr EbyteE22LoraModule::SetBaudRate(kBaudRate baud_rate) { } return MakeActionPtr(action_context_, Stage([this, it]() { - return at_support_.MakeRequest( - it->second, kWaitOk); + return at_support_.MakeRequest(it->second, + kWaitOk); })); } @@ -310,8 +294,7 @@ ActionPtr EbyteE22LoraModule::SetParity(kParity parity) { } return MakeActionPtr(action_context_, Stage([this, cmd]() { - return at_support_.MakeRequest(cmd, - kWaitOk); + return at_support_.MakeRequest(cmd, kWaitOk); })); } @@ -330,12 +313,10 @@ ActionPtr EbyteE22LoraModule::SetStopBits(kStopBits stop_bits) { break; } - return MakeActionPtr(action_context_, + return MakeActionPtr( + action_context_, - Stage([this, cmd]() { - return at_support_.MakeRequest(cmd, - kWaitOk); - })); + Stage([this, cmd]() { return at_support_.MakeRequest(cmd, kWaitOk); })); } ActionPtr EbyteE22LoraModule::SetupLoraNet( diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 1e7d501c..f4347429 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -139,9 +139,7 @@ ActionPtr LoraModuleTransport::Write(DataBuffer&& in_data) { return ActionPtr{action_context_}; } -void LoraModuleTransport::Connect() { - -} +void LoraModuleTransport::Connect() {} void LoraModuleTransport::OnConnected(ConnectionLoraIndex connection_index) { connection_ = connection_index; @@ -175,7 +173,7 @@ void LoraModuleTransport::DataReceived(ConnectionLoraIndex connection, } if (protocol_ == Protocol::kLora) { DataReceivedLora(data_in); - } + } } void LoraModuleTransport::DataReceivedLora(DataBuffer const& data_in) { diff --git a/aether/transport/lora_modules/lora_module_transport.h b/aether/transport/lora_modules/lora_module_transport.h index a9c0a125..c9dc5182 100644 --- a/aether/transport/lora_modules/lora_module_transport.h +++ b/aether/transport/lora_modules/lora_module_transport.h @@ -37,19 +37,19 @@ class LoraModuleTransport final : public ByteIStream { public: LoraModuleSend(ActionContext action_context, LoraModuleTransport& transport, DataBuffer data); - + private: std::uint16_t max_packet_size_{0}; - protected: + protected: LoraModuleTransport* transport_; - DataBuffer data_; + DataBuffer data_; }; class SendLoraAction final : public LoraModuleSend { public: SendLoraAction(ActionContext action_context, LoraModuleTransport& transport, - DataBuffer data); + DataBuffer data); void Send() override; private: @@ -97,7 +97,7 @@ class LoraModuleTransport final : public ByteIStream { MultiSubscription send_action_subs_; Subscription connection_sub_; Subscription read_packet_sub_; - + std::uint16_t max_packet_size_{0}; }; } // namespace ae From 6f4439297498571cd079bf69bf6f67fb74ec5312 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Tue, 2 Dec 2025 15:41:18 +0300 Subject: [PATCH 05/32] Fixing Ci/Cd build. --- aether/transport/lora_modules/lora_module_transport.cpp | 3 +-- aether/transport/lora_modules/lora_module_transport.h | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index f4347429..4ee2ea32 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -36,8 +36,7 @@ LoraModuleTransport::LoraModuleSend::LoraModuleSend( LoraModuleTransport::SendLoraAction::SendLoraAction( ActionContext action_context, LoraModuleTransport& transport, DataBuffer data) - : LoraModuleSend{action_context, transport, std::move(data)}, - max_packet_size_{std::move(transport_->lora_module_driver_->GetMtu())} {} + : LoraModuleSend{action_context, transport, std::move(data)} {} void LoraModuleTransport::SendLoraAction::Send() { if (state_ == State::kInProgress) { diff --git a/aether/transport/lora_modules/lora_module_transport.h b/aether/transport/lora_modules/lora_module_transport.h index c9dc5182..537c1efc 100644 --- a/aether/transport/lora_modules/lora_module_transport.h +++ b/aether/transport/lora_modules/lora_module_transport.h @@ -37,8 +37,6 @@ class LoraModuleTransport final : public ByteIStream { public: LoraModuleSend(ActionContext action_context, LoraModuleTransport& transport, DataBuffer data); - - private: std::uint16_t max_packet_size_{0}; protected: @@ -55,7 +53,6 @@ class LoraModuleTransport final : public ByteIStream { private: void SendPacket(DataBuffer const& data); MultiSubscription send_subs_; - std::uint16_t max_packet_size_{0}; }; public: From ab01e1d6fe19eb461969ae82ded003abf24726c1 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Tue, 2 Dec 2025 16:15:39 +0300 Subject: [PATCH 06/32] Fixing Ci/Cd. --- aether/transport/lora_modules/lora_module_transport.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 4ee2ea32..506522af 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -30,8 +30,8 @@ LoraModuleTransport::LoraModuleSend::LoraModuleSend( DataBuffer data) : SocketPacketSendAction{action_context}, transport_{&transport}, - data_{std::move(data)}, - max_packet_size_{std::move(transport_->lora_module_driver_->GetMtu())} {} + max_packet_size_{std::move(transport_->lora_module_driver_->GetMtu())}, + data_{std::move(data)} {} LoraModuleTransport::SendLoraAction::SendLoraAction( ActionContext action_context, LoraModuleTransport& transport, From 0a4fa9ac215af40777f78e3f96f75c92fba2e13f Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Tue, 2 Dec 2025 17:49:43 +0300 Subject: [PATCH 07/32] Fixing Ci/Cd. --- aether/lora_modules/ilora_module_driver.h | 2 +- aether/transport/lora_modules/lora_module_transport.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/aether/lora_modules/ilora_module_driver.h b/aether/lora_modules/ilora_module_driver.h index 59cb2089..91b7306a 100644 --- a/aether/lora_modules/ilora_module_driver.h +++ b/aether/lora_modules/ilora_module_driver.h @@ -52,7 +52,7 @@ class ILoraModuleDriver { virtual ActionPtr SetPowerSaveParam( LoraPowerSaveParam const& psp) = 0; virtual ActionPtr PowerOff() = 0; - + virtual std::uint16_t GetMtu() = 0; }; diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 506522af..3233f3ab 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -28,9 +28,9 @@ namespace ae { LoraModuleTransport::LoraModuleSend::LoraModuleSend( ActionContext action_context, LoraModuleTransport& transport, DataBuffer data) - : SocketPacketSendAction{action_context}, - transport_{&transport}, + : SocketPacketSendAction{action_context}, max_packet_size_{std::move(transport_->lora_module_driver_->GetMtu())}, + transport_{&transport}, data_{std::move(data)} {} LoraModuleTransport::SendLoraAction::SendLoraAction( From 39e2c809d69c9e68cc082910c7ac67218b6a108b Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Tue, 2 Dec 2025 17:53:17 +0300 Subject: [PATCH 08/32] Fixing cpp linter. --- aether/transport/lora_modules/lora_module_transport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 3233f3ab..40081d36 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -28,7 +28,7 @@ namespace ae { LoraModuleTransport::LoraModuleSend::LoraModuleSend( ActionContext action_context, LoraModuleTransport& transport, DataBuffer data) - : SocketPacketSendAction{action_context}, + : SocketPacketSendAction{action_context}, max_packet_size_{std::move(transport_->lora_module_driver_->GetMtu())}, transport_{&transport}, data_{std::move(data)} {} From 790991557c2b8e56a8607af27873bce572eb1107 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Wed, 3 Dec 2025 11:01:32 +0300 Subject: [PATCH 09/32] Fixing Ci/Cd. --- aether/lora_modules/ebyte_e22_lm.cpp | 5 +---- aether/lora_modules/ebyte_e22_lm.h | 4 ++-- aether/transport/lora_modules/lora_module_transport.cpp | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/aether/lora_modules/ebyte_e22_lm.cpp b/aether/lora_modules/ebyte_e22_lm.cpp index 8c2f8b57..97ea36c9 100644 --- a/aether/lora_modules/ebyte_e22_lm.cpp +++ b/aether/lora_modules/ebyte_e22_lm.cpp @@ -32,7 +32,6 @@ namespace ae { static constexpr Duration kOneSecond = std::chrono::milliseconds{1000}; static constexpr Duration kTwoSeconds = std::chrono::milliseconds{2000}; -static constexpr Duration kTenSeconds = std::chrono::milliseconds{10000}; static const AtRequest::Wait kWaitOk{"OK", kOneSecond}; static const AtRequest::Wait kWaitOkTwoSeconds{"OK", kTwoSeconds}; static const AtRequest::Wait kWaitEntryAt{"Entry AT", kOneSecond}; @@ -86,9 +85,7 @@ EbyteE22LoraModule::EbyteE22LoraModule(ActionContext action_context, serial_{SerialPortFactory::CreatePort(action_context_, std::move(poller), lora_module_init_.serial_init)}, at_support_{action_context_, *serial_}, - operation_queue_{action_context_}, - initiated_{false}, - started_{false} { + operation_queue_{action_context_}{ Init(); Start(); } diff --git a/aether/lora_modules/ebyte_e22_lm.h b/aether/lora_modules/ebyte_e22_lm.h index 9297f0c4..63df6142 100644 --- a/aether/lora_modules/ebyte_e22_lm.h +++ b/aether/lora_modules/ebyte_e22_lm.h @@ -101,8 +101,8 @@ class EbyteE22LoraModule final : public ILoraModuleDriver { ActionPtr poll_task_; std::unique_ptr poll_listener_; OwnActionPtr operation_queue_; - bool initiated_; - bool started_; + bool initiated_{false}; + bool started_{false}; bool at_mode_{false}; ActionPtr EnterAtMode(); diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 40081d36..8ff5e138 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -29,7 +29,7 @@ LoraModuleTransport::LoraModuleSend::LoraModuleSend( ActionContext action_context, LoraModuleTransport& transport, DataBuffer data) : SocketPacketSendAction{action_context}, - max_packet_size_{std::move(transport_->lora_module_driver_->GetMtu())}, + max_packet_size_{std::move(transport.lora_module_driver_->GetMtu())}, transport_{&transport}, data_{std::move(data)} {} From c092a157b90769dde40759d3b9acfd835ea82643 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Wed, 3 Dec 2025 11:53:41 +0300 Subject: [PATCH 10/32] Fixing Ci/Cd build. --- aether/lora_modules/ebyte_e22_lm.cpp | 2 +- aether/lora_modules/ebyte_e22_lm.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aether/lora_modules/ebyte_e22_lm.cpp b/aether/lora_modules/ebyte_e22_lm.cpp index 97ea36c9..f0817ded 100644 --- a/aether/lora_modules/ebyte_e22_lm.cpp +++ b/aether/lora_modules/ebyte_e22_lm.cpp @@ -85,7 +85,7 @@ EbyteE22LoraModule::EbyteE22LoraModule(ActionContext action_context, serial_{SerialPortFactory::CreatePort(action_context_, std::move(poller), lora_module_init_.serial_init)}, at_support_{action_context_, *serial_}, - operation_queue_{action_context_}{ + operation_queue_{action_context_} { Init(); Start(); } diff --git a/aether/lora_modules/ebyte_e22_lm.h b/aether/lora_modules/ebyte_e22_lm.h index 63df6142..c2bc393e 100644 --- a/aether/lora_modules/ebyte_e22_lm.h +++ b/aether/lora_modules/ebyte_e22_lm.h @@ -101,9 +101,9 @@ class EbyteE22LoraModule final : public ILoraModuleDriver { ActionPtr poll_task_; std::unique_ptr poll_listener_; OwnActionPtr operation_queue_; - bool initiated_{false}; - bool started_{false}; - bool at_mode_{false}; + //bool initiated_{false}; + //bool started_{false}; + //bool at_mode_{false}; ActionPtr EnterAtMode(); ActionPtr ExitAtMode(); From bbea8eeb40d3b0b226af235ee88cfc92babe587e Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Wed, 3 Dec 2025 12:08:32 +0300 Subject: [PATCH 11/32] Fixing cpp linter issues. --- aether/lora_modules/ebyte_e22_lm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aether/lora_modules/ebyte_e22_lm.h b/aether/lora_modules/ebyte_e22_lm.h index c2bc393e..fcde4eb9 100644 --- a/aether/lora_modules/ebyte_e22_lm.h +++ b/aether/lora_modules/ebyte_e22_lm.h @@ -101,9 +101,9 @@ class EbyteE22LoraModule final : public ILoraModuleDriver { ActionPtr poll_task_; std::unique_ptr poll_listener_; OwnActionPtr operation_queue_; - //bool initiated_{false}; - //bool started_{false}; - //bool at_mode_{false}; + // bool initiated_{false}; + // bool started_{false}; + // bool at_mode_{false}; ActionPtr EnterAtMode(); ActionPtr ExitAtMode(); From ce08018eae1f4e064d844c0971f6b4791defbcbb Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Wed, 3 Dec 2025 17:58:22 +0300 Subject: [PATCH 12/32] Updating Lora modules. --- aether/config.h | 2 +- aether/lora_modules/dx_smart_lr02_lm.cpp | 20 ++++++++++++++----- aether/types/small_function.h | 2 +- examples/cloud/aether_construct_lora_module.h | 4 ++-- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/aether/config.h b/aether/config.h index cd11963f..462a0b0a 100644 --- a/aether/config.h +++ b/aether/config.h @@ -120,7 +120,7 @@ #endif #ifndef AE_ENABLE_EBYTE_E22_LM -# define AE_ENABLE_EBYTE_E22_LM 1 +# define AE_ENABLE_EBYTE_E22_LM 0 #endif #ifndef AE_ENABLE_DX_SMART_LR02_LM diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index 55d2f99a..f8eb91d7 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -372,11 +372,11 @@ void DxSmartLr02LoraModule::Init() { Stage([this]() { return at_support_.MakeRequest("AT", kWaitOk); }), Stage([this]() { return SetupSerialPort(lora_module_init_.serial_init); - }), - Stage([this]() { return SetPowerSaveParam(lora_module_init_.psp); }), - Stage([this]() { return SetupLoraNet(lora_module_init_); }), + }), // Exit AT command mode Stage([this]() { return ExitAtMode(); }), + Stage([this]() { return SetPowerSaveParam(lora_module_init_.psp); }), + Stage([this]() { return SetupLoraNet(lora_module_init_); }), Stage(action_context_, [this]() { initiated_ = true; return UpdateStatus::Result(); @@ -415,8 +415,18 @@ ActionPtr DxSmartLr02LoraModule::OpenLoraConnection( } ActionPtr DxSmartLr02LoraModule::SendData( - ConnectionLoraIndex /* connection */, DataBuffer const& /* data */) { - return {}; + ConnectionLoraIndex /* connection */, DataBuffer const& data) { + return MakeActionPtr( + action_context_, + Stage([this, data{data}]() mutable { + return at_support_.MakeRequest( + [this, data{std::move(data)}]() { + auto write_action = ActionPtr{action_context_}; + serial_->Write(data); + write_action->Notify(); + return write_action; + }); + })); } ActionPtr DxSmartLr02LoraModule::ReadPacket( diff --git a/aether/types/small_function.h b/aether/types/small_function.h index 647397b0..44cb4d61 100644 --- a/aether/types/small_function.h +++ b/aether/types/small_function.h @@ -128,7 +128,7 @@ struct MethodPtr { T* instance; }; -static constexpr std::size_t kDefaultSize = sizeof(void*) * 4; +static constexpr std::size_t kDefaultSize = sizeof(void*) * 8; static constexpr std::size_t kDefaultAlignment = alignof(void*); template Date: Wed, 3 Dec 2025 18:02:21 +0300 Subject: [PATCH 13/32] Fixing cpp linter. --- aether/lora_modules/dx_smart_lr02_lm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index f8eb91d7..6fcb9b4f 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -372,7 +372,7 @@ void DxSmartLr02LoraModule::Init() { Stage([this]() { return at_support_.MakeRequest("AT", kWaitOk); }), Stage([this]() { return SetupSerialPort(lora_module_init_.serial_init); - }), + }), // Exit AT command mode Stage([this]() { return ExitAtMode(); }), Stage([this]() { return SetPowerSaveParam(lora_module_init_.psp); }), From 8e0825713f609a68a46b42dbe4e818220833f172 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Thu, 4 Dec 2025 12:54:50 +0300 Subject: [PATCH 14/32] Updating DX Smart LR02 module. --- aether/lora_modules/dx_smart_lr02_lm.cpp | 217 ++++++++++------------- 1 file changed, 91 insertions(+), 126 deletions(-) diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index 6fcb9b4f..033cb576 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -112,10 +112,6 @@ DxSmartLr02LoraModule::Start() { auto pipeline = MakeActionPtr(action_context_, - // Enter AT command mode - Stage([this]() { return EnterAtMode(); }), - // Exit AT command mode - Stage([this]() { return ExitAtMode(); }), // save it's started Stage(action_context_, [this]() { started_ = true; @@ -196,44 +192,36 @@ ActionPtr DxSmartLr02LoraModule::SetPowerSaveParam(LoraPowerSaveParam const& psp) { auto lora_module_operation = ActionPtr{action_context_}; - operation_queue_->Push(Stage([this, lora_module_operation, psp{psp}]() { - auto pipeline = MakeActionPtr( - action_context_, - // Enter AT command mode - Stage([this]() { return EnterAtMode(); }), - // Configure Lora Module Mode - Stage( - [this, psp]() { return SetLoraModuleMode(psp.lora_module_mode); }), - // Configure Lora Module Level - Stage([this, psp]() { - return SetLoraModuleLevel(psp.lora_module_level); - }), - // Configure Lora Module Power - Stage([this, psp]() { - return SetLoraModulePower(psp.lora_module_power); - }), - // Configure Lora Module BandWidth - Stage([this, psp]() { - return SetLoraModuleBandWidth(psp.lora_module_band_width); - }), - // Configure Lora Module Coding Rate - Stage([this, psp]() { - return SetLoraModuleCodingRate(psp.lora_module_coding_rate); - }), - // Configure Lora Module Spreading Factor - Stage([this, psp]() { - return SetLoraModuleSpreadingFactor(psp.lora_module_spreading_factor); - }), - // Exit AT command mode - Stage([this]() { return ExitAtMode(); })); - pipeline->StatusEvent().Subscribe(ActionHandler{ - OnResult{ - [lora_module_operation]() { lora_module_operation->Notify(); }}, - OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, - OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); - - return pipeline; - })); + auto pipeline = MakeActionPtr( + action_context_, + // Enter AT command mode + Stage([this]() { return EnterAtMode(); }), + // Configure Lora Module Mode + Stage([this, psp]() { return SetLoraModuleMode(psp.lora_module_mode); }), + // Configure Lora Module Level + Stage( + [this, psp]() { return SetLoraModuleLevel(psp.lora_module_level); }), + // Configure Lora Module Power + Stage( + [this, psp]() { return SetLoraModulePower(psp.lora_module_power); }), + // Configure Lora Module BandWidth + Stage([this, psp]() { + return SetLoraModuleBandWidth(psp.lora_module_band_width); + }), + // Configure Lora Module Coding Rate + Stage([this, psp]() { + return SetLoraModuleCodingRate(psp.lora_module_coding_rate); + }), + // Configure Lora Module Spreading Factor + Stage([this, psp]() { + return SetLoraModuleSpreadingFactor(psp.lora_module_spreading_factor); + }), + // Exit AT command mode + Stage([this]() { return ExitAtMode(); })); + pipeline->StatusEvent().Subscribe(ActionHandler{ + OnResult{[lora_module_operation]() { lora_module_operation->Notify(); }}, + OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, + OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); return lora_module_operation; } @@ -249,25 +237,20 @@ ActionPtr DxSmartLr02LoraModule::SetLoraModuleAddress(std::uint16_t const& address) { auto lora_module_operation = ActionPtr{action_context_}; - operation_queue_->Push(Stage([this, lora_module_operation, address]() { - auto pipeline = MakeActionPtr( - action_context_, - // Enter AT command mode - Stage([this]() { return EnterAtMode(); }), Stage([this, address]() { - return at_support_.MakeRequest("AT+MAC" + AdressToString(address), - kWaitOk); - }), - // Exit AT command mode - Stage([this]() { return ExitAtMode(); })); - - pipeline->StatusEvent().Subscribe(ActionHandler{ - OnResult{ - [lora_module_operation]() { lora_module_operation->Notify(); }}, - OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, - OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); + auto pipeline = MakeActionPtr( + action_context_, + // Enter AT command mode + Stage([this]() { return EnterAtMode(); }), Stage([this, address]() { + return at_support_.MakeRequest("AT+MAC" + AdressToString(address), + kWaitOk); + }), + // Exit AT command mode + Stage([this]() { return ExitAtMode(); })); - return pipeline; - })); + pipeline->StatusEvent().Subscribe(ActionHandler{ + OnResult{[lora_module_operation]() { lora_module_operation->Notify(); }}, + OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, + OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); return lora_module_operation; } @@ -280,25 +263,20 @@ DxSmartLr02LoraModule::SetLoraModuleChannel(std::uint8_t const& channel) { auto lora_module_operation = ActionPtr{action_context_}; - operation_queue_->Push(Stage([this, lora_module_operation, channel]() { - auto pipeline = MakeActionPtr( - action_context_, - // Enter AT command mode - Stage([this]() { return EnterAtMode(); }), Stage([this, channel]() { - return at_support_.MakeRequest( - "AT+CHANNEL" + ChannelToString(channel), kWaitOk); - }), - // Exit AT command mode - Stage([this]() { return ExitAtMode(); })); - - pipeline->StatusEvent().Subscribe(ActionHandler{ - OnResult{ - [lora_module_operation]() { lora_module_operation->Notify(); }}, - OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, - OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); + auto pipeline = MakeActionPtr( + action_context_, + // Enter AT command mode + Stage([this]() { return EnterAtMode(); }), Stage([this, channel]() { + return at_support_.MakeRequest("AT+CHANNEL" + ChannelToString(channel), + kWaitOk); + }), + // Exit AT command mode + Stage([this]() { return ExitAtMode(); })); - return pipeline; - })); + pipeline->StatusEvent().Subscribe(ActionHandler{ + OnResult{[lora_module_operation]() { lora_module_operation->Notify(); }}, + OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, + OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); return lora_module_operation; } @@ -308,25 +286,20 @@ DxSmartLr02LoraModule::SetLoraModuleCRCCheck( kLoraModuleCRCCheck const& crc_check) { auto lora_module_operation = ActionPtr{action_context_}; - operation_queue_->Push(Stage([this, lora_module_operation, crc_check]() { - auto pipeline = MakeActionPtr( - action_context_, - // Enter AT command mode - Stage([this]() { return EnterAtMode(); }), Stage([this, crc_check]() { - return at_support_.MakeRequest( - "AT+CRC" + std::to_string(static_cast(crc_check)), kWaitOk); - }), - // Exit AT command mode - Stage([this]() { return ExitAtMode(); })); + auto pipeline = MakeActionPtr( + action_context_, + // Enter AT command mode + Stage([this]() { return EnterAtMode(); }), Stage([this, crc_check]() { + return at_support_.MakeRequest( + "AT+CRC" + std::to_string(static_cast(crc_check)), kWaitOk); + }), + // Exit AT command mode + Stage([this]() { return ExitAtMode(); })); - pipeline->StatusEvent().Subscribe(ActionHandler{ - OnResult{ - [lora_module_operation]() { lora_module_operation->Notify(); }}, - OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, - OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); - - return pipeline; - })); + pipeline->StatusEvent().Subscribe(ActionHandler{ + OnResult{[lora_module_operation]() { lora_module_operation->Notify(); }}, + OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, + OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); return lora_module_operation; } @@ -336,28 +309,22 @@ DxSmartLr02LoraModule::SetLoraModuleIQSignalInversion( kLoraModuleIQSignalInversion const& signal_inversion) { auto lora_module_operation = ActionPtr{action_context_}; - operation_queue_->Push(Stage([this, lora_module_operation, - signal_inversion]() { - auto pipeline = MakeActionPtr( - action_context_, - // Enter AT command mode - Stage([this]() { return EnterAtMode(); }), - Stage([this, signal_inversion]() { - return at_support_.MakeRequest( - "AT+IQ" + std::to_string(static_cast(signal_inversion)), - kWaitOk); - }), - // Exit AT command mode - Stage([this]() { return ExitAtMode(); })); - - pipeline->StatusEvent().Subscribe(ActionHandler{ - OnResult{ - [lora_module_operation]() { lora_module_operation->Notify(); }}, - OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, - OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); + auto pipeline = MakeActionPtr( + action_context_, + // Enter AT command mode + Stage([this]() { return EnterAtMode(); }), + Stage([this, signal_inversion]() { + return at_support_.MakeRequest( + "AT+IQ" + std::to_string(static_cast(signal_inversion)), + kWaitOk); + }), + // Exit AT command mode + Stage([this]() { return ExitAtMode(); })); - return pipeline; - })); + pipeline->StatusEvent().Subscribe(ActionHandler{ + OnResult{[lora_module_operation]() { lora_module_operation->Notify(); }}, + OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, + OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); return lora_module_operation; } @@ -417,15 +384,13 @@ ActionPtr DxSmartLr02LoraModule::OpenLoraConnection( ActionPtr DxSmartLr02LoraModule::SendData( ConnectionLoraIndex /* connection */, DataBuffer const& data) { return MakeActionPtr( - action_context_, - Stage([this, data{data}]() mutable { - return at_support_.MakeRequest( - [this, data{std::move(data)}]() { - auto write_action = ActionPtr{action_context_}; - serial_->Write(data); - write_action->Notify(); - return write_action; - }); + action_context_, Stage([this, data{data}]() mutable { + return at_support_.MakeRequest([this, data{std::move(data)}]() { + auto write_action = ActionPtr{action_context_}; + serial_->Write(data); + write_action->Notify(); + return write_action; + }); })); } From 9810b41737ae2b30eb97ca00eca346fe4f10b247 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Thu, 4 Dec 2025 17:57:42 +0300 Subject: [PATCH 15/32] Updating Lora modules. --- aether/config.h | 2 +- aether/lora_modules/dx_smart_lr02_lm.cpp | 91 ++++--------------- aether/lora_modules/dx_smart_lr02_lm.h | 8 +- aether/lora_modules/ebyte_e22_lm.cpp | 7 -- aether/lora_modules/ebyte_e22_lm.h | 4 - .../lora_modules/lora_module_transport.cpp | 11 ++- 6 files changed, 28 insertions(+), 95 deletions(-) diff --git a/aether/config.h b/aether/config.h index 462a0b0a..180b0342 100644 --- a/aether/config.h +++ b/aether/config.h @@ -200,7 +200,7 @@ #endif // default value used for connection timeout, until statistics are available #ifndef AE_DEFAULT_CONNECTION_TIMEOUT_MS -# define AE_DEFAULT_CONNECTION_TIMEOUT_MS 5000 +# define AE_DEFAULT_CONNECTION_TIMEOUT_MS 15000 #endif // window size for server answear to ping statistics diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index 033cb576..03b6fd04 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -115,7 +115,6 @@ DxSmartLr02LoraModule::Start() { // save it's started Stage(action_context_, [this]() { started_ = true; - SetupPoll(); return UpdateStatus::Result(); })); @@ -218,10 +217,11 @@ DxSmartLr02LoraModule::SetPowerSaveParam(LoraPowerSaveParam const& psp) { }), // Exit AT command mode Stage([this]() { return ExitAtMode(); })); + pipeline->StatusEvent().Subscribe(ActionHandler{ OnResult{[lora_module_operation]() { lora_module_operation->Notify(); }}, OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, - OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); + OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); return lora_module_operation; } @@ -333,15 +333,8 @@ DxSmartLr02LoraModule::SetLoraModuleIQSignalInversion( void DxSmartLr02LoraModule::Init() { operation_queue_->Push(Stage([this]() { auto init_pipeline = MakeActionPtr( - action_context_, - // Enter AT command mode - Stage([this]() { return EnterAtMode(); }), - Stage([this]() { return at_support_.MakeRequest("AT", kWaitOk); }), - Stage([this]() { - return SetupSerialPort(lora_module_init_.serial_init); - }), - // Exit AT command mode - Stage([this]() { return ExitAtMode(); }), + action_context_, + Stage([this]() { return SetupSerialPort(lora_module_init_.serial_init); }), Stage([this]() { return SetPowerSaveParam(lora_module_init_.psp); }), Stage([this]() { return SetupLoraNet(lora_module_init_); }), Stage(action_context_, [this]() { @@ -399,61 +392,6 @@ ActionPtr DxSmartLr02LoraModule::ReadPacket( return {}; } -void DxSmartLr02LoraModule::SetupPoll() { - poll_listener_ = at_support_.ListenForResponse( - "#XPOLL: ", [this](auto& at_buffer, auto pos) { - std::int32_t handle{}; - std::string flags; - AtSupport::ParseResponse(*pos, "#XPOLL", handle, flags); - PollEvent(handle, flags); - return at_buffer.erase(pos); - }); - - // TODO: config for poll interval - poll_task_ = ActionPtr{ - action_context_, - [this]() { - if (connections_.empty()) { - return; - } - // add poll to operation queue - operation_queue_->Push(Stage([this]() { return Poll(); })); - }, - std::chrono::milliseconds{100}}; -} - -ActionPtr DxSmartLr02LoraModule::Poll() { - return MakeActionPtr(action_context_, Stage([this]() { - std::string handles; - for (auto ci : connections_) { - handles += "," + std::to_string(ci); - } - return at_support_.MakeRequest( - "#XPOLL=0" + handles, kWaitOk); - })); -} - -void DxSmartLr02LoraModule::PollEvent(std::int32_t handle, - std::string_view flags) { - auto flags_val = FromChars(flags); - if (!flags_val) { - return; - } - - // get connection index - auto it = connections_.find(static_cast(handle)); - if (it == std::end(connections_)) { - AE_TELED_ERROR("Poll unknown handle {}", handle); - return; - } - - constexpr std::uint32_t kPollIn = 0x01; - if (*flags_val | kPollIn) { - operation_queue_->Push( - Stage([this, connection{*it}]() { return ReadPacket(connection); })); - } -} - ActionPtr DxSmartLr02LoraModule::EnterAtMode() { if (at_mode_ == false) { at_mode_ = true; @@ -534,15 +472,17 @@ ActionPtr DxSmartLr02LoraModule::SetLoraModuleSpreadingFactor( } ActionPtr DxSmartLr02LoraModule::SetupSerialPort( - SerialInit& serial_init) { + SerialInit const& serial_init) { return MakeActionPtr( - action_context_, Stage([this, serial_init]() { - return SetBaudRate(serial_init.baud_rate); - }), + action_context_, + // Enter AT command mode + Stage([this]() { return EnterAtMode(); }), + Stage([this, serial_init]() { return SetBaudRate(serial_init.baud_rate); }), Stage([this, serial_init]() { return SetParity(serial_init.parity); }), - Stage([this, serial_init]() { - return SetStopBits(serial_init.stop_bits); - })); + Stage([this, serial_init]() { return SetStopBits(serial_init.stop_bits); }), + // Exit AT command mode + Stage([this]() { return ExitAtMode(); }) + ); } ActionPtr DxSmartLr02LoraModule::SetBaudRate(kBaudRate baud_rate) { @@ -602,9 +542,10 @@ ActionPtr DxSmartLr02LoraModule::SetStopBits(kStopBits stop_bits) { } ActionPtr DxSmartLr02LoraModule::SetupLoraNet( - LoraModuleInit& lora_module_init) { + LoraModuleInit const& lora_module_init) { return MakeActionPtr( - action_context_, Stage([this, lora_module_init]() { + action_context_, + Stage([this, lora_module_init]() { return SetLoraModuleAddress(lora_module_init.lora_module_my_adress); }), Stage([this, lora_module_init]() { diff --git a/aether/lora_modules/dx_smart_lr02_lm.h b/aether/lora_modules/dx_smart_lr02_lm.h index 3b45852b..88106036 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.h +++ b/aether/lora_modules/dx_smart_lr02_lm.h @@ -87,10 +87,6 @@ class DxSmartLr02LoraModule final : public ILoraModuleDriver { DataBuffer const& data); ActionPtr ReadPacket(ConnectionLoraIndex connection); - void SetupPoll(); - ActionPtr Poll(); - void PollEvent(std::int32_t handle, std::string_view flags); - ActionContext action_context_; LoraModuleInit lora_module_init_; std::unique_ptr serial_; @@ -121,12 +117,12 @@ class DxSmartLr02LoraModule final : public ILoraModuleDriver { kLoraModuleSpreadingFactor const& spreading_factor); // Module spreading factor - ActionPtr SetupSerialPort(SerialInit& serial_init); + ActionPtr SetupSerialPort(SerialInit const& serial_init); ActionPtr SetBaudRate(kBaudRate baud_rate); ActionPtr SetParity(kParity parity); ActionPtr SetStopBits(kStopBits stop_bits); - ActionPtr SetupLoraNet(LoraModuleInit& lora_module_init); + ActionPtr SetupLoraNet(LoraModuleInit const& lora_module_init); std::string AdressToString(uint16_t value); std::string ChannelToString(uint8_t value); diff --git a/aether/lora_modules/ebyte_e22_lm.cpp b/aether/lora_modules/ebyte_e22_lm.cpp index f0817ded..86111986 100644 --- a/aether/lora_modules/ebyte_e22_lm.cpp +++ b/aether/lora_modules/ebyte_e22_lm.cpp @@ -182,13 +182,6 @@ ActionPtr EbyteE22LoraModule::ReadPacket( return {}; } -void EbyteE22LoraModule::SetupPoll() {} - -ActionPtr EbyteE22LoraModule::Poll() { return {}; } - -void EbyteE22LoraModule::PollEvent(std::int32_t /* handle */, - std::string_view /* flags */) {} - ActionPtr EbyteE22LoraModule::EnterAtMode() { return {}; } ActionPtr EbyteE22LoraModule::ExitAtMode() { return {}; } diff --git a/aether/lora_modules/ebyte_e22_lm.h b/aether/lora_modules/ebyte_e22_lm.h index fcde4eb9..c8da94b7 100644 --- a/aether/lora_modules/ebyte_e22_lm.h +++ b/aether/lora_modules/ebyte_e22_lm.h @@ -88,10 +88,6 @@ class EbyteE22LoraModule final : public ILoraModuleDriver { DataBuffer const& data); ActionPtr ReadPacket(ConnectionLoraIndex connection); - void SetupPoll(); - ActionPtr Poll(); - void PollEvent(std::int32_t handle, std::string_view flags); - ActionContext action_context_; LoraModuleInit lora_module_init_; std::unique_ptr serial_; diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 8ff5e138..8cffa737 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -123,6 +123,10 @@ void LoraModuleTransport::Restream() { ActionPtr LoraModuleTransport::Write(DataBuffer&& in_data) { AE_TELE_DEBUG(kLoraModuleTransportSend, "Send data size {}", in_data.size()); + if (protocol_ == Protocol::kTcp || protocol_ == Protocol::kUdp) { + protocol_ = Protocol::kLora; + } + if (protocol_ == Protocol::kLora) { auto send_action = send_action_queue_manager_->AddPacket( ActionPtr{action_context_, *this, std::move(in_data)}); @@ -138,7 +142,11 @@ ActionPtr LoraModuleTransport::Write(DataBuffer&& in_data) { return ActionPtr{action_context_}; } -void LoraModuleTransport::Connect() {} +void LoraModuleTransport::Connect() { + ConnectionLoraIndex connection_index{}; + + OnConnected(connection_index); +} void LoraModuleTransport::OnConnected(ConnectionLoraIndex connection_index) { connection_ = connection_index; @@ -161,7 +169,6 @@ void LoraModuleTransport::Disconnect() { return; } - /* lora_module_driver_->CloseNetwork(connection_);*/ connection_ = kInvalidConnectionLoraIndex; } From 1e65f54cbafd147447ad2eef1e07cd4efd6b70cb Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Fri, 5 Dec 2025 18:01:31 +0300 Subject: [PATCH 16/32] Updating Lora modules. --- aether/lora_modules/dx_smart_lr02_lm.cpp | 21 +++++++++++++++++- aether/lora_modules/dx_smart_lr02_lm.h | 3 +++ .../lora_modules/lora_module_transport.cpp | 22 +++++++++++++++---- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index 03b6fd04..890ce4dd 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -115,6 +115,7 @@ DxSmartLr02LoraModule::Start() { // save it's started Stage(action_context_, [this]() { started_ = true; + SetupPoll(); return UpdateStatus::Result(); })); @@ -389,7 +390,25 @@ ActionPtr DxSmartLr02LoraModule::SendData( ActionPtr DxSmartLr02LoraModule::ReadPacket( ConnectionLoraIndex /* connection */) { - return {}; + return {}; +} + +void DxSmartLr02LoraModule::SetupPoll() { + poll_listener_ = + at_support_.ListenForResponse("", [this](auto&, auto pos) { + std::int32_t cid{}; + AtSupport::ParseResponse(*pos, "", cid); + PollEvent(); + }); +} + +void DxSmartLr02LoraModule::PollEvent() { + ConnectionLoraIndex connection{}; + // get connection index + + AE_TELED_DEBUG("Data available for connection"); + operation_queue_->Push(Stage( + [this, connection{connection}]() { return ReadPacket(connection); })); } ActionPtr DxSmartLr02LoraModule::EnterAtMode() { diff --git a/aether/lora_modules/dx_smart_lr02_lm.h b/aether/lora_modules/dx_smart_lr02_lm.h index 88106036..3c839216 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.h +++ b/aether/lora_modules/dx_smart_lr02_lm.h @@ -87,6 +87,9 @@ class DxSmartLr02LoraModule final : public ILoraModuleDriver { DataBuffer const& data); ActionPtr ReadPacket(ConnectionLoraIndex connection); + void SetupPoll(); + void PollEvent(); + ActionContext action_context_; LoraModuleInit lora_module_init_; std::unique_ptr serial_; diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 8cffa737..63de02fd 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -121,13 +121,15 @@ void LoraModuleTransport::Restream() { } ActionPtr LoraModuleTransport::Write(DataBuffer&& in_data) { + Protocol proto{Protocol::kTcp}; + AE_TELE_DEBUG(kLoraModuleTransportSend, "Send data size {}", in_data.size()); if (protocol_ == Protocol::kTcp || protocol_ == Protocol::kUdp) { - protocol_ = Protocol::kLora; + proto = Protocol::kLora; } - if (protocol_ == Protocol::kLora) { + if (proto == Protocol::kLora) { auto send_action = send_action_queue_manager_->AddPacket( ActionPtr{action_context_, *this, std::move(in_data)}); send_action_subs_.Push( @@ -174,16 +176,28 @@ void LoraModuleTransport::Disconnect() { void LoraModuleTransport::DataReceived(ConnectionLoraIndex connection, DataBuffer const& data_in) { + Protocol proto{Protocol::kTcp}; + if (connection_ != connection) { return; } - if (protocol_ == Protocol::kLora) { + + if (protocol_ == Protocol::kTcp || protocol_ == Protocol::kUdp) { + proto = Protocol::kLora; + } + + if (proto == Protocol::kLora) { DataReceivedLora(data_in); } } void LoraModuleTransport::DataReceivedLora(DataBuffer const& data_in) { - out_data_event_.Emit(data_in); + data_packet_collector_.AddData(data_in.data(), data_in.size()); + for (auto data = data_packet_collector_.PopPacket(); !data.empty(); + data = data_packet_collector_.PopPacket()) { + AE_TELE_DEBUG(kModemTransportReceive, "Receive data size {}", data.size()); + out_data_event_.Emit(data); + } } } // namespace ae From 30a44be523c7a0188b973a67adcbb354211cb1b1 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Mon, 8 Dec 2025 14:39:29 +0300 Subject: [PATCH 17/32] Updating Lora modules. --- aether/lora_modules/dx_smart_lr02_lm.cpp | 28 ++++++------------------ aether/lora_modules/dx_smart_lr02_lm.h | 5 +---- aether/lora_modules/ebyte_e22_lm.cpp | 5 ++--- aether/lora_modules/ebyte_e22_lm.h | 2 +- 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index 890ce4dd..92499a75 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -89,6 +89,7 @@ DxSmartLr02LoraModule::DxSmartLr02LoraModule(ActionContext action_context, operation_queue_{action_context_}, initiated_{false}, started_{false} { + serial_->read_event().Subscribe(MethodPtr<&DxSmartLr02LoraModule::ReadPacket>{this}); Init(); Start(); } @@ -115,7 +116,7 @@ DxSmartLr02LoraModule::Start() { // save it's started Stage(action_context_, [this]() { started_ = true; - SetupPoll(); + //SetupPoll(); return UpdateStatus::Result(); })); @@ -388,27 +389,12 @@ ActionPtr DxSmartLr02LoraModule::SendData( })); } -ActionPtr DxSmartLr02LoraModule::ReadPacket( - ConnectionLoraIndex /* connection */) { - return {}; -} - -void DxSmartLr02LoraModule::SetupPoll() { - poll_listener_ = - at_support_.ListenForResponse("", [this](auto&, auto pos) { - std::int32_t cid{}; - AtSupport::ParseResponse(*pos, "", cid); - PollEvent(); - }); -} - -void DxSmartLr02LoraModule::PollEvent() { +void DxSmartLr02LoraModule::ReadPacket(DataBuffer const& data) { ConnectionLoraIndex connection{}; - // get connection index - - AE_TELED_DEBUG("Data available for connection"); - operation_queue_->Push(Stage( - [this, connection{connection}]() { return ReadPacket(connection); })); + + AE_TELED_DEBUG("Received {} bytes.", data.size()); + // Emit the received data + data_event_.Emit(connection, data); } ActionPtr DxSmartLr02LoraModule::EnterAtMode() { diff --git a/aether/lora_modules/dx_smart_lr02_lm.h b/aether/lora_modules/dx_smart_lr02_lm.h index 3c839216..d3882a2d 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.h +++ b/aether/lora_modules/dx_smart_lr02_lm.h @@ -85,10 +85,7 @@ class DxSmartLr02LoraModule final : public ILoraModuleDriver { ActionPtr SendData(ConnectionLoraIndex connection, DataBuffer const& data); - ActionPtr ReadPacket(ConnectionLoraIndex connection); - - void SetupPoll(); - void PollEvent(); + void ReadPacket(DataBuffer const& data); ActionContext action_context_; LoraModuleInit lora_module_init_; diff --git a/aether/lora_modules/ebyte_e22_lm.cpp b/aether/lora_modules/ebyte_e22_lm.cpp index 86111986..685e26d6 100644 --- a/aether/lora_modules/ebyte_e22_lm.cpp +++ b/aether/lora_modules/ebyte_e22_lm.cpp @@ -177,9 +177,8 @@ ActionPtr EbyteE22LoraModule::SendData( return {}; } -ActionPtr EbyteE22LoraModule::ReadPacket( - ConnectionLoraIndex /* connection */) { - return {}; +void EbyteE22LoraModule::ReadPacket( + DataBuffer const& /* data */) { } ActionPtr EbyteE22LoraModule::EnterAtMode() { return {}; } diff --git a/aether/lora_modules/ebyte_e22_lm.h b/aether/lora_modules/ebyte_e22_lm.h index c8da94b7..94eacf8a 100644 --- a/aether/lora_modules/ebyte_e22_lm.h +++ b/aether/lora_modules/ebyte_e22_lm.h @@ -86,7 +86,7 @@ class EbyteE22LoraModule final : public ILoraModuleDriver { ActionPtr SendData(ConnectionLoraIndex connection, DataBuffer const& data); - ActionPtr ReadPacket(ConnectionLoraIndex connection); + void ReadPacket(DataBuffer const& data); ActionContext action_context_; LoraModuleInit lora_module_init_; From 6ceab4cfe9015f23a3806eb34c32cc4416a4712d Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Mon, 8 Dec 2025 15:45:15 +0300 Subject: [PATCH 18/32] Fixing SmallFunction issue. --- aether/serial_ports/at_support/at_request.h | 3 ++- aether/types/small_function.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/aether/serial_ports/at_support/at_request.h b/aether/serial_ports/at_support/at_request.h index 26aca89b..f9dea097 100644 --- a/aether/serial_ports/at_support/at_request.h +++ b/aether/serial_ports/at_support/at_request.h @@ -47,7 +47,8 @@ class AtRequest final : public Action { kError, }; - using CommandMaker = SmallFunction()>; + // using CommandMaker = SmallFunction()>; + using CommandMaker = std::function()>; struct Command { std::variant command; diff --git a/aether/types/small_function.h b/aether/types/small_function.h index 44cb4d61..647397b0 100644 --- a/aether/types/small_function.h +++ b/aether/types/small_function.h @@ -128,7 +128,7 @@ struct MethodPtr { T* instance; }; -static constexpr std::size_t kDefaultSize = sizeof(void*) * 8; +static constexpr std::size_t kDefaultSize = sizeof(void*) * 4; static constexpr std::size_t kDefaultAlignment = alignof(void*); template Date: Mon, 8 Dec 2025 17:45:54 +0300 Subject: [PATCH 19/32] Fixing cpp linter issues. --- aether/lora_modules/dx_smart_lr02_lm.cpp | 28 ++++++++++--------- aether/lora_modules/dx_smart_lr02_lm.h | 2 +- .../lora_modules/lora_module_transport.cpp | 10 +++---- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index 92499a75..f630384f 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -89,7 +89,8 @@ DxSmartLr02LoraModule::DxSmartLr02LoraModule(ActionContext action_context, operation_queue_{action_context_}, initiated_{false}, started_{false} { - serial_->read_event().Subscribe(MethodPtr<&DxSmartLr02LoraModule::ReadPacket>{this}); + serial_->read_event().Subscribe( + MethodPtr<&DxSmartLr02LoraModule::ReadPacket>{this}); Init(); Start(); } @@ -116,7 +117,7 @@ DxSmartLr02LoraModule::Start() { // save it's started Stage(action_context_, [this]() { started_ = true; - //SetupPoll(); + // SetupPoll(); return UpdateStatus::Result(); })); @@ -223,7 +224,7 @@ DxSmartLr02LoraModule::SetPowerSaveParam(LoraPowerSaveParam const& psp) { pipeline->StatusEvent().Subscribe(ActionHandler{ OnResult{[lora_module_operation]() { lora_module_operation->Notify(); }}, OnError{[lora_module_operation]() { lora_module_operation->Failed(); }}, - OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); + OnStop{[lora_module_operation]() { lora_module_operation->Stop(); }}}); return lora_module_operation; } @@ -335,8 +336,9 @@ DxSmartLr02LoraModule::SetLoraModuleIQSignalInversion( void DxSmartLr02LoraModule::Init() { operation_queue_->Push(Stage([this]() { auto init_pipeline = MakeActionPtr( - action_context_, - Stage([this]() { return SetupSerialPort(lora_module_init_.serial_init); }), + action_context_, Stage([this]() { + return SetupSerialPort(lora_module_init_.serial_init); + }), Stage([this]() { return SetPowerSaveParam(lora_module_init_.psp); }), Stage([this]() { return SetupLoraNet(lora_module_init_); }), Stage(action_context_, [this]() { @@ -391,7 +393,7 @@ ActionPtr DxSmartLr02LoraModule::SendData( void DxSmartLr02LoraModule::ReadPacket(DataBuffer const& data) { ConnectionLoraIndex connection{}; - + AE_TELED_DEBUG("Received {} bytes.", data.size()); // Emit the received data data_event_.Emit(connection, data); @@ -481,13 +483,14 @@ ActionPtr DxSmartLr02LoraModule::SetupSerialPort( return MakeActionPtr( action_context_, // Enter AT command mode - Stage([this]() { return EnterAtMode(); }), - Stage([this, serial_init]() { return SetBaudRate(serial_init.baud_rate); }), + Stage([this]() { return EnterAtMode(); }), Stage([this, serial_init]() { + return SetBaudRate(serial_init.baud_rate); + }), Stage([this, serial_init]() { return SetParity(serial_init.parity); }), - Stage([this, serial_init]() { return SetStopBits(serial_init.stop_bits); }), + Stage( + [this, serial_init]() { return SetStopBits(serial_init.stop_bits); }), // Exit AT command mode - Stage([this]() { return ExitAtMode(); }) - ); + Stage([this]() { return ExitAtMode(); })); } ActionPtr DxSmartLr02LoraModule::SetBaudRate(kBaudRate baud_rate) { @@ -549,8 +552,7 @@ ActionPtr DxSmartLr02LoraModule::SetStopBits(kStopBits stop_bits) { ActionPtr DxSmartLr02LoraModule::SetupLoraNet( LoraModuleInit const& lora_module_init) { return MakeActionPtr( - action_context_, - Stage([this, lora_module_init]() { + action_context_, Stage([this, lora_module_init]() { return SetLoraModuleAddress(lora_module_init.lora_module_my_adress); }), Stage([this, lora_module_init]() { diff --git a/aether/lora_modules/dx_smart_lr02_lm.h b/aether/lora_modules/dx_smart_lr02_lm.h index d3882a2d..7dcb4a23 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.h +++ b/aether/lora_modules/dx_smart_lr02_lm.h @@ -86,7 +86,7 @@ class DxSmartLr02LoraModule final : public ILoraModuleDriver { ActionPtr SendData(ConnectionLoraIndex connection, DataBuffer const& data); void ReadPacket(DataBuffer const& data); - + ActionContext action_context_; LoraModuleInit lora_module_init_; std::unique_ptr serial_; diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 63de02fd..2c9b5d8b 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -122,7 +122,7 @@ void LoraModuleTransport::Restream() { ActionPtr LoraModuleTransport::Write(DataBuffer&& in_data) { Protocol proto{Protocol::kTcp}; - + AE_TELE_DEBUG(kLoraModuleTransportSend, "Send data size {}", in_data.size()); if (protocol_ == Protocol::kTcp || protocol_ == Protocol::kUdp) { @@ -146,7 +146,7 @@ ActionPtr LoraModuleTransport::Write(DataBuffer&& in_data) { void LoraModuleTransport::Connect() { ConnectionLoraIndex connection_index{}; - + OnConnected(connection_index); } @@ -177,15 +177,15 @@ void LoraModuleTransport::Disconnect() { void LoraModuleTransport::DataReceived(ConnectionLoraIndex connection, DataBuffer const& data_in) { Protocol proto{Protocol::kTcp}; - + if (connection_ != connection) { return; } - + if (protocol_ == Protocol::kTcp || protocol_ == Protocol::kUdp) { proto = Protocol::kLora; } - + if (proto == Protocol::kLora) { DataReceivedLora(data_in); } From ab678a93d460b5eea88ab7bb7417f04240c50de5 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Wed, 10 Dec 2025 16:20:32 +0300 Subject: [PATCH 20/32] Adding gateway Lora device. --- aether/CMakeLists.txt | 37 +++++++----------- aether/lora_modules/gw_lora_device.cpp | 23 +++++++++++ aether/lora_modules/gw_lora_device.h | 54 ++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 aether/lora_modules/gw_lora_device.cpp create mode 100644 aether/lora_modules/gw_lora_device.h diff --git a/aether/CMakeLists.txt b/aether/CMakeLists.txt index 432b8cc1..8ce7f794 100644 --- a/aether/CMakeLists.txt +++ b/aether/CMakeLists.txt @@ -36,8 +36,7 @@ list(APPEND common_dependencies "../third_party/libsodium" "../third_party/gcem" "../third_party/etl" - "../third_party/aethernet-numeric" -) + "../third_party/aethernet-numeric") # for etl set(GIT_DIR_LOOKUP_POLICY ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR) @@ -56,8 +55,7 @@ list(APPEND aether_srcs list(APPEND aether_c_api_srcs "aether_c/c_uid.cpp" - "aether_c/aether_capi.cpp" -) + "aether_c/aether_capi.cpp") list(APPEND types_srcs "types/address.cpp" @@ -86,14 +84,12 @@ list(APPEND obj_srcs "obj/domain.cpp" "obj/obj_id.cpp" "obj/registry.cpp" - "obj/obj_ptr.cpp" - ) + "obj/obj_ptr.cpp") list(APPEND ptr_srcs "ptr/ptr.cpp" "ptr/ptr_view.cpp" - "ptr/ref_tree.cpp" - ) + "ptr/ref_tree.cpp") list(APPEND actions_srcs "ae_actions/get_client_cloud.cpp" @@ -107,8 +103,7 @@ list(APPEND actions_srcs "actions/action_processor.cpp" "actions/timer_action.cpp" "actions/task_queue.cpp" - "actions/repeatable_task.cpp" - ) + "actions/repeatable_task.cpp") list(APPEND registration_srcs "registration/api/client_reg_api_safe.cpp" @@ -132,8 +127,7 @@ list(APPEND adapters_srcs "adapters/modem_adapter.cpp" "adapters/parent_lora_module.cpp" "adapters/parent_modem.cpp" - "adapters/parent_wifi.cpp" - ) + "adapters/parent_wifi.cpp") list(APPEND access_points_srcs "access_points/access_point.cpp" @@ -151,6 +145,7 @@ list(APPEND modems_srcs list(APPEND lora_modules_srcs "lora_modules/dx_smart_lr02_lm.cpp" "lora_modules/ebyte_e22_lm.cpp" + "lora_modules/gw_lora_device.cpp" "lora_modules/lora_module_factory.cpp") list(APPEND gateway_api_srcs @@ -158,8 +153,7 @@ list(APPEND gateway_api_srcs list(APPEND wifi_srcs "wifi/wifi_driver_factory.cpp" - "wifi/esp_wifi_driver.cpp" - ) + "wifi/esp_wifi_driver.cpp") list(APPEND serial_ports_srcs "serial_ports/at_support/at_buffer.cpp" @@ -170,8 +164,7 @@ list(APPEND serial_ports_srcs "serial_ports/serial_port_factory.cpp" "serial_ports/esp32_serial_port.cpp" "serial_ports/win_serial_port.cpp" - "serial_ports/unix_serial_port.cpp" - ) + "serial_ports/unix_serial_port.cpp") list(APPEND transport_srcs "transport/system_sockets/sockets/unix_socket.cpp" @@ -191,8 +184,7 @@ list(APPEND transport_srcs "transport/system_sockets/tcp/tcp.cpp" "transport/system_sockets/udp/udp.cpp" "transport/modems/modem_transport.cpp" - "transport/gateway/gateway_transport.cpp" -) + "transport/gateway/gateway_transport.cpp") list(APPEND stream_api_src "stream_api/stream_write_action.cpp" @@ -208,15 +200,13 @@ list(APPEND stream_api_src "stream_api/safe_stream/sending_chunk_list.cpp" "stream_api/safe_stream/receiving_chunk_list.cpp" "stream_api/safe_stream/safe_stream_send_action.cpp" - "stream_api/safe_stream/safe_stream_recv_action.cpp" -) + "stream_api/safe_stream/safe_stream_recv_action.cpp") list(APPEND api_protocol_srcs "api_protocol/protocol_context.cpp" "api_protocol/api_pack_parser.cpp" "api_protocol/child_data.cpp" - "api_protocol/return_result_api.cpp" - ) + "api_protocol/return_result_api.cpp") list(APPEND crypto_srcs "crypto/crypto_nonce.cpp" @@ -227,8 +217,7 @@ list(APPEND crypto_srcs "crypto/sodium/sodium_async_crypto_provider.cpp" "crypto/sodium/sodium_sync_crypto_provider.cpp" "crypto/hydrogen/hydro_async_crypto_provider.cpp" - "crypto/hydrogen/hydro_sync_crypto_provider.cpp" - ) + "crypto/hydrogen/hydro_sync_crypto_provider.cpp") list(APPEND work_cloud_api_srcs "work_cloud_api/work_server_api/login_api.cpp" diff --git a/aether/lora_modules/gw_lora_device.cpp b/aether/lora_modules/gw_lora_device.cpp new file mode 100644 index 00000000..ed3f38ce --- /dev/null +++ b/aether/lora_modules/gw_lora_device.cpp @@ -0,0 +1,23 @@ +/* + * Copyright 2025 Aethernet Inc. + * + * 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 + * + * http://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 "aether/lora_modules/gw_lora_device.h" + +#include "aether/tele/tele.h" + +namespace ae { + +} // namespace ae \ No newline at end of file diff --git a/aether/lora_modules/gw_lora_device.h b/aether/lora_modules/gw_lora_device.h new file mode 100644 index 00000000..c26bf6f4 --- /dev/null +++ b/aether/lora_modules/gw_lora_device.h @@ -0,0 +1,54 @@ +/* + * Copyright 2025 Aethernet Inc. + * + * 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 + * + * http://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 AETHER_LORA_MODULES_GW_LORA_DEVICE_H_ +#define AETHER_LORA_MODULES_GW_LORA_DEVICE_H_ + +#include + +#include "aether/types/server_id.h" +#include "aether/types/client_id.h" +#include "aether/gateway_api/gateway_api.h" +#include "aether/transport/gateway/gateway_device.h" + +namespace ae { +using DeviceId = std::uint8_t; + +class GwLoraDevice final : public IGatewayDevice { + public: + explicit GwLoraDevice(ActionContext action_context); + ~GwLoraDevice() override; + + ActionPtr ToServer(ClientId client_id, ServerId server_id, + DataBuffer&& data) override; + + ActionPtr ToServer(ClientId client_id, + ServerEndpoints const& server_endpoints, + DataBuffer&& data) override; + + FromServerEvent::Subscriber from_server_event() override; + + private: + ActionContext action_context_; + DeviceId device_id_; + + ProtocolContext protocol_context_; + GatewayApi gateway_api_; + GatewayClientApi gateway_client_api_; +}; +} // namespace ae + +#endif // AETHER_LORA_MODULES_GW_LORA_DEVICE_H_ From 9f68cc6e9d5ba72b3d66a752ff9850602808b082 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Wed, 10 Dec 2025 17:33:43 +0300 Subject: [PATCH 21/32] Fixing build. --- aether/access_points/lora_module_access_point.h | 2 +- aether/transport/lora_modules/lora_module_transport.cpp | 6 +++--- aether/transport/lora_modules/lora_module_transport.h | 4 ++-- aether/transport/modems/modem_transport.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/aether/access_points/lora_module_access_point.h b/aether/access_points/lora_module_access_point.h index 46b0d506..6550af06 100644 --- a/aether/access_points/lora_module_access_point.h +++ b/aether/access_points/lora_module_access_point.h @@ -68,7 +68,7 @@ class LoraModuleAccessPoint final : public AccessPoint { ILoraModuleDriver& lora_module_driver(); std::vector> GenerateChannels( - std::vector const& endpoints) override; + ObjPtr const& server) override; private: Obj::ptr aether_; diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 2c9b5d8b..51b4c2fd 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -81,12 +81,12 @@ void LoraModuleTransport::SendLoraAction::Send() { LoraModuleTransport::LoraModuleTransport(ActionContext action_context, ILoraModuleDriver& lora_module_driver, - UnifiedAddress address) + Endpoint address) : action_context_{action_context}, lora_module_driver_{&lora_module_driver}, address_{std::move(address)}, - protocol_{ - std::visit([](auto const& arg) { return arg.protocol; }, address_)}, + protocol_{ std::visit([](auto const& arg) { return arg.protocol; }, + address_)}, stream_info_{}, send_action_queue_manager_{action_context_}, max_packet_size_{lora_module_driver_->GetMtu()} { diff --git a/aether/transport/lora_modules/lora_module_transport.h b/aether/transport/lora_modules/lora_module_transport.h index ee5f56d7..caef98e5 100644 --- a/aether/transport/lora_modules/lora_module_transport.h +++ b/aether/transport/lora_modules/lora_module_transport.h @@ -59,7 +59,7 @@ class LoraModuleTransport final : public ByteIStream { public: LoraModuleTransport(ActionContext action_context, ILoraModuleDriver& lora_module_driver, - UnifiedAddress address); + Endpoint address); ~LoraModuleTransport() override; ActionPtr Write(DataBuffer&& in_data) override; @@ -79,7 +79,7 @@ class LoraModuleTransport final : public ByteIStream { ActionContext action_context_; ILoraModuleDriver* lora_module_driver_; - UnifiedAddress address_; + Endpoint address_; Protocol protocol_; StreamInfo stream_info_; diff --git a/aether/transport/modems/modem_transport.cpp b/aether/transport/modems/modem_transport.cpp index d9533bfe..47b490bc 100644 --- a/aether/transport/modems/modem_transport.cpp +++ b/aether/transport/modems/modem_transport.cpp @@ -120,8 +120,8 @@ ModemTransport::ModemTransport(ActionContext action_context, : action_context_{action_context}, modem_driver_{&modem_driver}, address_{std::move(address)}, - protocol_{ - std::visit([](auto const& arg) { return arg.protocol; }, address_)}, + protocol_{ std::visit([](auto const& arg) { return arg.protocol; }, + address_)}, stream_info_{}, send_action_queue_manager_{action_context_} { AE_TELE_INFO(kModemTransport, "Modem transport created for {}", address_); From c24467bb6b0cf1ce50dde5385d2eb1c60ed41d68 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Wed, 10 Dec 2025 17:36:20 +0300 Subject: [PATCH 22/32] Fixing cpp linter issues. --- aether/lora_modules/gw_lora_device.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aether/lora_modules/gw_lora_device.cpp b/aether/lora_modules/gw_lora_device.cpp index ed3f38ce..a78f9402 100644 --- a/aether/lora_modules/gw_lora_device.cpp +++ b/aether/lora_modules/gw_lora_device.cpp @@ -19,5 +19,5 @@ #include "aether/tele/tele.h" namespace ae { - -} // namespace ae \ No newline at end of file + +} // namespace ae From fb2da3ea51a945aa660ea4cf6ca14c48d5e3407f Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Wed, 10 Dec 2025 17:46:46 +0300 Subject: [PATCH 23/32] Fixing build issue. --- aether/channels/lora_module_channel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aether/channels/lora_module_channel.h b/aether/channels/lora_module_channel.h index 1a3d3467..8eb98edb 100644 --- a/aether/channels/lora_module_channel.h +++ b/aether/channels/lora_module_channel.h @@ -41,7 +41,7 @@ class LoraModuleChannel final : public Channel { Duration TransportBuildTimeout() const override; - UnifiedAddress address; + Endpoint address; private: Obj::ptr aether_; From 527701acab0ed9ad61352836e0f02d2f365c9485 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Thu, 11 Dec 2025 12:20:50 +0300 Subject: [PATCH 24/32] Adding Gateway lora device. --- .../lora_module_access_point.cpp | 1 + aether/lora_modules/gw_lora_device.cpp | 48 +++++++++++++++++++ third_party/libsodium | 2 +- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/aether/access_points/lora_module_access_point.cpp b/aether/access_points/lora_module_access_point.cpp index cc9766c5..ffad2c02 100644 --- a/aether/access_points/lora_module_access_point.cpp +++ b/aether/access_points/lora_module_access_point.cpp @@ -18,6 +18,7 @@ #if AE_SUPPORT_LORA # include "aether/aether.h" +# include "aether/server.h" # include "aether/lora_modules/ilora_module_driver.h" # include "aether/channels/lora_module_channel.h" diff --git a/aether/lora_modules/gw_lora_device.cpp b/aether/lora_modules/gw_lora_device.cpp index a78f9402..0b91bfd8 100644 --- a/aether/lora_modules/gw_lora_device.cpp +++ b/aether/lora_modules/gw_lora_device.cpp @@ -19,5 +19,53 @@ #include "aether/tele/tele.h" namespace ae { +namespace gw_lora_device_internal { +class GwStreamWriteAction final : public StreamWriteAction { + public: + explicit GwStreamWriteAction(ActionContext action_context) + : StreamWriteAction{action_context} { + state_ = State::kDone; + } +}; +} // namespace gw_lora_device_internal +GwLoraDevice::GwLoraDevice(ActionContext action_context) + : action_context_{action_context}, + device_id_{}, + gateway_api_{protocol_context_}, + gateway_client_api_{protocol_context_} {} + +GwLoraDevice::~GwLoraDevice() {} + +ActionPtr GwLoraDevice::ToServer(ClientId client_id, + ServerId server_id, + DataBuffer&& data) { + auto api = ApiContext{gateway_api_}; + api->to_server_id(client_id, server_id, std::move(data)); + DataBuffer packet = std::move(api); + + AE_TELED_DEBUG("Publish from device_id {} data {}", + static_cast(device_id_), packet); + + return ActionPtr{ + action_context_}; +} + +ActionPtr GwLoraDevice::ToServer( + ClientId client_id, ServerEndpoints const& server_endpoints, + DataBuffer&& data) { + auto api = ApiContext{gateway_api_}; + api->to_server(client_id, server_endpoints, std::move(data)); + DataBuffer packet = std::move(api); + + AE_TELED_DEBUG("Publish from device_id {} data {}", + static_cast(device_id_), packet); + + return ActionPtr{ + action_context_}; +} + +GwLoraDevice::FromServerEvent::Subscriber GwLoraDevice::from_server_event() { + return gateway_client_api_.from_server_event(); +} } // namespace ae diff --git a/third_party/libsodium b/third_party/libsodium index fd8c876b..29090390 160000 --- a/third_party/libsodium +++ b/third_party/libsodium @@ -1 +1 @@ -Subproject commit fd8c876bb5ad9d5ad79074ccd6b509f845631807 +Subproject commit 2909039095d1bf45ad86f647f45f53ecc6b347c9 From b558f9eaee95a0c6e4d7df7c8ec9c7f532e66590 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Thu, 11 Dec 2025 12:48:51 +0300 Subject: [PATCH 25/32] Fixing Lora module access point. --- aether/access_points/lora_module_access_point.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aether/access_points/lora_module_access_point.cpp b/aether/access_points/lora_module_access_point.cpp index ffad2c02..6b29e259 100644 --- a/aether/access_points/lora_module_access_point.cpp +++ b/aether/access_points/lora_module_access_point.cpp @@ -93,7 +93,7 @@ ILoraModuleDriver& LoraModuleAccessPoint::lora_module_driver() { } std::vector> LoraModuleAccessPoint::GenerateChannels( - std::vector const& endpoints) { + ObjPtr const& server) { AE_TELED_DEBUG("Generate lora module channels"); std::vector> channels; channels.reserve(server->endpoints.size()); From 7a6f686682a40a494c7ce8e5437cfc42e46a2f03 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Thu, 11 Dec 2025 13:09:17 +0300 Subject: [PATCH 26/32] Fixing Lora module channel and transport. --- aether/channels/lora_module_channel.cpp | 5 ++--- aether/transport/lora_modules/lora_module_transport.cpp | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/aether/channels/lora_module_channel.cpp b/aether/channels/lora_module_channel.cpp index 05b22bb5..0229091b 100644 --- a/aether/channels/lora_module_channel.cpp +++ b/aether/channels/lora_module_channel.cpp @@ -139,14 +139,13 @@ class LoraModuleTransportBuilderAction final : public TransportBuilderAction { LoraModuleChannel::LoraModuleChannel(ObjPtr aether, LoraModuleAccessPoint::ptr access_point, Endpoint address, Domain* domain) - : Channel{std::move(address), domain}, + : Channel{domain}, aether_{std::move(aether)}, access_point_{std::move(access_point)} { // fill transport properties transport_properties_.max_packet_size = 400; transport_properties_.rec_packet_size = 400; - auto protocol = std::visit([](auto&& adr) { return adr.protocol; }, address); - switch (protocol) { + switch (address.protocol) { case Protocol::kTcp: { transport_properties_.connection_type = ConnectionType::kConnectionFull; transport_properties_.reliability = Reliability::kReliable; diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp index 51b4c2fd..004842b4 100644 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ b/aether/transport/lora_modules/lora_module_transport.cpp @@ -85,8 +85,7 @@ LoraModuleTransport::LoraModuleTransport(ActionContext action_context, : action_context_{action_context}, lora_module_driver_{&lora_module_driver}, address_{std::move(address)}, - protocol_{ std::visit([](auto const& arg) { return arg.protocol; }, - address_)}, + protocol_{address_.protocol}, stream_info_{}, send_action_queue_manager_{action_context_}, max_packet_size_{lora_module_driver_->GetMtu()} { From 5bdb155ac8e1e38d89967c3b9adf47760ed1bdbf Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Thu, 11 Dec 2025 14:24:12 +0300 Subject: [PATCH 27/32] Enabling support gateway. --- aether/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aether/config.h b/aether/config.h index f8510337..9a018e9a 100644 --- a/aether/config.h +++ b/aether/config.h @@ -131,7 +131,7 @@ * \brief Is work with gateway supported. */ #ifndef AE_SUPPORT_GATEWAY -# define AE_SUPPORT_GATEWAY 0 +# define AE_SUPPORT_GATEWAY 1 #endif // Registration functionality can be stripped-out for pre-registered clients. From 1a0560052b33bdbba919d7916ba57f62ef802ed8 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Thu, 11 Dec 2025 17:56:24 +0300 Subject: [PATCH 28/32] Updating gateway lora device. --- aether/lora_modules/gw_lora_device.cpp | 29 +++++++++++++++++++++++--- aether/lora_modules/gw_lora_device.h | 11 ++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/aether/lora_modules/gw_lora_device.cpp b/aether/lora_modules/gw_lora_device.cpp index 0b91bfd8..596257ce 100644 --- a/aether/lora_modules/gw_lora_device.cpp +++ b/aether/lora_modules/gw_lora_device.cpp @@ -16,6 +16,7 @@ #include "aether/lora_modules/gw_lora_device.h" +#include "aether/crc.h" #include "aether/tele/tele.h" namespace ae { @@ -40,10 +41,21 @@ GwLoraDevice::~GwLoraDevice() {} ActionPtr GwLoraDevice::ToServer(ClientId client_id, ServerId server_id, DataBuffer&& data) { + LoraPacket lora_packet{}; auto api = ApiContext{gateway_api_}; - api->to_server_id(client_id, server_id, std::move(data)); + + lora_packet.length = data.size(); + lora_packet.data = data; + lora_packet.crc = crc32::from_buffer(data.data(), data.size()).value; + + std::vector packet_data; + auto writer = ae::VectorWriter<>{packet_data}; + auto os = ae::omstream{writer}; + os << lora_packet; + + api->to_server_id(client_id, server_id, std::move(packet_data)); DataBuffer packet = std::move(api); - + AE_TELED_DEBUG("Publish from device_id {} data {}", static_cast(device_id_), packet); @@ -54,8 +66,19 @@ ActionPtr GwLoraDevice::ToServer(ClientId client_id, ActionPtr GwLoraDevice::ToServer( ClientId client_id, ServerEndpoints const& server_endpoints, DataBuffer&& data) { + LoraPacket lora_packet{}; auto api = ApiContext{gateway_api_}; - api->to_server(client_id, server_endpoints, std::move(data)); + + lora_packet.length = data.size(); + lora_packet.data = data; + lora_packet.crc = crc32::from_buffer(data.data(), data.size()).value; + + std::vector packet_data; + auto writer = ae::VectorWriter<>{packet_data}; + auto os = ae::omstream{writer}; + os << lora_packet; + + api->to_server(client_id, server_endpoints, std::move(packet_data)); DataBuffer packet = std::move(api); AE_TELED_DEBUG("Publish from device_id {} data {}", diff --git a/aether/lora_modules/gw_lora_device.h b/aether/lora_modules/gw_lora_device.h index c26bf6f4..6a3b0854 100644 --- a/aether/lora_modules/gw_lora_device.h +++ b/aether/lora_modules/gw_lora_device.h @@ -21,12 +21,23 @@ #include "aether/types/server_id.h" #include "aether/types/client_id.h" +#include "aether/reflect/reflect.h" #include "aether/gateway_api/gateway_api.h" #include "aether/transport/gateway/gateway_device.h" namespace ae { using DeviceId = std::uint8_t; +static constexpr std::uint16_t kLoraModuleAddress = 2; + +struct LoraPacket { + AE_REFLECT_MEMBERS(address, length, data, crc) + std::uint16_t address{kLoraModuleAddress}; + std::size_t length{0}; + DataBuffer data; + std::uint32_t crc{0}; +}; + class GwLoraDevice final : public IGatewayDevice { public: explicit GwLoraDevice(ActionContext action_context); From 2530912052ccb75db4acfa2aff30fff43d341573 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Thu, 11 Dec 2025 17:57:07 +0300 Subject: [PATCH 29/32] Fixing cpp linter issues. --- aether/lora_modules/gw_lora_device.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/aether/lora_modules/gw_lora_device.cpp b/aether/lora_modules/gw_lora_device.cpp index 596257ce..54a557a7 100644 --- a/aether/lora_modules/gw_lora_device.cpp +++ b/aether/lora_modules/gw_lora_device.cpp @@ -39,23 +39,23 @@ GwLoraDevice::GwLoraDevice(ActionContext action_context) GwLoraDevice::~GwLoraDevice() {} ActionPtr GwLoraDevice::ToServer(ClientId client_id, - ServerId server_id, - DataBuffer&& data) { + ServerId server_id, + DataBuffer&& data) { LoraPacket lora_packet{}; auto api = ApiContext{gateway_api_}; - + lora_packet.length = data.size(); lora_packet.data = data; lora_packet.crc = crc32::from_buffer(data.data(), data.size()).value; - + std::vector packet_data; auto writer = ae::VectorWriter<>{packet_data}; auto os = ae::omstream{writer}; os << lora_packet; - + api->to_server_id(client_id, server_id, std::move(packet_data)); DataBuffer packet = std::move(api); - + AE_TELED_DEBUG("Publish from device_id {} data {}", static_cast(device_id_), packet); @@ -68,16 +68,16 @@ ActionPtr GwLoraDevice::ToServer( DataBuffer&& data) { LoraPacket lora_packet{}; auto api = ApiContext{gateway_api_}; - + lora_packet.length = data.size(); lora_packet.data = data; lora_packet.crc = crc32::from_buffer(data.data(), data.size()).value; - + std::vector packet_data; auto writer = ae::VectorWriter<>{packet_data}; auto os = ae::omstream{writer}; os << lora_packet; - + api->to_server(client_id, server_endpoints, std::move(packet_data)); DataBuffer packet = std::move(api); From 8487f9a43288e0648e2fcf9ed2136cb6640da7b9 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Fri, 12 Dec 2025 17:49:14 +0300 Subject: [PATCH 30/32] Updating Lora modules to work with gateway. --- aether/CMakeLists.txt | 1 - .../lora_module_access_point.cpp | 86 ++------ .../access_points/lora_module_access_point.h | 52 ++--- aether/adapters/lora_module_adapter.cpp | 3 +- aether/channels/lora_module_channel.cpp | 146 ++++--------- aether/channels/lora_module_channel.h | 12 +- aether/config.h | 6 +- aether/lora_modules/gw_lora_device.cpp | 5 + aether/lora_modules/gw_lora_device.h | 6 + .../lora_modules/lora_module_transport.cpp | 204 ------------------ .../lora_modules/lora_module_transport.h | 104 --------- examples/cloud/aether_construct_lora_module.h | 2 +- 12 files changed, 102 insertions(+), 525 deletions(-) delete mode 100644 aether/transport/lora_modules/lora_module_transport.cpp delete mode 100644 aether/transport/lora_modules/lora_module_transport.h diff --git a/aether/CMakeLists.txt b/aether/CMakeLists.txt index 155c686f..c4bee1ea 100644 --- a/aether/CMakeLists.txt +++ b/aether/CMakeLists.txt @@ -176,7 +176,6 @@ list(APPEND transport_srcs "transport/system_sockets/sockets/win_sock_addr.cpp" "transport/system_sockets/sockets/win_tcp_socket.cpp" "transport/system_sockets/sockets/win_udp_socket.cpp" - "transport/lora_modules/lora_module_transport.cpp" "transport/modems/modem_transport.cpp" "transport/socket_packet_send_action.cpp" "transport/data_packet_collector.cpp" diff --git a/aether/access_points/lora_module_access_point.cpp b/aether/access_points/lora_module_access_point.cpp index 6b29e259..e34a1253 100644 --- a/aether/access_points/lora_module_access_point.cpp +++ b/aether/access_points/lora_module_access_point.cpp @@ -15,7 +15,8 @@ */ #include "aether/access_points/lora_module_access_point.h" -#if AE_SUPPORT_LORA + +#if AE_SUPPORT_LORA && AE_SUPPORT_GATEWAY # include "aether/aether.h" # include "aether/server.h" @@ -25,47 +26,11 @@ # include "aether/access_points/filter_protocols.h" namespace ae { -LoraModuleConnectAction::LoraModuleConnectAction( - ActionContext action_context, [[maybe_unused]] ILoraModuleDriver& driver) - : Action{action_context}, driver_{&driver}, state_{State::kStart} { - AE_TELED_DEBUG("LoraModuleConnectAction created"); -} +LoraModuleAccessPoint::JoinAction::JoinAction(ActionContext action_context) + : Action{action_context} {} -UpdateStatus LoraModuleConnectAction::Update() { - if (state_.changed()) { - switch (state_.Acquire()) { - case State::kStart: - Start(); - break; - case State::kSuccess: - return UpdateStatus::Result(); - case State::kFailed: - return UpdateStatus::Error(); - } - } - return {}; -} - -void LoraModuleConnectAction::Start() { - AE_TELED_DEBUG("LoraModuleConnectAction start"); - auto action = driver_->Start(); - if (!action) { - state_ = State::kFailed; - Action::Trigger(); - return; - } - action->StatusEvent().Subscribe(ActionHandler{ - OnResult{[this]() { - AE_TELED_INFO("Lora module access point start success"); - state_ = State::kSuccess; - Action::Trigger(); - }}, - OnError{[this]() { - AE_TELED_ERROR("Lora module access point start failed"); - state_ = State::kFailed; - Action::Trigger(); - }}, - }); +UpdateStatus LoraModuleAccessPoint::JoinAction::Update() { + return UpdateStatus::Result(); } LoraModuleAccessPoint::LoraModuleAccessPoint( @@ -75,38 +40,25 @@ LoraModuleAccessPoint::LoraModuleAccessPoint( aether_{std::move(aether)}, lora_module_adapter_{std::move(lora_module_adapter)} {} -ActionPtr LoraModuleAccessPoint::Connect() { - AE_TELED_DEBUG("Make lora module access point connection"); - - // reuse connect action if it's in progress - if (!connect_action_) { - connect_action_ = ActionPtr{ - *aether_.as(), lora_module_adapter_->lora_module_driver()}; - connect_sub_ = connect_action_->FinishedEvent().Subscribe( - [this]() { connect_action_.reset(); }); - } - return connect_action_; -} - -ILoraModuleDriver& LoraModuleAccessPoint::lora_module_driver() { - return lora_module_adapter_->lora_module_driver(); +ActionPtr LoraModuleAccessPoint::Join() { + return ActionPtr{*aether_}; } std::vector> LoraModuleAccessPoint::GenerateChannels( ObjPtr const& server) { AE_TELED_DEBUG("Generate lora module channels"); - std::vector> channels; - channels.reserve(server->endpoints.size()); - Aether::ptr aether = aether_; - LoraModuleAccessPoint::ptr self = MakePtrFromThis(this); - for (auto const& endpoint : server->endpoints) { - if (!FilterProtocol(endpoint)) { - continue; - } - channels.emplace_back( - domain_->CreateObj(aether, self, endpoint)); + auto self_ptr = MakePtrFromThis(this); + return {domain_->CreateObj(self_ptr, server)}; +} + +Aether::ptr const& LoraModuleAccessPoint::aether() const { return aether_; } + +GwLoraDevice& LoraModuleAccessPoint::gw_lora_device() { + if (!gw_lora_device_) { + gw_lora_device_ = std::make_unique( + *aether_); } - return channels; + return *gw_lora_device_; } } // namespace ae diff --git a/aether/access_points/lora_module_access_point.h b/aether/access_points/lora_module_access_point.h index 6550af06..adfebdc9 100644 --- a/aether/access_points/lora_module_access_point.h +++ b/aether/access_points/lora_module_access_point.h @@ -19,62 +19,44 @@ #include "aether/config.h" -#if AE_SUPPORT_LORA +#if AE_SUPPORT_LORA && AE_SUPPORT_GATEWAY + # include "aether/obj/obj.h" # include "aether/actions/action.h" # include "aether/actions/action_ptr.h" -# include "aether/types/state_machine.h" -# include "aether/lora_modules/ilora_module_driver.h" # include "aether/adapters/lora_module_adapter.h" -# include "aether/events/event_subscription.h" # include "aether/access_points/access_point.h" +# include "aether/lora_modules/gw_lora_device.h" namespace ae { -class Aether; - -class LoraModuleConnectAction final : public Action { - public: - enum class State : std::uint8_t { - kStart, - kSuccess, - kFailed, - }; - - LoraModuleConnectAction(ActionContext action_context, - ILoraModuleDriver& driver); - - UpdateStatus Update(); - - private: - void Start(); - - ILoraModuleDriver* driver_; - Subscription start_sub_; - StateMachine state_; -}; - class LoraModuleAccessPoint final : public AccessPoint { AE_OBJECT(LoraModuleAccessPoint, AccessPoint, 0) LoraModuleAccessPoint() = default; public: + class JoinAction : public Action { + public: + explicit JoinAction(ActionContext action_context); + UpdateStatus Update(); + }; + LoraModuleAccessPoint(ObjPtr aether, LoraModuleAdapter::ptr lora_module_adapter, Domain* domain); - AE_OBJECT_REFLECT(AE_MMBRS(aether_, lora_module_adapter_)); + AE_OBJECT_REFLECT(AE_MMBRS(lora_module_adapter_)); - ActionPtr Connect(); - ILoraModuleDriver& lora_module_driver(); + ActionPtr Join(); std::vector> GenerateChannels( - ObjPtr const& server) override; + Server::ptr const& server) override; + Aether::ptr const& aether() const; + GwLoraDevice& gw_lora_device(); private: - Obj::ptr aether_; - LoraModuleAdapter::ptr lora_module_adapter_; - ActionPtr connect_action_; - Subscription connect_sub_; + Aether::ptr aether_; + Adapter::ptr lora_module_adapter_; + std::unique_ptr gw_lora_device_; }; } // namespace ae #endif diff --git a/aether/adapters/lora_module_adapter.cpp b/aether/adapters/lora_module_adapter.cpp index bcb4d97a..92bcf09e 100644 --- a/aether/adapters/lora_module_adapter.cpp +++ b/aether/adapters/lora_module_adapter.cpp @@ -15,7 +15,8 @@ */ #include "aether/adapters/lora_module_adapter.h" -#if AE_SUPPORT_LORA + +#if AE_SUPPORT_LORA && AE_SUPPORT_GATEWAY # include "aether/aether.h" # include "aether/lora_modules/lora_module_factory.h" diff --git a/aether/channels/lora_module_channel.cpp b/aether/channels/lora_module_channel.cpp index 0229091b..8f8b4609 100644 --- a/aether/channels/lora_module_channel.cpp +++ b/aether/channels/lora_module_channel.cpp @@ -15,59 +15,54 @@ */ #include "aether/channels/lora_module_channel.h" -#if AE_SUPPORT_LORA + +#if AE_SUPPORT_LORA && AE_SUPPORT_GATEWAY # include # include "aether/memory.h" # include "aether/aether.h" # include "aether/types/state_machine.h" -# include "aether/transport/lora_modules/lora_module_transport.h" +# include "aether/transport/gateway/gateway_transport.h" namespace ae { namespace lora_module_channel_internal { class LoraModuleTransportBuilderAction final : public TransportBuilderAction { enum class State : std::uint8_t { - kLoraModuleConnect, - kTransportCreate, - kWaitTransportConnected, - kTransportConnected, - kFailed + kJoin, + kCreateTransport, + kResult, + kError }; public: LoraModuleTransportBuilderAction(ActionContext action_context, - LoraModuleChannel& channel, LoraModuleAccessPoint& access_point, - Endpoint address) + Server::ptr const& server) : TransportBuilderAction{action_context}, action_context_{action_context}, - channel_{&channel}, access_point_{&access_point}, - address_{std::move(address)}, - state_{State::kLoraModuleConnect}, - start_time_{Now()} { + server_{server}, + state_{State::kJoin}{ AE_TELED_DEBUG("Lora module transport building"); + state_.changed_event().Subscribe([this](auto) { Action::Trigger(); }); } UpdateStatus Update() override { if (state_.changed()) { switch (state_.Acquire()) { - case State::kLoraModuleConnect: - ConnectLoraModule(); + case State::kJoin: + Join(); break; - case State::kTransportCreate: + case State::kCreateTransport: CreateTransport(); break; - case State::kWaitTransportConnected: - break; - case State::kTransportConnected: + case State::kResult: return UpdateStatus::Result(); - case State::kFailed: + case State::kError: return UpdateStatus::Error(); } } - return {}; } @@ -76,104 +71,53 @@ class LoraModuleTransportBuilderAction final : public TransportBuilderAction { } private: - void ConnectLoraModule() { - lora_module_connect_sub_ = - access_point_->Connect()->StatusEvent().Subscribe(ActionHandler{ - OnResult{[this]() { - state_ = State::kTransportCreate; - Action::Trigger(); - }}, - OnError{[this]() { - state_ = State::kFailed; - Action::Trigger(); - }}, - }); + void Join() { + auto join = access_point_->Join(); + join->StatusEvent().Subscribe(ActionHandler{ + OnResult{[this]() { state_ = State::kCreateTransport; }}, + OnError{[this]() { state_ = State::kError; }}, + }); } void CreateTransport() { - state_ = State::kWaitTransportConnected; - - auto& lora_module_driver = access_point_->lora_module_driver(); - transport_stream_ = std::make_unique( - action_context_, lora_module_driver, address_); - - if (transport_stream_->stream_info().link_state == LinkState::kLinked) { - Connected(); - return; + auto server = server_.Lock(); + assert(server && "Server should be alive"); + + if (server->server_id == 0) { + transport_stream_ = std::make_unique( + ServerEndpoints{server->endpoints}, access_point_->gw_lora_device()); + } else { + transport_stream_ = std::make_unique( + server->server_id, access_point_->gw_lora_device()); } - - tranpsport_sub_ = - transport_stream_->stream_update_event().Subscribe([this]() { - if (transport_stream_->stream_info().link_state == - LinkState::kLinked) { - Connected(); - } else if (transport_stream_->stream_info().link_state == - LinkState::kLinkError) { - state_ = State::kFailed; - Action::Trigger(); - } - }); - } - - void Connected() { - auto built_time = std::chrono::duration_cast(Now() - start_time_); - AE_TELED_DEBUG("Lora modem transport built by {:%S}", built_time); - channel_->channel_statistics().AddConnectionTime(built_time); - state_ = State::kTransportConnected; - Action::Trigger(); + state_ = State::kResult; } ActionContext action_context_; - LoraModuleChannel* channel_; LoraModuleAccessPoint* access_point_; - Endpoint address_; + PtrView server_; StateMachine state_; - std::unique_ptr transport_stream_; - Subscription tranpsport_sub_; - Subscription lora_module_connect_sub_; - TimePoint start_time_; + + std::unique_ptr transport_stream_; }; } // namespace lora_module_channel_internal -LoraModuleChannel::LoraModuleChannel(ObjPtr aether, - LoraModuleAccessPoint::ptr access_point, - Endpoint address, Domain* domain) +LoraModuleChannel::LoraModuleChannel(LoraModuleAccessPoint::ptr access_point, + Server::ptr server, Domain* domain) : Channel{domain}, - aether_{std::move(aether)}, - access_point_{std::move(access_point)} { - // fill transport properties - transport_properties_.max_packet_size = 400; + access_point_{std::move(access_point)}, + server_{std::move(server)} { + transport_properties_.connection_type = ConnectionType::kConnectionLess; + transport_properties_.reliability = Reliability::kUnreliable; transport_properties_.rec_packet_size = 400; - switch (address.protocol) { - case Protocol::kTcp: { - transport_properties_.connection_type = ConnectionType::kConnectionFull; - transport_properties_.reliability = Reliability::kReliable; - break; - } - case Protocol::kUdp: { - transport_properties_.connection_type = ConnectionType::kConnectionLess; - transport_properties_.reliability = Reliability::kUnreliable; - break; - } - default: - // protocol is not supported - assert(false); - } + transport_properties_.max_packet_size = 400; } ActionPtr LoraModuleChannel::TransportBuilder() { - if (!access_point_) { - aether_->domain_->LoadRoot(access_point_); - } - return ActionPtr< - lora_module_channel_internal::LoraModuleTransportBuilderAction>{ - *aether_.as(), *this, *access_point_, address}; -} - -Duration LoraModuleChannel::TransportBuildTimeout() const { - return channel_statistics_->connection_time_statistics().percentile<99>() + - std::chrono::seconds{5}; + auto const& aether = access_point_->aether(); + return ActionPtr{ + *aether, *access_point_, server_}; } } // namespace ae diff --git a/aether/channels/lora_module_channel.h b/aether/channels/lora_module_channel.h index 8eb98edb..d0a9448e 100644 --- a/aether/channels/lora_module_channel.h +++ b/aether/channels/lora_module_channel.h @@ -19,33 +19,29 @@ #include "aether/config.h" -#if AE_SUPPORT_LORA +#if AE_SUPPORT_LORA && AE_SUPPORT_GATEWAY + # include "aether/channels/channel.h" # include "aether/access_points/lora_module_access_point.h" namespace ae { -class Aether; - class LoraModuleChannel final : public Channel { AE_OBJECT(LoraModuleChannel, Channel, 0) LoraModuleChannel() = default; public: - LoraModuleChannel(ObjPtr aether, - LoraModuleAccessPoint::ptr access_point, Endpoint address, + LoraModuleChannel(LoraModuleAccessPoint::ptr access_point, Server::ptr server, Domain* domain); AE_OBJECT_REFLECT(AE_MMBRS(access_point_)) ActionPtr TransportBuilder() override; - Duration TransportBuildTimeout() const override; - Endpoint address; private: - Obj::ptr aether_; LoraModuleAccessPoint::ptr access_point_; + Server::ptr server_; }; } // namespace ae #endif diff --git a/aether/config.h b/aether/config.h index 9a018e9a..8b3019c2 100644 --- a/aether/config.h +++ b/aether/config.h @@ -116,7 +116,7 @@ * \brief Is lora protocol supported. */ #ifndef AE_SUPPORT_LORA -# define AE_SUPPORT_LORA 1 +# define AE_SUPPORT_LORA 0 #endif #ifndef AE_ENABLE_EBYTE_E22_LM @@ -124,14 +124,14 @@ #endif #ifndef AE_ENABLE_DX_SMART_LR02_LM -# define AE_ENABLE_DX_SMART_LR02_LM 1 +# define AE_ENABLE_DX_SMART_LR02_LM 0 #endif /** * \brief Is work with gateway supported. */ #ifndef AE_SUPPORT_GATEWAY -# define AE_SUPPORT_GATEWAY 1 +# define AE_SUPPORT_GATEWAY 0 #endif // Registration functionality can be stripped-out for pre-registered clients. diff --git a/aether/lora_modules/gw_lora_device.cpp b/aether/lora_modules/gw_lora_device.cpp index 54a557a7..d30ea1dd 100644 --- a/aether/lora_modules/gw_lora_device.cpp +++ b/aether/lora_modules/gw_lora_device.cpp @@ -16,6 +16,9 @@ #include "aether/lora_modules/gw_lora_device.h" +#if AE_SUPPORT_GATEWAY + +#include "aether/stream_api/stream_write_action.h" #include "aether/crc.h" #include "aether/tele/tele.h" @@ -92,3 +95,5 @@ GwLoraDevice::FromServerEvent::Subscriber GwLoraDevice::from_server_event() { return gateway_client_api_.from_server_event(); } } // namespace ae + +#endif diff --git a/aether/lora_modules/gw_lora_device.h b/aether/lora_modules/gw_lora_device.h index 6a3b0854..16da069f 100644 --- a/aether/lora_modules/gw_lora_device.h +++ b/aether/lora_modules/gw_lora_device.h @@ -17,6 +17,10 @@ #ifndef AETHER_LORA_MODULES_GW_LORA_DEVICE_H_ #define AETHER_LORA_MODULES_GW_LORA_DEVICE_H_ +#include "aether/config.h" + +#if AE_SUPPORT_GATEWAY + #include #include "aether/types/server_id.h" @@ -25,6 +29,7 @@ #include "aether/gateway_api/gateway_api.h" #include "aether/transport/gateway/gateway_device.h" + namespace ae { using DeviceId = std::uint8_t; @@ -62,4 +67,5 @@ class GwLoraDevice final : public IGatewayDevice { }; } // namespace ae +#endif #endif // AETHER_LORA_MODULES_GW_LORA_DEVICE_H_ diff --git a/aether/transport/lora_modules/lora_module_transport.cpp b/aether/transport/lora_modules/lora_module_transport.cpp deleted file mode 100644 index 004842b4..00000000 --- a/aether/transport/lora_modules/lora_module_transport.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2025 Aethernet Inc. - * - * 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 - * - * http://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 "aether/transport/lora_modules/lora_module_transport.h" - -#if defined LORA_MODULE_TRANSPORT_ENABLED - -# include "aether/mstream.h" -# include "aether/reflect/reflect.h" -# include "aether/mstream_buffers.h" - -# include "aether/transport/transport_tele.h" - -namespace ae { -LoraModuleTransport::LoraModuleSend::LoraModuleSend( - ActionContext action_context, LoraModuleTransport& transport, - DataBuffer data) - : SocketPacketSendAction{action_context}, - max_packet_size_{std::move(transport.lora_module_driver_->GetMtu())}, - transport_{&transport}, - data_{std::move(data)} {} - -LoraModuleTransport::SendLoraAction::SendLoraAction( - ActionContext action_context, LoraModuleTransport& transport, - DataBuffer data) - : LoraModuleSend{action_context, transport, std::move(data)} {} - -void LoraModuleTransport::SendLoraAction::Send() { - if (state_ == State::kInProgress) { - return; - } - state_ = State::kInProgress; - - // split data to chunks and write them to modem - for (std::size_t sent_offset = 0; sent_offset < data_.size();) { - auto remain_to_send = data_.size() - sent_offset; - auto size_to_send = - remain_to_send > max_packet_size_ ? max_packet_size_ : remain_to_send; - - auto write_action = transport_->lora_module_driver_->WritePacket( - transport_->connection_, - DataBuffer{data_.data() + sent_offset, - data_.data() + sent_offset + size_to_send}); - - if (!write_action) { - state_ = State::kFailed; - Action::Trigger(); - return; - } - - send_subs_.Push(write_action->StatusEvent().Subscribe(ActionHandler{ - OnResult{[this]() { - state_ = State::kDone; - Action::Trigger(); - }}, - OnError{[this]() { - state_ = State::kFailed; - Action::Trigger(); - }}, - OnStop{[this]() { - state_ = State::kStopped; - Action::Trigger(); - }}, - })); - sent_offset += size_to_send; - } -} - -LoraModuleTransport::LoraModuleTransport(ActionContext action_context, - ILoraModuleDriver& lora_module_driver, - Endpoint address) - : action_context_{action_context}, - lora_module_driver_{&lora_module_driver}, - address_{std::move(address)}, - protocol_{address_.protocol}, - stream_info_{}, - send_action_queue_manager_{action_context_}, - max_packet_size_{lora_module_driver_->GetMtu()} { - AE_TELE_INFO(kLoraModuleTransport, "Lora module transport created for {}", - address_); - stream_info_.link_state = LinkState::kUnlinked; - stream_info_.is_reliable = (protocol_ == Protocol::kTcp); - stream_info_.max_element_size = 2 * max_packet_size_; - stream_info_.rec_element_size = max_packet_size_; - - Connect(); -} - -LoraModuleTransport::~LoraModuleTransport() { Disconnect(); } - -LoraModuleTransport::StreamUpdateEvent::Subscriber -LoraModuleTransport::stream_update_event() { - return stream_update_event_; -} - -StreamInfo LoraModuleTransport::stream_info() const { return stream_info_; } - -LoraModuleTransport::OutDataEvent::Subscriber -LoraModuleTransport::out_data_event() { - return out_data_event_; -} - -void LoraModuleTransport::Restream() { - AE_TELED_DEBUG("Lora module transport restream"); - stream_info_.link_state = LinkState::kLinkError; - Disconnect(); -} - -ActionPtr LoraModuleTransport::Write(DataBuffer&& in_data) { - Protocol proto{Protocol::kTcp}; - - AE_TELE_DEBUG(kLoraModuleTransportSend, "Send data size {}", in_data.size()); - - if (protocol_ == Protocol::kTcp || protocol_ == Protocol::kUdp) { - proto = Protocol::kLora; - } - - if (proto == Protocol::kLora) { - auto send_action = send_action_queue_manager_->AddPacket( - ActionPtr{action_context_, *this, std::move(in_data)}); - send_action_subs_.Push( - send_action->StatusEvent().Subscribe(OnError{[this]() { - AE_TELED_ERROR("Send error, disconnect!"); - OnConnectionFailed(); - Disconnect(); - }})); - return send_action; - } - - return ActionPtr{action_context_}; -} - -void LoraModuleTransport::Connect() { - ConnectionLoraIndex connection_index{}; - - OnConnected(connection_index); -} - -void LoraModuleTransport::OnConnected(ConnectionLoraIndex connection_index) { - connection_ = connection_index; - - read_packet_sub_ = lora_module_driver_->data_event().Subscribe( - MethodPtr<&LoraModuleTransport::DataReceived>{this}); - - stream_info_.is_writable = true; - stream_info_.link_state = LinkState::kLinked; - stream_update_event_.Emit(); -} - -void LoraModuleTransport::OnConnectionFailed() { - stream_info_.link_state = LinkState::kLinkError; - stream_update_event_.Emit(); -} - -void LoraModuleTransport::Disconnect() { - if (connection_ == kInvalidConnectionLoraIndex) { - return; - } - - connection_ = kInvalidConnectionLoraIndex; -} - -void LoraModuleTransport::DataReceived(ConnectionLoraIndex connection, - DataBuffer const& data_in) { - Protocol proto{Protocol::kTcp}; - - if (connection_ != connection) { - return; - } - - if (protocol_ == Protocol::kTcp || protocol_ == Protocol::kUdp) { - proto = Protocol::kLora; - } - - if (proto == Protocol::kLora) { - DataReceivedLora(data_in); - } -} - -void LoraModuleTransport::DataReceivedLora(DataBuffer const& data_in) { - data_packet_collector_.AddData(data_in.data(), data_in.size()); - for (auto data = data_packet_collector_.PopPacket(); !data.empty(); - data = data_packet_collector_.PopPacket()) { - AE_TELE_DEBUG(kModemTransportReceive, "Receive data size {}", data.size()); - out_data_event_.Emit(data); - } -} - -} // namespace ae - -#endif diff --git a/aether/transport/lora_modules/lora_module_transport.h b/aether/transport/lora_modules/lora_module_transport.h deleted file mode 100644 index caef98e5..00000000 --- a/aether/transport/lora_modules/lora_module_transport.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2025 Aethernet Inc. - * - * 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 - * - * http://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 AETHER_TRANSPORT_LORA_MODULES_LORA_MODULE_TRANSPORT_H_ -#define AETHER_TRANSPORT_LORA_MODULES_LORA_MODULE_TRANSPORT_H_ - -#include "aether/config.h" - -#if AE_SUPPORT_LORA -# define LORA_MODULE_TRANSPORT_ENABLED 1 - -# include "aether/actions/action.h" -# include "aether/actions/action_ptr.h" -# include "aether/events/multi_subscription.h" - -# include "aether/stream_api/istream.h" -# include "aether/lora_modules/ilora_module_driver.h" -# include "aether/transport/data_packet_collector.h" -# include "aether/transport/socket_packet_send_action.h" -# include "aether/transport/socket_packet_queue_manager.h" - -namespace ae { -class LoraModuleTransport final : public ByteIStream { - class LoraModuleSend : public SocketPacketSendAction { - public: - LoraModuleSend(ActionContext action_context, LoraModuleTransport& transport, - DataBuffer data); - std::uint16_t max_packet_size_{0}; - - protected: - LoraModuleTransport* transport_; - DataBuffer data_; - }; - - class SendLoraAction final : public LoraModuleSend { - public: - SendLoraAction(ActionContext action_context, LoraModuleTransport& transport, - DataBuffer data); - void Send() override; - - private: - void SendPacket(DataBuffer const& data); - MultiSubscription send_subs_; - }; - - public: - LoraModuleTransport(ActionContext action_context, - ILoraModuleDriver& lora_module_driver, - Endpoint address); - ~LoraModuleTransport() override; - - ActionPtr Write(DataBuffer&& in_data) override; - StreamUpdateEvent::Subscriber stream_update_event() override; - StreamInfo stream_info() const override; - OutDataEvent::Subscriber out_data_event() override; - void Restream() override; - - private: - void Connect(); - void OnConnected(ConnectionLoraIndex connection_index); - void OnConnectionFailed(); - void Disconnect(); - - void DataReceived(ConnectionLoraIndex connection, DataBuffer const& data_in); - void DataReceivedLora(DataBuffer const& data_in); - - ActionContext action_context_; - ILoraModuleDriver* lora_module_driver_; - Endpoint address_; - Protocol protocol_; - - StreamInfo stream_info_; - - ConnectionLoraIndex connection_ = kInvalidConnectionLoraIndex; - OwnActionPtr> - send_action_queue_manager_; - StreamDataPacketCollector data_packet_collector_; - - OutDataEvent out_data_event_; - StreamUpdateEvent stream_update_event_; - - MultiSubscription send_action_subs_; - Subscription connection_sub_; - Subscription read_packet_sub_; - - std::uint16_t max_packet_size_{0}; -}; -} // namespace ae - -#endif -#endif // AETHER_TRANSPORT_LORA_MODULES_LORA_MODULE_TRANSPORT_H_ diff --git a/examples/cloud/aether_construct_lora_module.h b/examples/cloud/aether_construct_lora_module.h index 85c898c9..39583b73 100644 --- a/examples/cloud/aether_construct_lora_module.h +++ b/examples/cloud/aether_construct_lora_module.h @@ -22,7 +22,7 @@ #include "aether/config.h" #if CLOUD_TEST_LORA_MODULE -# if !AE_SUPPORT_LORA +# if !AE_SUPPORT_LORA || !AE_SUPPORT_GATEWAY # error "Lora module is not supported" # else From a5017b87fd86c8b79d9e2a73ae0dc57afc986c7a Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Mon, 15 Dec 2025 10:31:56 +0300 Subject: [PATCH 31/32] Fixing cpp linter issues. --- aether/access_points/lora_module_access_point.h | 3 ++- aether/channels/lora_module_channel.cpp | 14 +++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/aether/access_points/lora_module_access_point.h b/aether/access_points/lora_module_access_point.h index adfebdc9..5a1b0140 100644 --- a/aether/access_points/lora_module_access_point.h +++ b/aether/access_points/lora_module_access_point.h @@ -39,7 +39,7 @@ class LoraModuleAccessPoint final : public AccessPoint { explicit JoinAction(ActionContext action_context); UpdateStatus Update(); }; - + LoraModuleAccessPoint(ObjPtr aether, LoraModuleAdapter::ptr lora_module_adapter, Domain* domain); @@ -53,6 +53,7 @@ class LoraModuleAccessPoint final : public AccessPoint { Aether::ptr const& aether() const; GwLoraDevice& gw_lora_device(); + private: Aether::ptr aether_; Adapter::ptr lora_module_adapter_; diff --git a/aether/channels/lora_module_channel.cpp b/aether/channels/lora_module_channel.cpp index 8f8b4609..fb08fa31 100644 --- a/aether/channels/lora_module_channel.cpp +++ b/aether/channels/lora_module_channel.cpp @@ -28,12 +28,7 @@ namespace ae { namespace lora_module_channel_internal { class LoraModuleTransportBuilderAction final : public TransportBuilderAction { - enum class State : std::uint8_t { - kJoin, - kCreateTransport, - kResult, - kError - }; + enum class State : std::uint8_t { kJoin, kCreateTransport, kResult, kError }; public: LoraModuleTransportBuilderAction(ActionContext action_context, @@ -43,7 +38,7 @@ class LoraModuleTransportBuilderAction final : public TransportBuilderAction { action_context_{action_context}, access_point_{&access_point}, server_{server}, - state_{State::kJoin}{ + state_{State::kJoin} { AE_TELED_DEBUG("Lora module transport building"); state_.changed_event().Subscribe([this](auto) { Action::Trigger(); }); } @@ -104,7 +99,7 @@ class LoraModuleTransportBuilderAction final : public TransportBuilderAction { } // namespace lora_module_channel_internal LoraModuleChannel::LoraModuleChannel(LoraModuleAccessPoint::ptr access_point, - Server::ptr server, Domain* domain) + Server::ptr server, Domain* domain) : Channel{domain}, access_point_{std::move(access_point)}, server_{std::move(server)} { @@ -116,7 +111,8 @@ LoraModuleChannel::LoraModuleChannel(LoraModuleAccessPoint::ptr access_point, ActionPtr LoraModuleChannel::TransportBuilder() { auto const& aether = access_point_->aether(); - return ActionPtr{ + return ActionPtr< + lora_module_channel_internal::LoraModuleTransportBuilderAction>{ *aether, *access_point_, server_}; } From f08af170e93272c5e8c2642708a34d3136f9b367 Mon Sep 17 00:00:00 2001 From: Kiryanov D V Date: Mon, 15 Dec 2025 18:03:57 +0300 Subject: [PATCH 32/32] Updating Lora modules. --- .../lora_module_access_point.cpp | 60 +++++++++++++++++++ .../access_points/lora_module_access_point.h | 29 ++++++++- aether/adapters/lora_module_adapter.h | 10 ++-- aether/adapters/parent_lora_module.h | 4 +- aether/channels/lora_module_channel.cpp | 32 ++++++++-- aether/lora_modules/dx_smart_lr02_lm.cpp | 2 +- aether/lora_modules/gw_lora_device.cpp | 26 +------- 7 files changed, 126 insertions(+), 37 deletions(-) diff --git a/aether/access_points/lora_module_access_point.cpp b/aether/access_points/lora_module_access_point.cpp index e34a1253..16ead431 100644 --- a/aether/access_points/lora_module_access_point.cpp +++ b/aether/access_points/lora_module_access_point.cpp @@ -26,6 +26,49 @@ # include "aether/access_points/filter_protocols.h" namespace ae { +LoraModuleConnectAction::LoraModuleConnectAction(ActionContext action_context, + [[maybe_unused]] ILoraModuleDriver& driver) + : Action{action_context}, driver_{&driver}, state_{State::kStart} { + AE_TELED_DEBUG("LoraModuleConnectAction created"); +} + +UpdateStatus LoraModuleConnectAction::Update() { + if (state_.changed()) { + switch (state_.Acquire()) { + case State::kStart: + Start(); + break; + case State::kSuccess: + return UpdateStatus::Result(); + case State::kFailed: + return UpdateStatus::Error(); + } + } + return {}; +} + +void LoraModuleConnectAction::Start() { + AE_TELED_DEBUG("LoraModuleConnectAction start"); + auto action = driver_->Start(); + if (!action) { + state_ = State::kFailed; + Action::Trigger(); + return; + } + action->StatusEvent().Subscribe(ActionHandler{ + OnResult{[this]() { + AE_TELED_INFO("Lora module access point start success"); + state_ = State::kSuccess; + Action::Trigger(); + }}, + OnError{[this]() { + AE_TELED_ERROR("Lora module access point start failed"); + state_ = State::kFailed; + Action::Trigger(); + }}, + }); +} + LoraModuleAccessPoint::JoinAction::JoinAction(ActionContext action_context) : Action{action_context} {} @@ -40,6 +83,23 @@ LoraModuleAccessPoint::LoraModuleAccessPoint( aether_{std::move(aether)}, lora_module_adapter_{std::move(lora_module_adapter)} {} +ActionPtr LoraModuleAccessPoint::Connect() { + AE_TELED_DEBUG("Make lora module access point connection"); + + // reuse connect action if it's in progress + if (!connect_action_) { + connect_action_ = ActionPtr{ + *aether_.as(), lora_module_adapter_->lora_module_driver()}; + connect_sub_ = connect_action_->FinishedEvent().Subscribe( + [this]() { connect_action_.reset(); }); + } + return connect_action_; +} + +ILoraModuleDriver& LoraModuleAccessPoint::lora_module_driver() { + return lora_module_adapter_->lora_module_driver(); +} + ActionPtr LoraModuleAccessPoint::Join() { return ActionPtr{*aether_}; } diff --git a/aether/access_points/lora_module_access_point.h b/aether/access_points/lora_module_access_point.h index 5a1b0140..d82c321d 100644 --- a/aether/access_points/lora_module_access_point.h +++ b/aether/access_points/lora_module_access_point.h @@ -29,6 +29,28 @@ # include "aether/lora_modules/gw_lora_device.h" namespace ae { +class Aether; + +class LoraModuleConnectAction final : public Action { + public: + enum class State : std::uint8_t { + kStart, + kSuccess, + kFailed, + }; + + LoraModuleConnectAction(ActionContext action_context, ILoraModuleDriver& driver); + + UpdateStatus Update(); + + private: + void Start(); + + ILoraModuleDriver* driver_; + Subscription start_sub_; + StateMachine state_; +}; + class LoraModuleAccessPoint final : public AccessPoint { AE_OBJECT(LoraModuleAccessPoint, AccessPoint, 0) LoraModuleAccessPoint() = default; @@ -46,6 +68,9 @@ class LoraModuleAccessPoint final : public AccessPoint { AE_OBJECT_REFLECT(AE_MMBRS(lora_module_adapter_)); + ActionPtr Connect(); + ILoraModuleDriver& lora_module_driver(); + ActionPtr Join(); std::vector> GenerateChannels( @@ -56,7 +81,9 @@ class LoraModuleAccessPoint final : public AccessPoint { private: Aether::ptr aether_; - Adapter::ptr lora_module_adapter_; + LoraModuleAdapter::ptr lora_module_adapter_; + ActionPtr connect_action_; + Subscription connect_sub_; std::unique_ptr gw_lora_device_; }; } // namespace ae diff --git a/aether/adapters/lora_module_adapter.h b/aether/adapters/lora_module_adapter.h index 7b95b1e6..1874ea5a 100644 --- a/aether/adapters/lora_module_adapter.h +++ b/aether/adapters/lora_module_adapter.h @@ -17,21 +17,19 @@ #ifndef AETHER_ADAPTERS_LORA_MODULE_ADAPTER_H_ #define AETHER_ADAPTERS_LORA_MODULE_ADAPTER_H_ -#include "aether/config.h" +#include -#if AE_SUPPORT_LORA -# include +#include "aether/config.h" +#if AE_SUPPORT_LORA && AE_SUPPORT_GATEWAY # include "aether/events/events.h" # include "aether/lora_modules/ilora_module_driver.h" # include "aether/adapters/parent_lora_module.h" # include "aether/access_points/access_point.h" -# define LORA_MODULE_TCP_TRANSPORT_ENABLED 1 - namespace ae { -class LoraModuleAdapter : public ParentLoraModuleAdapter { +class LoraModuleAdapter final : public ParentLoraModuleAdapter { AE_OBJECT(LoraModuleAdapter, ParentLoraModuleAdapter, 0) LoraModuleAdapter() = default; diff --git a/aether/adapters/parent_lora_module.h b/aether/adapters/parent_lora_module.h index 56a25390..7888b3ec 100644 --- a/aether/adapters/parent_lora_module.h +++ b/aether/adapters/parent_lora_module.h @@ -19,7 +19,8 @@ #include "aether/config.h" -#if AE_SUPPORT_LORA +#if AE_SUPPORT_LORA && AE_SUPPORT_GATEWAY + # include "aether/aether.h" # include "aether/adapters/adapter.h" # include "aether/lora_modules/lora_module_driver_types.h" @@ -47,5 +48,6 @@ class ParentLoraModuleAdapter : public Adapter { LoraModuleInit lora_module_init_; }; } // namespace ae + #endif #endif // AETHER_ADAPTERS_PARENT_LORA_MODULE_H_ diff --git a/aether/channels/lora_module_channel.cpp b/aether/channels/lora_module_channel.cpp index fb08fa31..59dd997c 100644 --- a/aether/channels/lora_module_channel.cpp +++ b/aether/channels/lora_module_channel.cpp @@ -28,7 +28,13 @@ namespace ae { namespace lora_module_channel_internal { class LoraModuleTransportBuilderAction final : public TransportBuilderAction { - enum class State : std::uint8_t { kJoin, kCreateTransport, kResult, kError }; + enum class State : std::uint8_t { + kMLoraModuleConnect, + kJoin, + kTransportCreate, + kResult, + kError + }; public: LoraModuleTransportBuilderAction(ActionContext action_context, @@ -38,7 +44,7 @@ class LoraModuleTransportBuilderAction final : public TransportBuilderAction { action_context_{action_context}, access_point_{&access_point}, server_{server}, - state_{State::kJoin} { + state_{State::kMLoraModuleConnect} { AE_TELED_DEBUG("Lora module transport building"); state_.changed_event().Subscribe([this](auto) { Action::Trigger(); }); } @@ -46,10 +52,13 @@ class LoraModuleTransportBuilderAction final : public TransportBuilderAction { UpdateStatus Update() override { if (state_.changed()) { switch (state_.Acquire()) { + case State::kMLoraModuleConnect: + ConnectLoraModule(); + break; case State::kJoin: Join(); break; - case State::kCreateTransport: + case State::kTransportCreate: CreateTransport(); break; case State::kResult: @@ -66,10 +75,24 @@ class LoraModuleTransportBuilderAction final : public TransportBuilderAction { } private: + void ConnectLoraModule() { + modem_connect_sub_ = + access_point_->Connect()->StatusEvent().Subscribe(ActionHandler{ + OnResult{[this]() { + state_ = State::kTransportCreate; + Action::Trigger(); + }}, + OnError{[this]() { + state_ = State::kError; + Action::Trigger(); + }}, + }); + } + void Join() { auto join = access_point_->Join(); join->StatusEvent().Subscribe(ActionHandler{ - OnResult{[this]() { state_ = State::kCreateTransport; }}, + OnResult{[this]() { state_ = State::kTransportCreate; }}, OnError{[this]() { state_ = State::kError; }}, }); } @@ -94,6 +117,7 @@ class LoraModuleTransportBuilderAction final : public TransportBuilderAction { StateMachine state_; std::unique_ptr transport_stream_; + Subscription modem_connect_sub_; }; } // namespace lora_module_channel_internal diff --git a/aether/lora_modules/dx_smart_lr02_lm.cpp b/aether/lora_modules/dx_smart_lr02_lm.cpp index f630384f..d22b861e 100644 --- a/aether/lora_modules/dx_smart_lr02_lm.cpp +++ b/aether/lora_modules/dx_smart_lr02_lm.cpp @@ -38,7 +38,7 @@ static const AtRequest::Wait kWaitEntryAt{"Entry AT", kOneSecond}; static const AtRequest::Wait kWaitExitAt{"Exit AT", kOneSecond}; static const AtRequest::Wait kWaitPowerOn{"Power on", kOneSecond}; -class DxSmartLr02LoraOpenNetwork final + class DxSmartLr02LoraOpenNetwork final : public Action { public: DxSmartLr02LoraOpenNetwork(ActionContext action_context, diff --git a/aether/lora_modules/gw_lora_device.cpp b/aether/lora_modules/gw_lora_device.cpp index d30ea1dd..ee077fe6 100644 --- a/aether/lora_modules/gw_lora_device.cpp +++ b/aether/lora_modules/gw_lora_device.cpp @@ -44,19 +44,8 @@ GwLoraDevice::~GwLoraDevice() {} ActionPtr GwLoraDevice::ToServer(ClientId client_id, ServerId server_id, DataBuffer&& data) { - LoraPacket lora_packet{}; auto api = ApiContext{gateway_api_}; - - lora_packet.length = data.size(); - lora_packet.data = data; - lora_packet.crc = crc32::from_buffer(data.data(), data.size()).value; - - std::vector packet_data; - auto writer = ae::VectorWriter<>{packet_data}; - auto os = ae::omstream{writer}; - os << lora_packet; - - api->to_server_id(client_id, server_id, std::move(packet_data)); + api->to_server_id(client_id, server_id, std::move(data)); DataBuffer packet = std::move(api); AE_TELED_DEBUG("Publish from device_id {} data {}", @@ -69,19 +58,8 @@ ActionPtr GwLoraDevice::ToServer(ClientId client_id, ActionPtr GwLoraDevice::ToServer( ClientId client_id, ServerEndpoints const& server_endpoints, DataBuffer&& data) { - LoraPacket lora_packet{}; auto api = ApiContext{gateway_api_}; - - lora_packet.length = data.size(); - lora_packet.data = data; - lora_packet.crc = crc32::from_buffer(data.data(), data.size()).value; - - std::vector packet_data; - auto writer = ae::VectorWriter<>{packet_data}; - auto os = ae::omstream{writer}; - os << lora_packet; - - api->to_server(client_id, server_endpoints, std::move(packet_data)); + api->to_server(client_id, server_endpoints, std::move(data)); DataBuffer packet = std::move(api); AE_TELED_DEBUG("Publish from device_id {} data {}",