Skip to content

Commit 8f5cbe7

Browse files
committed
- CS104 slave: added functions to set callback handlers for reset process and delay acquisition commands (#137)
1 parent 2650583 commit 8f5cbe7

3 files changed

Lines changed: 178 additions & 5 deletions

File tree

lib60870-C/src/iec60870/cs104/cs104_slave.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,7 +1433,7 @@ createSlave(int maxLowPrioQueueSize, int maxHighPrioQueueSize)
14331433
{
14341434
CS104_Slave self = (CS104_Slave)GLOBAL_CALLOC(1, sizeof(struct sCS104_Slave));
14351435

1436-
if (self != NULL)
1436+
if (self)
14371437
{
14381438
self->conParameters = defaultConnectionParameters;
14391439
self->alParameters = defaultAppLayerParameters;
@@ -1751,6 +1751,20 @@ CS104_Slave_setClockSyncHandler(CS104_Slave self, CS101_ClockSynchronizationHand
17511751
self->clockSyncHandlerParameter = parameter;
17521752
}
17531753

1754+
void
1755+
CS104_Slave_setResetProcessHandler(CS104_Slave self, CS101_ResetProcessHandler handler, void* parameter)
1756+
{
1757+
self->resetProcessHandler = handler;
1758+
self->resetProcessHandlerParameter = parameter;
1759+
}
1760+
1761+
void
1762+
CS104_Slave_setDelayAcquisitionHandler(CS104_Slave self, CS101_DelayAcquisitionHandler handler, void* parameter)
1763+
{
1764+
self->delayAcquisitionHandler = handler;
1765+
self->delayAcquisitionHandlerParameter = parameter;
1766+
}
1767+
17541768
void
17551769
CS104_Slave_setRawMessageHandler(CS104_Slave self, CS104_SlaveRawMessageHandler handler, void* parameter)
17561770
{
@@ -2243,7 +2257,7 @@ handleASDU(MasterConnection self, CS101_ASDU asdu)
22432257

22442258
if (cot == CS101_COT_ACTIVATION)
22452259
{
2246-
if (slave->clockSyncHandler != NULL)
2260+
if (slave->clockSyncHandler)
22472261
{
22482262
union uInformationObject _io;
22492263

@@ -2363,7 +2377,7 @@ handleASDU(MasterConnection self, CS101_ASDU asdu)
23632377

23642378
if (cot == CS101_COT_ACTIVATION)
23652379
{
2366-
if (slave->resetProcessHandler != NULL)
2380+
if (slave->resetProcessHandler)
23672381
{
23682382
union uInformationObject _io;
23692383

@@ -2414,7 +2428,7 @@ handleASDU(MasterConnection self, CS101_ASDU asdu)
24142428

24152429
if ((cot == CS101_COT_ACTIVATION) || (cot == CS101_COT_SPONTANEOUS))
24162430
{
2417-
if (slave->delayAcquisitionHandler != NULL)
2431+
if (slave->delayAcquisitionHandler)
24182432
{
24192433
union uInformationObject _io;
24202434

lib60870-C/src/inc/api/cs104_slave.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,24 +216,74 @@ CS104_Slave_setConnectionRequestHandler(CS104_Slave self, CS104_ConnectionReques
216216
void
217217
CS104_Slave_setConnectionEventHandler(CS104_Slave self, CS104_ConnectionEventHandler handler, void* parameter);
218218

219+
/**
220+
* \brief Set the handler for the general interrogation message
221+
*
222+
* \param handler the callback handler function
223+
* \param parameter user provided parameter to be passed to the callback handler
224+
*/
219225
void
220226
CS104_Slave_setInterrogationHandler(CS104_Slave self, CS101_InterrogationHandler handler, void* parameter);
221227

228+
/**
229+
* \brief Set the handler for the counter interrogation message
230+
*
231+
* \param handler the callback handler function
232+
* \param parameter user provided parameter to be passed to the callback handler
233+
*/
222234
void
223235
CS104_Slave_setCounterInterrogationHandler(CS104_Slave self, CS101_CounterInterrogationHandler handler, void* parameter);
224236

225237
/**
226238
* \brief set handler for read request (C_RD_NA_1 - 102)
239+
*
240+
* \param handler the callback handler function
241+
* \param parameter user provided parameter to be passed to the callback handler
227242
*/
228243
void
229244
CS104_Slave_setReadHandler(CS104_Slave self, CS101_ReadHandler handler, void* parameter);
230245

246+
/**
247+
* \brief Set the handler for a received ASDU
248+
*
249+
* NOTE: This a generic handler that will only be called when the ASDU has not been handled by
250+
* one of the other callback handlers.
251+
*
252+
* \param handler the callback handler function
253+
* \param parameter user provided parameter to be passed to the callback handler
254+
*/
231255
void
232256
CS104_Slave_setASDUHandler(CS104_Slave self, CS101_ASDUHandler handler, void* parameter);
233257

258+
/**
259+
* \brief Set the handler for the clock synchronization message
260+
*
261+
* \param handler the callback handler function
262+
* \param parameter user provided parameter to be passed to the callback handler
263+
*/
234264
void
235265
CS104_Slave_setClockSyncHandler(CS104_Slave self, CS101_ClockSynchronizationHandler handler, void* parameter);
236266

267+
/**
268+
* \brief Set the handler for the reset process message (C_RP_NA_1)
269+
*
270+
* \param handler the callback handler function
271+
* \param parameter user provided parameter to be passed to the callback handler
272+
*/
273+
void
274+
CS104_Slave_setResetProcessHandler(CS104_Slave self, CS101_ResetProcessHandler handler, void* parameter);
275+
276+
/**
277+
* \brief Set the handler for the delay acquisition message (C_CD_NA_1)
278+
*
279+
* \note Do not use! The delay acquisition command is not allowed for CS 104.
280+
*
281+
* \param handler the callback handler function
282+
* \param parameter user provided parameter to be passed to the callback handler
283+
*/
284+
void
285+
CS104_Slave_setDelayAcquisitionHandler(CS104_Slave self, CS101_DelayAcquisitionHandler handler, void* parameter);
286+
237287
/**
238288
* \brief Set the raw message callback (called when a message is sent or received)
239289
*

lib60870-C/tests/all_tests.c

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6882,7 +6882,6 @@ test_CS104Slave_handleTestCommand_asduReceivedHandler (void* parameter, int addr
68826882
void
68836883
test_CS104Slave_handleTestCommandWithTimestamp()
68846884
{
6885-
//TODO install asduHandler to intercept
68866885
CS101_ASDU receivedASDU = NULL;
68876886

68886887
CS104_Slave slave = CS104_Slave_create(10, 10);
@@ -7160,6 +7159,114 @@ test_CS104Slave_rejectCommandWithUnknownCA()
71607159
CS104_Slave_destroy(slave);
71617160
}
71627161

7162+
bool
7163+
test_ResetProcessHandler(void* parameter, IMasterConnection connection, CS101_ASDU asdu, uint8_t qrp)
7164+
{
7165+
int* resetProcessHandlerCalled = (int*)parameter;
7166+
7167+
if (resetProcessHandlerCalled)
7168+
{
7169+
*resetProcessHandlerCalled = *resetProcessHandlerCalled + 1;
7170+
}
7171+
7172+
IMasterConnection_sendACT_CON(connection, asdu, false);
7173+
7174+
return true;
7175+
}
7176+
7177+
void
7178+
test_CS104Slave_handleResetProcessCommand()
7179+
{
7180+
CS101_ASDU receivedASDU = NULL;
7181+
int resetProcessHandlerCalled = 0;
7182+
7183+
CS104_Slave slave = CS104_Slave_create(10, 10);
7184+
7185+
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
7186+
CS104_Slave_setLocalPort(slave, 20004);
7187+
7188+
CS104_Slave_start(slave);
7189+
7190+
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
7191+
7192+
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
7193+
7194+
bool result = CS104_Connection_connect(con);
7195+
TEST_ASSERT_TRUE(result);
7196+
7197+
CS104_Connection_setASDUReceivedHandler(con, test_CS104Slave_handleTestCommand_asduReceivedHandler, &receivedASDU);
7198+
7199+
CS104_Connection_sendStartDT(con);
7200+
7201+
ResetProcessCommand rpc = ResetProcessCommand_create(NULL, 0, 0);
7202+
7203+
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
7204+
7205+
CS101_ASDU_addInformationObject(asdu, (InformationObject) rpc);
7206+
ResetProcessCommand_destroy(rpc);
7207+
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
7208+
CS101_ASDU_destroy(asdu);
7209+
7210+
Thread_sleep(500);
7211+
7212+
TEST_ASSERT_NOT_NULL(receivedASDU);
7213+
TEST_ASSERT_EQUAL_INT(C_RP_NA_1, CS101_ASDU_getTypeID(receivedASDU));
7214+
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_TYPE_ID, CS101_ASDU_getCOT(receivedASDU));
7215+
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
7216+
7217+
if (receivedASDU) {
7218+
CS101_ASDU_destroy(receivedASDU);
7219+
receivedASDU = NULL;
7220+
}
7221+
7222+
CS104_Slave_setResetProcessHandler(slave, test_ResetProcessHandler, &resetProcessHandlerCalled);
7223+
7224+
rpc = ResetProcessCommand_create(NULL, 0, 0);
7225+
7226+
asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
7227+
7228+
CS101_ASDU_addInformationObject(asdu, (InformationObject) rpc);
7229+
ResetProcessCommand_destroy(rpc);
7230+
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
7231+
CS101_ASDU_destroy(asdu);
7232+
7233+
Thread_sleep(500);
7234+
7235+
TEST_ASSERT_NOT_NULL(receivedASDU);
7236+
TEST_ASSERT_EQUAL_INT(C_RP_NA_1, CS101_ASDU_getTypeID(receivedASDU));
7237+
TEST_ASSERT_EQUAL_INT(CS101_COT_ACTIVATION_CON, CS101_ASDU_getCOT(receivedASDU));
7238+
TEST_ASSERT_FALSE(CS101_ASDU_isNegative(receivedASDU));
7239+
TEST_ASSERT_EQUAL_INT(1, resetProcessHandlerCalled);
7240+
7241+
/* send reset process command with invalid IOA (!= 0) */
7242+
7243+
rpc = ResetProcessCommand_create(NULL, 1, 0);
7244+
7245+
asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
7246+
7247+
CS101_ASDU_addInformationObject(asdu, (InformationObject) rpc);
7248+
ResetProcessCommand_destroy(rpc);
7249+
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
7250+
CS101_ASDU_destroy(asdu);
7251+
7252+
Thread_sleep(500);
7253+
7254+
TEST_ASSERT_NOT_NULL(receivedASDU);
7255+
TEST_ASSERT_EQUAL_INT(C_RP_NA_1, CS101_ASDU_getTypeID(receivedASDU));
7256+
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_IOA, CS101_ASDU_getCOT(receivedASDU));
7257+
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
7258+
TEST_ASSERT_EQUAL_INT(1, resetProcessHandlerCalled);
7259+
7260+
CS104_Connection_close(con);
7261+
7262+
CS104_Connection_destroy(con);
7263+
7264+
if (receivedASDU)
7265+
CS101_ASDU_destroy(receivedASDU);
7266+
7267+
CS104_Slave_destroy(slave);
7268+
}
7269+
71637270
int
71647271
main(int argc, char** argv)
71657272
{
@@ -7299,5 +7406,7 @@ main(int argc, char** argv)
72997406

73007407
RUN_TEST(test_CS104Slave_rejectCommandWithUnknownCA);
73017408

7409+
RUN_TEST(test_CS104Slave_handleResetProcessCommand);
7410+
73027411
return UNITY_END();
73037412
}

0 commit comments

Comments
 (0)