@@ -100,11 +100,11 @@ Server::Server(const std::string &bind_ip, const std::uint_fast16_t tcp_port,
100100
101101 appLayerParameters = CS104_Slave_getAppLayerParameters (slave);
102102
103- // reduce lib60870-C connection timeout down to 2s
104- auto param = CS104_Slave_getConnectionParameters (slave);
105- param->t0 = 2 ; // socket connect timeout
106- param->t1 = 2 ; // acknowledgement timeout
107- param->t2 = 1 ; // acknowledgement interval
103+ // use lib60870-C defaults for connection timeouts
104+ // auto param = CS104_Slave_getConnectionParameters(slave);
105+ // param->t0 = 10 ; // socket connect timeout
106+ // param->t1 = 15 ; // acknowledgement timeout
107+ // param->t2 = 10 ; // acknowledgement interval
108108
109109 // Function pointers for custom handler functions
110110 void *key = static_cast <void *>(this );
@@ -243,38 +243,33 @@ void Server::scheduleDataPointTimer() {
243243}
244244
245245void Server::schedulePeriodicTask (const std::function<void ()> &task,
246- int interval) {
247- {
248- if (interval < 50 ) {
249- throw std::out_of_range (
250- " The interval for periodic tasks must be 1000ms at minimum." );
251- }
252- auto periodic = std::make_shared<std::function<void ()>>(
253- []() {}); // Empty function initially
254- std::weak_ptr<std::function<void ()>> weakPeriodic =
255- periodic; // Weak reference
256- std::weak_ptr<Server> weakSelf =
257- shared_from_this (); // Weak reference to `this`
246+ std::int_fast32_t interval) {
247+ if (interval < 50 ) {
248+ throw std::out_of_range (
249+ " The interval for periodic tasks must be 50ms at minimum." );
250+ }
258251
259- *periodic = [weakSelf, task, interval, weakPeriodic]() {
260- auto self = weakSelf.lock ();
261- if (!self)
262- return ; // Prevent running if `this` was destroyed
252+ std::weak_ptr<Server> weakSelf =
253+ shared_from_this (); // Weak reference to `this`
263254
264- // Schedule next execution
265- if (auto periodicLock = weakPeriodic.lock ()) { // Try to lock weak_ptr
266- self->scheduleTask (*periodicLock, interval);
267- }
268- task ();
269- };
270- // Schedule first execution
271- scheduleTask (*periodic, interval);
272- }
255+ auto periodicCallback = [weakSelf, task, interval]() {
256+ auto self = weakSelf.lock ();
257+ if (!self)
258+ return ; // Prevent running if `this` was destroyed
259+
260+ // Schedule next execution
261+ self->schedulePeriodicTask (task, interval); // Reschedule itself
262+
263+ task ();
264+ };
265+ // Schedule first execution
266+ scheduleTask (periodicCallback, interval);
273267
274268 runThread_wait.notify_one ();
275269}
276270
277- void Server::scheduleTask (const std::function<void ()> &task, int delay) {
271+ void Server::scheduleTask (const std::function<void ()> &task,
272+ std::int_fast32_t delay) {
278273 {
279274 std::lock_guard<std::mutex> lock (runThread_mutex);
280275 if (delay < 0 ) {
@@ -741,44 +736,48 @@ void Server::onUnexpectedMessage(
741736 std::shared_ptr<Remote::Message::IncomingMessage> message,
742737 UnexpectedMessageCause cause) {
743738 CS101_ASDU asdu = message->getAsdu ();
739+
740+ // manipulate and send copy instead of original ASDU
741+ CS101_ASDU cp = CS101_ASDU_clone (asdu, nullptr );
744742 switch (cause) {
745743 case INVALID_TYPE_ID :
746744 DEBUG_PRINT (Debug::Server, " on_unexpected_message] Invalid type id" );
747- CS101_ASDU_setCOT (asdu , CS101_COT_UNKNOWN_TYPE_ID );
748- IMasterConnection_sendASDU (connection, asdu );
745+ CS101_ASDU_setCOT (cp , CS101_COT_UNKNOWN_TYPE_ID );
746+ IMasterConnection_sendASDU (connection, cp );
749747 break ;
750748 case MISMATCHED_TYPE_ID :
751749 DEBUG_PRINT (Debug::Server, " on_unexpected_message] Mismatching type id" );
752- CS101_ASDU_setCOT (asdu , CS101_COT_UNKNOWN_TYPE_ID );
753- IMasterConnection_sendASDU (connection, asdu );
750+ CS101_ASDU_setCOT (cp , CS101_COT_UNKNOWN_TYPE_ID );
751+ IMasterConnection_sendASDU (connection, cp );
754752 break ;
755753 case UNKNOWN_TYPE_ID :
756754 DEBUG_PRINT (Debug::Server, " on_unexpected_message] Unknown type id" );
757- CS101_ASDU_setCOT (asdu , CS101_COT_UNKNOWN_TYPE_ID );
758- IMasterConnection_sendASDU (connection, asdu );
755+ CS101_ASDU_setCOT (cp , CS101_COT_UNKNOWN_TYPE_ID );
756+ IMasterConnection_sendASDU (connection, cp );
759757 break ;
760758 case INVALID_COT :
761759 case UNKNOWN_COT :
762760 DEBUG_PRINT (Debug::Server, " on_unexpected_message] Invalid COT" );
763- CS101_ASDU_setCOT (asdu , CS101_COT_UNKNOWN_COT );
764- IMasterConnection_sendASDU (connection, asdu );
761+ CS101_ASDU_setCOT (cp , CS101_COT_UNKNOWN_COT );
762+ IMasterConnection_sendASDU (connection, cp );
765763 break ;
766764 case UNKNOWN_CA :
767765 DEBUG_PRINT (Debug::Server, " on_unexpected_message] Unknown CA" );
768- CS101_ASDU_setCOT (asdu , CS101_COT_UNKNOWN_CA );
769- IMasterConnection_sendASDU (connection, asdu );
766+ CS101_ASDU_setCOT (cp , CS101_COT_UNKNOWN_CA );
767+ IMasterConnection_sendASDU (connection, cp );
770768 break ;
771769 case UNKNOWN_IOA :
772770 DEBUG_PRINT (Debug::Server, " on_unexpected_message] Unknown IOA" );
773- CS101_ASDU_setCOT (asdu , CS101_COT_UNKNOWN_IOA );
774- IMasterConnection_sendASDU (connection, asdu );
771+ CS101_ASDU_setCOT (cp , CS101_COT_UNKNOWN_IOA );
772+ IMasterConnection_sendASDU (connection, cp );
775773 break ;
776774 case UNIMPLEMENTED_GROUP :
777775 DEBUG_PRINT (Debug::Server, " on_unexpected_message] Unimplemented group" );
778776 break ;
779777 default : {
780778 }
781779 }
780+ CS101_ASDU_destroy (cp);
782781
783782 if (py_onUnexpectedMessage.is_set ()) {
784783 std::weak_ptr<Server> weakSelf =
@@ -1102,40 +1101,46 @@ void Server::sendActivationConfirmation(IMasterConnection connection,
11021101 if (!isExistingConnection (connection))
11031102 return ;
11041103
1105- CS101_ASDU_setCOT (asdu, CS101_COT_ACTIVATION_CON );
1106- CS101_ASDU_setNegative (asdu, negative);
1104+ // manipulate copy instead of original asdu
1105+ CS101_ASDU cp = CS101_ASDU_clone (asdu, nullptr );
1106+ CS101_ASDU_setCOT (cp, CS101_COT_ACTIVATION_CON );
1107+ CS101_ASDU_setNegative (cp, negative);
11071108
11081109 if (isGlobalCommonAddress (CS101_ASDU_getCA (asdu))) {
11091110 DEBUG_PRINT (Debug::Server, " send_activation_confirmation] to all MTUs" );
11101111 std::lock_guard<Module::GilAwareMutex> const st_lock (station_mutex);
11111112 for (auto &s : stations) {
1112- CS101_ASDU_setCA (asdu , s->getCommonAddress ());
1113- IMasterConnection_sendASDU (connection, asdu );
1113+ CS101_ASDU_setCA (cp , s->getCommonAddress ());
1114+ IMasterConnection_sendASDU (connection, cp );
11141115 }
11151116 } else {
11161117 DEBUG_PRINT (Debug::Server,
11171118 " send_activation_confirmation] to requesting MTU" );
1118- IMasterConnection_sendASDU (connection, asdu );
1119+ IMasterConnection_sendASDU (connection, cp );
11191120 }
1121+ CS101_ASDU_destroy (cp);
11201122}
11211123
11221124void Server::sendActivationTermination (IMasterConnection connection,
11231125 CS101_ASDU asdu) {
11241126 if (!isExistingConnection (connection))
11251127 return ;
11261128
1127- CS101_ASDU_setCOT (asdu, CS101_COT_ACTIVATION_TERMINATION );
1129+ // manipulate copy instead of original asdu
1130+ CS101_ASDU cp = CS101_ASDU_clone (asdu, nullptr );
1131+ CS101_ASDU_setCOT (cp, CS101_COT_ACTIVATION_TERMINATION );
11281132
11291133 if (isGlobalCommonAddress (CS101_ASDU_getCA (asdu))) {
11301134
11311135 std::lock_guard<Module::GilAwareMutex> const st_lock (station_mutex);
11321136 for (auto &s : stations) {
1133- CS101_ASDU_setCA (asdu , s->getCommonAddress ());
1134- IMasterConnection_sendASDU (connection, asdu );
1137+ CS101_ASDU_setCA (cp , s->getCommonAddress ());
1138+ IMasterConnection_sendASDU (connection, cp );
11351139 }
11361140 } else {
1137- IMasterConnection_sendASDU (connection, asdu );
1141+ IMasterConnection_sendASDU (connection, cp );
11381142 }
1143+ CS101_ASDU_destroy (cp);
11391144}
11401145
11411146void Server::sendEndOfInitialization (const std::uint_fast16_t commonAddress,
@@ -1332,7 +1337,7 @@ bool Server::interrogationHandler(void *parameter, IMasterConnection connection,
13321337 }
13331338 } catch (const std::exception &e) {
13341339 DEBUG_PRINT (Debug::Server,
1335- " Invalid point message for counter interrogation: " +
1340+ " Invalid point message for interrogation: " +
13361341 std::string (e.what ()));
13371342 }
13381343 }
0 commit comments