IC_104/lib60870-C/tests/all_tests.c
George 1ddf693260 feat:
--READ smash_read_this.txt
2026-06-22 16:04:13 +05:30

9634 lines
378 KiB
C

#include "buffer_frame.h"
#include "cs104_connection.h"
#include "cs104_slave.h"
#include "hal_socket.h"
#include "hal_thread.h"
#include "hal_time.h"
#include "iec60870_common.h"
#include "unity.h"
#include <stdlib.h>
#include <string.h>
#ifndef CONFIG_CS104_SUPPORT_TLS
#define CONFIG_CS104_SUPPORT_TLS 0
#endif
#if WIN32
#define bzero(b, len) (memset((b), '\0', (len)), (void)0)
#endif
void
setUp(void)
{
}
void
tearDown(void)
{
}
static struct sCS101_AppLayerParameters defaultAppLayerParameters = {
/* .sizeOfTypeId = */ 1,
/* .sizeOfVSQ = */ 1,
/* .sizeOfCOT = */ 2,
/* .originatorAddress = */ 0,
/* .sizeOfCA = */ 2,
/* .sizeOfIOA = */ 3,
/* .maxSizeOfASDU = */ 249};
typedef struct sCS104_IPAddress* CS104_IPAddress;
struct sCS104_IPAddress
{
uint8_t address[16];
eCS104_IPAddressType type;
};
/* declaration of library internal function */
void
InformationObject_setObjectAddress(InformationObject self, int ioa);
static bool
CS104_IPAddress_setFromString(CS104_IPAddress self, const char* ipAddrStr)
{
if (strchr(ipAddrStr, '.') != NULL)
{
/* parse IPv4 string */
self->type = IP_ADDRESS_TYPE_IPV4;
int i;
for (i = 0; i < 4; i++)
{
uint32_t val = strtoul(ipAddrStr, NULL, 10);
if (val > UINT8_MAX)
return false;
self->address[i] = val;
ipAddrStr = strchr(ipAddrStr, '.');
if ((ipAddrStr == NULL) || (*ipAddrStr == 0))
break;
ipAddrStr++;
}
return true;
}
else if (strchr(ipAddrStr, ':') != NULL)
{
self->type = IP_ADDRESS_TYPE_IPV6;
/* has "::" ? */
char* doubleSep = (char*)strstr(ipAddrStr, "::");
int elementsBefore = 0;
int elementsAfter = 8;
int elementsSkipped = 0;
if (doubleSep)
{
/* count number of elements before double separator */
char* curPos = (char*)ipAddrStr;
if (curPos != doubleSep)
{
elementsBefore = 1;
while (curPos < doubleSep)
{
if (*curPos == ':')
elementsBefore++;
curPos++;
}
}
/* count number of elements after double separator */
elementsAfter = 0;
curPos = doubleSep + 2;
if (*curPos != 0)
{
elementsAfter = 1;
while (*curPos != 0)
{
if (*curPos == ':')
elementsAfter++;
curPos++;
}
}
elementsSkipped = 8 - elementsBefore - elementsAfter;
}
int i;
for (i = 0; i < elementsBefore; i++)
{
uint32_t val = strtoul(ipAddrStr, NULL, 16);
if (val > UINT16_MAX)
return false;
self->address[i * 2] = val / 0x100;
self->address[i * 2 + 1] = val % 0x100;
ipAddrStr = strchr(ipAddrStr, ':');
if ((ipAddrStr == NULL) || (*ipAddrStr == 0))
break;
ipAddrStr++;
}
for (i = elementsBefore; i < elementsBefore + elementsSkipped; i++)
{
self->address[i * 2] = 0;
self->address[i * 2 + 1] = 0;
}
if (doubleSep)
ipAddrStr = doubleSep + 2;
for (i = elementsBefore + elementsSkipped; i < 8; i++)
{
uint32_t val = strtoul(ipAddrStr, NULL, 16);
if (val > UINT16_MAX)
return false;
self->address[i * 2] = val / 0x100;
self->address[i * 2 + 1] = val % 0x100;
ipAddrStr = strchr(ipAddrStr, ':');
if ((ipAddrStr == NULL) || (*ipAddrStr == 0))
break;
ipAddrStr++;
}
return true;
}
else
{
return false;
}
}
static bool
CS104_IPAddress_equals(CS104_IPAddress self, CS104_IPAddress other)
{
if (self->type != other->type)
return false;
int size;
if (self->type == IP_ADDRESS_TYPE_IPV4)
size = 4;
else
size = 16;
int i;
for (i = 0; i < size; i++)
{
if (self->address[i] != other->address[i])
return false;
}
return true;
}
#ifdef __cplusplus
extern "C"
{
#endif
void
CS101_ASDU_encode(CS101_ASDU self, Frame frame);
#ifdef __cplusplus
}
#endif
void
test_CP56Time2a(void)
{
struct sCP56Time2a currentTime;
uint64_t currentTimestamp = Hal_getTimeInMs();
CP56Time2a_createFromMsTimestamp(&currentTime, currentTimestamp);
uint64_t convertedTimestamp = CP56Time2a_toMsTimestamp(&currentTime);
TEST_ASSERT_EQUAL_UINT64(currentTimestamp, convertedTimestamp);
}
void
test_CP56Time2aToMsTimestamp(void)
{
struct sCP56Time2a timeval;
timeval.encodedValue[0] = 0x85;
timeval.encodedValue[1] = 0x49;
timeval.encodedValue[2] = 0x0c;
timeval.encodedValue[3] = 0x09;
timeval.encodedValue[4] = 0x55;
timeval.encodedValue[5] = 0x03;
timeval.encodedValue[6] = 0x11;
uint64_t convertedTimeval = CP56Time2a_toMsTimestamp(&timeval);
TEST_ASSERT_EQUAL_UINT64((uint64_t)1490087538821, convertedTimeval);
}
void
test_CP56Time2aConversionFunctions(void)
{
uint64_t currentTime = Hal_getTimeInMs();
struct sCP56Time2a timeval;
CP56Time2a_setFromMsTimestamp(&timeval, currentTime);
uint64_t convertedTime = CP56Time2a_toMsTimestamp(&timeval);
TEST_ASSERT_EQUAL_UINT64(currentTime, convertedTime);
}
void
test_StepPositionInformation(void)
{
StepPositionInformation spi1;
StepPositionInformation spi2;
StepPositionInformation spi3;
StepPositionInformation spi4;
StepPositionInformation spi5;
StepPositionInformation spi6;
StepPositionInformation spi7;
StepPositionInformation spi8;
spi1 = StepPositionInformation_create(NULL, 101, 0, true, IEC60870_QUALITY_GOOD);
spi2 = StepPositionInformation_create(NULL, 102, 63, false, IEC60870_QUALITY_OVERFLOW);
spi3 = StepPositionInformation_create(NULL, 103, 62, false, IEC60870_QUALITY_RESERVED);
spi4 = StepPositionInformation_create(NULL, 104, 61, false, IEC60870_QUALITY_ELAPSED_TIME_INVALID);
spi5 = StepPositionInformation_create(NULL, 105, -61, false, IEC60870_QUALITY_BLOCKED);
spi6 = StepPositionInformation_create(NULL, 106, -62, false, IEC60870_QUALITY_SUBSTITUTED);
spi7 = StepPositionInformation_create(NULL, 107, -63, false, IEC60870_QUALITY_NON_TOPICAL);
spi8 = StepPositionInformation_create(NULL, 108, 0, false, IEC60870_QUALITY_INVALID);
TEST_ASSERT_EQUAL_INT(0, StepPositionInformation_getValue(spi1));
TEST_ASSERT_TRUE(StepPositionInformation_isTransient(spi1));
TEST_ASSERT_EQUAL_INT(63, StepPositionInformation_getValue(spi2));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi2));
TEST_ASSERT_EQUAL_INT(62, StepPositionInformation_getValue(spi3));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi3));
TEST_ASSERT_EQUAL_INT(61, StepPositionInformation_getValue(spi4));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi4));
TEST_ASSERT_EQUAL_INT(-61, StepPositionInformation_getValue(spi5));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi5));
TEST_ASSERT_EQUAL_INT(-62, StepPositionInformation_getValue(spi6));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi6));
TEST_ASSERT_EQUAL_INT(-63, StepPositionInformation_getValue(spi7));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi7));
TEST_ASSERT_EQUAL_INT(0, StepPositionInformation_getValue(spi8));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi8));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, StepPositionInformation_getQuality(spi1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, StepPositionInformation_getQuality(spi2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, StepPositionInformation_getQuality(spi3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID, StepPositionInformation_getQuality(spi4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, StepPositionInformation_getQuality(spi5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, StepPositionInformation_getQuality(spi6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, StepPositionInformation_getQuality(spi7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, StepPositionInformation_getQuality(spi8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi8);
StepPositionInformation_destroy(spi1);
StepPositionInformation_destroy(spi2);
StepPositionInformation_destroy(spi3);
StepPositionInformation_destroy(spi4);
StepPositionInformation_destroy(spi5);
StepPositionInformation_destroy(spi6);
StepPositionInformation_destroy(spi7);
StepPositionInformation_destroy(spi8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(46, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
StepPositionInformation spi1_dec = (StepPositionInformation)CS101_ASDU_getElement(asdu2, 0);
StepPositionInformation spi2_dec = (StepPositionInformation)CS101_ASDU_getElement(asdu2, 1);
StepPositionInformation spi3_dec = (StepPositionInformation)CS101_ASDU_getElement(asdu2, 2);
StepPositionInformation spi4_dec = (StepPositionInformation)CS101_ASDU_getElement(asdu2, 3);
StepPositionInformation spi5_dec = (StepPositionInformation)CS101_ASDU_getElement(asdu2, 4);
StepPositionInformation spi6_dec = (StepPositionInformation)CS101_ASDU_getElement(asdu2, 5);
StepPositionInformation spi7_dec = (StepPositionInformation)CS101_ASDU_getElement(asdu2, 6);
StepPositionInformation spi8_dec = (StepPositionInformation)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spi1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)spi2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)spi3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)spi4_dec));
TEST_ASSERT_EQUAL_INT(105, InformationObject_getObjectAddress((InformationObject)spi5_dec));
TEST_ASSERT_EQUAL_INT(106, InformationObject_getObjectAddress((InformationObject)spi6_dec));
TEST_ASSERT_EQUAL_INT(107, InformationObject_getObjectAddress((InformationObject)spi7_dec));
TEST_ASSERT_EQUAL_INT(108, InformationObject_getObjectAddress((InformationObject)spi8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, StepPositionInformation_getQuality(spi1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, StepPositionInformation_getQuality(spi2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, StepPositionInformation_getQuality(spi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID, StepPositionInformation_getQuality(spi4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, StepPositionInformation_getQuality(spi5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, StepPositionInformation_getQuality(spi6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, StepPositionInformation_getQuality(spi7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, StepPositionInformation_getQuality(spi8_dec));
TEST_ASSERT_EQUAL_INT(0, StepPositionInformation_getValue(spi1_dec));
TEST_ASSERT_TRUE(StepPositionInformation_isTransient(spi1_dec));
TEST_ASSERT_EQUAL_INT(63, StepPositionInformation_getValue(spi2_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi2_dec));
TEST_ASSERT_EQUAL_INT(62, StepPositionInformation_getValue(spi3_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi3_dec));
TEST_ASSERT_EQUAL_INT(61, StepPositionInformation_getValue(spi4_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi4_dec));
TEST_ASSERT_EQUAL_INT(-61, StepPositionInformation_getValue(spi5_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi5_dec));
TEST_ASSERT_EQUAL_INT(-62, StepPositionInformation_getValue(spi6_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi6_dec));
TEST_ASSERT_EQUAL_INT(-63, StepPositionInformation_getValue(spi7_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi7_dec));
TEST_ASSERT_EQUAL_INT(-0, StepPositionInformation_getValue(spi8_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient(spi8_dec));
StepPositionInformation_destroy(spi1_dec);
StepPositionInformation_destroy(spi2_dec);
StepPositionInformation_destroy(spi3_dec);
StepPositionInformation_destroy(spi4_dec);
StepPositionInformation_destroy(spi5_dec);
StepPositionInformation_destroy(spi6_dec);
StepPositionInformation_destroy(spi7_dec);
StepPositionInformation_destroy(spi8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_StepPositionWithCP24Time2a(void)
{
StepPositionWithCP24Time2a spi1;
StepPositionWithCP24Time2a spi2;
StepPositionWithCP24Time2a spi3;
StepPositionWithCP24Time2a spi4;
StepPositionWithCP24Time2a spi5;
StepPositionWithCP24Time2a spi6;
StepPositionWithCP24Time2a spi7;
StepPositionWithCP24Time2a spi8;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
uint64_t time4 = time3 + 1000;
uint64_t time5 = time4 + 1000;
uint64_t time6 = time5 + 1000;
uint64_t time7 = time6 + 1000;
uint64_t time8 = time7 + 1000;
struct sCP24Time2a cpTime1;
struct sCP24Time2a cpTime2;
struct sCP24Time2a cpTime3;
struct sCP24Time2a cpTime4;
struct sCP24Time2a cpTime5;
struct sCP24Time2a cpTime6;
struct sCP24Time2a cpTime7;
struct sCP24Time2a cpTime8;
bzero(&cpTime1, sizeof(struct sCP24Time2a));
bzero(&cpTime2, sizeof(struct sCP24Time2a));
bzero(&cpTime3, sizeof(struct sCP24Time2a));
bzero(&cpTime4, sizeof(struct sCP24Time2a));
bzero(&cpTime5, sizeof(struct sCP24Time2a));
bzero(&cpTime6, sizeof(struct sCP24Time2a));
bzero(&cpTime7, sizeof(struct sCP24Time2a));
bzero(&cpTime8, sizeof(struct sCP24Time2a));
CP24Time2a_setMinute(&cpTime1, 12);
CP24Time2a_setMillisecond(&cpTime1, 24123);
CP24Time2a_setMinute(&cpTime2, 54);
CP24Time2a_setMillisecond(&cpTime2, 12345);
CP24Time2a_setMinute(&cpTime3, 00);
CP24Time2a_setMillisecond(&cpTime3, 00001);
CP24Time2a_setMinute(&cpTime4, 12);
CP24Time2a_setMillisecond(&cpTime4, 24123);
CP24Time2a_setMinute(&cpTime5, 12);
CP24Time2a_setMillisecond(&cpTime5, 24123);
CP24Time2a_setMinute(&cpTime6, 12);
CP24Time2a_setMillisecond(&cpTime6, 24123);
CP24Time2a_setMinute(&cpTime7, 12);
CP24Time2a_setMillisecond(&cpTime7, 24123);
CP24Time2a_setMinute(&cpTime8, 12);
CP24Time2a_setMillisecond(&cpTime8, 24123);
spi1 = StepPositionWithCP24Time2a_create(NULL, 101, 0, true, IEC60870_QUALITY_GOOD, &cpTime1);
spi2 = StepPositionWithCP24Time2a_create(NULL, 102, 63, false, IEC60870_QUALITY_OVERFLOW, &cpTime2);
spi3 = StepPositionWithCP24Time2a_create(NULL, 103, 62, false, IEC60870_QUALITY_RESERVED, &cpTime3);
spi4 = StepPositionWithCP24Time2a_create(NULL, 104, 61, false, IEC60870_QUALITY_ELAPSED_TIME_INVALID, &cpTime4);
spi5 = StepPositionWithCP24Time2a_create(NULL, 105, -61, false, IEC60870_QUALITY_BLOCKED, &cpTime5);
spi6 = StepPositionWithCP24Time2a_create(NULL, 106, -62, false, IEC60870_QUALITY_SUBSTITUTED, &cpTime6);
spi7 = StepPositionWithCP24Time2a_create(NULL, 107, -63, false, IEC60870_QUALITY_NON_TOPICAL, &cpTime7);
spi8 = StepPositionWithCP24Time2a_create(NULL, 108, 0, false, IEC60870_QUALITY_INVALID, &cpTime8);
TEST_ASSERT_EQUAL_INT(0, StepPositionInformation_getValue((StepPositionInformation)spi1));
TEST_ASSERT_TRUE(StepPositionInformation_isTransient((StepPositionInformation)spi1));
TEST_ASSERT_EQUAL_INT(63, StepPositionInformation_getValue((StepPositionInformation)spi2));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi2));
TEST_ASSERT_EQUAL_INT(62, StepPositionInformation_getValue((StepPositionInformation)spi3));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi3));
TEST_ASSERT_EQUAL_INT(61, StepPositionInformation_getValue((StepPositionInformation)spi4));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi4));
TEST_ASSERT_EQUAL_INT(-61, StepPositionInformation_getValue((StepPositionInformation)spi5));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi5));
TEST_ASSERT_EQUAL_INT(-62, StepPositionInformation_getValue((StepPositionInformation)spi6));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi6));
TEST_ASSERT_EQUAL_INT(-63, StepPositionInformation_getValue((StepPositionInformation)spi7));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi7));
TEST_ASSERT_EQUAL_INT(0, StepPositionInformation_getValue((StepPositionInformation)spi8));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi8));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, StepPositionInformation_getQuality((StepPositionInformation)spi1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW,
StepPositionInformation_getQuality((StepPositionInformation)spi2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED,
StepPositionInformation_getQuality((StepPositionInformation)spi3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
StepPositionInformation_getQuality((StepPositionInformation)spi4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
StepPositionInformation_getQuality((StepPositionInformation)spi5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
StepPositionInformation_getQuality((StepPositionInformation)spi6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
StepPositionInformation_getQuality((StepPositionInformation)spi7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
StepPositionInformation_getQuality((StepPositionInformation)spi8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi8);
StepPositionWithCP24Time2a_destroy(spi1);
StepPositionWithCP24Time2a_destroy(spi2);
StepPositionWithCP24Time2a_destroy(spi3);
StepPositionWithCP24Time2a_destroy(spi4);
StepPositionWithCP24Time2a_destroy(spi5);
StepPositionWithCP24Time2a_destroy(spi6);
StepPositionWithCP24Time2a_destroy(spi7);
StepPositionWithCP24Time2a_destroy(spi8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(70, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
StepPositionWithCP24Time2a spi1_dec = (StepPositionWithCP24Time2a)CS101_ASDU_getElement(asdu2, 0);
StepPositionWithCP24Time2a spi2_dec = (StepPositionWithCP24Time2a)CS101_ASDU_getElement(asdu2, 1);
StepPositionWithCP24Time2a spi3_dec = (StepPositionWithCP24Time2a)CS101_ASDU_getElement(asdu2, 2);
StepPositionWithCP24Time2a spi4_dec = (StepPositionWithCP24Time2a)CS101_ASDU_getElement(asdu2, 3);
StepPositionWithCP24Time2a spi5_dec = (StepPositionWithCP24Time2a)CS101_ASDU_getElement(asdu2, 4);
StepPositionWithCP24Time2a spi6_dec = (StepPositionWithCP24Time2a)CS101_ASDU_getElement(asdu2, 5);
StepPositionWithCP24Time2a spi7_dec = (StepPositionWithCP24Time2a)CS101_ASDU_getElement(asdu2, 6);
StepPositionWithCP24Time2a spi8_dec = (StepPositionWithCP24Time2a)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spi1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)spi2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)spi3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)spi4_dec));
TEST_ASSERT_EQUAL_INT(105, InformationObject_getObjectAddress((InformationObject)spi5_dec));
TEST_ASSERT_EQUAL_INT(106, InformationObject_getObjectAddress((InformationObject)spi6_dec));
TEST_ASSERT_EQUAL_INT(107, InformationObject_getObjectAddress((InformationObject)spi7_dec));
TEST_ASSERT_EQUAL_INT(108, InformationObject_getObjectAddress((InformationObject)spi8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD,
StepPositionInformation_getQuality((StepPositionInformation)spi1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW,
StepPositionInformation_getQuality((StepPositionInformation)spi2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED,
StepPositionInformation_getQuality((StepPositionInformation)spi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
StepPositionInformation_getQuality((StepPositionInformation)spi4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
StepPositionInformation_getQuality((StepPositionInformation)spi5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
StepPositionInformation_getQuality((StepPositionInformation)spi6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
StepPositionInformation_getQuality((StepPositionInformation)spi7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
StepPositionInformation_getQuality((StepPositionInformation)spi8_dec));
TEST_ASSERT_EQUAL_INT(0, StepPositionInformation_getValue((StepPositionInformation)spi1_dec));
TEST_ASSERT_TRUE(StepPositionInformation_isTransient((StepPositionInformation)spi1_dec));
TEST_ASSERT_EQUAL_INT(63, StepPositionInformation_getValue((StepPositionInformation)spi2_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi2_dec));
TEST_ASSERT_EQUAL_INT(62, StepPositionInformation_getValue((StepPositionInformation)spi3_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi3_dec));
TEST_ASSERT_EQUAL_INT(61, StepPositionInformation_getValue((StepPositionInformation)spi4_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi4_dec));
TEST_ASSERT_EQUAL_INT(-61, StepPositionInformation_getValue((StepPositionInformation)spi5_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi5_dec));
TEST_ASSERT_EQUAL_INT(-62, StepPositionInformation_getValue((StepPositionInformation)spi6_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi6_dec));
TEST_ASSERT_EQUAL_INT(-63, StepPositionInformation_getValue((StepPositionInformation)spi7_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi7_dec));
TEST_ASSERT_EQUAL_INT(-0, StepPositionInformation_getValue((StepPositionInformation)spi8_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi8_dec));
CP24Time2a time1_dec = StepPositionWithCP24Time2a_getTimestamp(spi1_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time1_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time1_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time1_dec));
CP24Time2a time2_dec = StepPositionWithCP24Time2a_getTimestamp(spi2_dec);
TEST_ASSERT_EQUAL_INT(54, CP24Time2a_getMinute(time2_dec));
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getSecond(time2_dec));
TEST_ASSERT_EQUAL_INT(345, CP24Time2a_getMillisecond(time2_dec));
CP24Time2a time3_dec = StepPositionWithCP24Time2a_getTimestamp(spi3_dec);
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getMinute(time3_dec));
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getSecond(time3_dec));
TEST_ASSERT_EQUAL_INT(1, CP24Time2a_getMillisecond(time3_dec));
CP24Time2a time4_dec = StepPositionWithCP24Time2a_getTimestamp(spi4_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time4_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time4_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time4_dec));
CP24Time2a time5_dec = StepPositionWithCP24Time2a_getTimestamp(spi5_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time5_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time5_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time5_dec));
CP24Time2a time6_dec = StepPositionWithCP24Time2a_getTimestamp(spi6_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time6_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time6_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time6_dec));
CP24Time2a time7_dec = StepPositionWithCP24Time2a_getTimestamp(spi7_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time7_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time7_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time7_dec));
CP24Time2a time8_dec = StepPositionWithCP24Time2a_getTimestamp(spi8_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time8_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time8_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time8_dec));
StepPositionWithCP24Time2a_destroy(spi1_dec);
StepPositionWithCP24Time2a_destroy(spi2_dec);
StepPositionWithCP24Time2a_destroy(spi3_dec);
StepPositionWithCP24Time2a_destroy(spi4_dec);
StepPositionWithCP24Time2a_destroy(spi5_dec);
StepPositionWithCP24Time2a_destroy(spi6_dec);
StepPositionWithCP24Time2a_destroy(spi7_dec);
StepPositionWithCP24Time2a_destroy(spi8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_StepPositionWithCP56Time2a(void)
{
StepPositionWithCP56Time2a spi1;
StepPositionWithCP56Time2a spi2;
StepPositionWithCP56Time2a spi3;
StepPositionWithCP56Time2a spi4;
StepPositionWithCP56Time2a spi5;
StepPositionWithCP56Time2a spi6;
StepPositionWithCP56Time2a spi7;
StepPositionWithCP56Time2a spi8;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
uint64_t time4 = time3 + 1000;
uint64_t time5 = time4 + 1000;
uint64_t time6 = time5 + 1000;
uint64_t time7 = time6 + 1000;
uint64_t time8 = time7 + 1000;
struct sCP56Time2a cpTime1;
struct sCP56Time2a cpTime2;
struct sCP56Time2a cpTime3;
struct sCP56Time2a cpTime4;
struct sCP56Time2a cpTime5;
struct sCP56Time2a cpTime6;
struct sCP56Time2a cpTime7;
struct sCP56Time2a cpTime8;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
CP56Time2a_createFromMsTimestamp(&cpTime2, time2);
CP56Time2a_createFromMsTimestamp(&cpTime3, time3);
CP56Time2a_createFromMsTimestamp(&cpTime4, time4);
CP56Time2a_createFromMsTimestamp(&cpTime5, time5);
CP56Time2a_createFromMsTimestamp(&cpTime6, time6);
CP56Time2a_createFromMsTimestamp(&cpTime7, time7);
CP56Time2a_createFromMsTimestamp(&cpTime8, time8);
spi1 = StepPositionWithCP56Time2a_create(NULL, 101, 0, true, IEC60870_QUALITY_GOOD, &cpTime1);
spi2 = StepPositionWithCP56Time2a_create(NULL, 102, 63, false, IEC60870_QUALITY_OVERFLOW, &cpTime2);
spi3 = StepPositionWithCP56Time2a_create(NULL, 103, 62, false, IEC60870_QUALITY_RESERVED, &cpTime3);
spi4 = StepPositionWithCP56Time2a_create(NULL, 104, 61, false, IEC60870_QUALITY_ELAPSED_TIME_INVALID, &cpTime4);
spi5 = StepPositionWithCP56Time2a_create(NULL, 105, -61, false, IEC60870_QUALITY_BLOCKED, &cpTime5);
spi6 = StepPositionWithCP56Time2a_create(NULL, 106, -62, false, IEC60870_QUALITY_SUBSTITUTED, &cpTime6);
spi7 = StepPositionWithCP56Time2a_create(NULL, 107, -63, false, IEC60870_QUALITY_NON_TOPICAL, &cpTime7);
spi8 = StepPositionWithCP56Time2a_create(NULL, 108, 0, false, IEC60870_QUALITY_INVALID, &cpTime8);
TEST_ASSERT_EQUAL_INT(0, StepPositionInformation_getValue((StepPositionInformation)spi1));
TEST_ASSERT_TRUE(StepPositionInformation_isTransient((StepPositionInformation)spi1));
TEST_ASSERT_EQUAL_INT(63, StepPositionInformation_getValue((StepPositionInformation)spi2));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi2));
TEST_ASSERT_EQUAL_INT(62, StepPositionInformation_getValue((StepPositionInformation)spi3));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi3));
TEST_ASSERT_EQUAL_INT(61, StepPositionInformation_getValue((StepPositionInformation)spi4));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi4));
TEST_ASSERT_EQUAL_INT(-61, StepPositionInformation_getValue((StepPositionInformation)spi5));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi5));
TEST_ASSERT_EQUAL_INT(-62, StepPositionInformation_getValue((StepPositionInformation)spi6));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi6));
TEST_ASSERT_EQUAL_INT(-63, StepPositionInformation_getValue((StepPositionInformation)spi7));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi7));
TEST_ASSERT_EQUAL_INT(0, StepPositionInformation_getValue((StepPositionInformation)spi8));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi8));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, StepPositionInformation_getQuality((StepPositionInformation)spi1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW,
StepPositionInformation_getQuality((StepPositionInformation)spi2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED,
StepPositionInformation_getQuality((StepPositionInformation)spi3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
StepPositionInformation_getQuality((StepPositionInformation)spi4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
StepPositionInformation_getQuality((StepPositionInformation)spi5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
StepPositionInformation_getQuality((StepPositionInformation)spi6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
StepPositionInformation_getQuality((StepPositionInformation)spi7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
StepPositionInformation_getQuality((StepPositionInformation)spi8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi8);
StepPositionWithCP56Time2a_destroy(spi1);
StepPositionWithCP56Time2a_destroy(spi2);
StepPositionWithCP56Time2a_destroy(spi3);
StepPositionWithCP56Time2a_destroy(spi4);
StepPositionWithCP56Time2a_destroy(spi5);
StepPositionWithCP56Time2a_destroy(spi6);
StepPositionWithCP56Time2a_destroy(spi7);
StepPositionWithCP56Time2a_destroy(spi8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(102, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
StepPositionWithCP56Time2a spi1_dec = (StepPositionWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
StepPositionWithCP56Time2a spi2_dec = (StepPositionWithCP56Time2a)CS101_ASDU_getElement(asdu2, 1);
StepPositionWithCP56Time2a spi3_dec = (StepPositionWithCP56Time2a)CS101_ASDU_getElement(asdu2, 2);
StepPositionWithCP56Time2a spi4_dec = (StepPositionWithCP56Time2a)CS101_ASDU_getElement(asdu2, 3);
StepPositionWithCP56Time2a spi5_dec = (StepPositionWithCP56Time2a)CS101_ASDU_getElement(asdu2, 4);
StepPositionWithCP56Time2a spi6_dec = (StepPositionWithCP56Time2a)CS101_ASDU_getElement(asdu2, 5);
StepPositionWithCP56Time2a spi7_dec = (StepPositionWithCP56Time2a)CS101_ASDU_getElement(asdu2, 6);
StepPositionWithCP56Time2a spi8_dec = (StepPositionWithCP56Time2a)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spi1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)spi2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)spi3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)spi4_dec));
TEST_ASSERT_EQUAL_INT(105, InformationObject_getObjectAddress((InformationObject)spi5_dec));
TEST_ASSERT_EQUAL_INT(106, InformationObject_getObjectAddress((InformationObject)spi6_dec));
TEST_ASSERT_EQUAL_INT(107, InformationObject_getObjectAddress((InformationObject)spi7_dec));
TEST_ASSERT_EQUAL_INT(108, InformationObject_getObjectAddress((InformationObject)spi8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD,
StepPositionInformation_getQuality((StepPositionInformation)spi1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW,
StepPositionInformation_getQuality((StepPositionInformation)spi2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED,
StepPositionInformation_getQuality((StepPositionInformation)spi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
StepPositionInformation_getQuality((StepPositionInformation)spi4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
StepPositionInformation_getQuality((StepPositionInformation)spi5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
StepPositionInformation_getQuality((StepPositionInformation)spi6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
StepPositionInformation_getQuality((StepPositionInformation)spi7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
StepPositionInformation_getQuality((StepPositionInformation)spi8_dec));
TEST_ASSERT_EQUAL_INT(0, StepPositionInformation_getValue((StepPositionInformation)spi1_dec));
TEST_ASSERT_TRUE(StepPositionInformation_isTransient((StepPositionInformation)spi1_dec));
TEST_ASSERT_EQUAL_INT(63, StepPositionInformation_getValue((StepPositionInformation)spi2_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi2_dec));
TEST_ASSERT_EQUAL_INT(62, StepPositionInformation_getValue((StepPositionInformation)spi3_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi3_dec));
TEST_ASSERT_EQUAL_INT(61, StepPositionInformation_getValue((StepPositionInformation)spi4_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi4_dec));
TEST_ASSERT_EQUAL_INT(-61, StepPositionInformation_getValue((StepPositionInformation)spi5_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi5_dec));
TEST_ASSERT_EQUAL_INT(-62, StepPositionInformation_getValue((StepPositionInformation)spi6_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi6_dec));
TEST_ASSERT_EQUAL_INT(-63, StepPositionInformation_getValue((StepPositionInformation)spi7_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi7_dec));
TEST_ASSERT_EQUAL_INT(-0, StepPositionInformation_getValue((StepPositionInformation)spi8_dec));
TEST_ASSERT_FALSE(StepPositionInformation_isTransient((StepPositionInformation)spi8_dec));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(StepPositionWithCP56Time2a_getTimestamp(spi1_dec)));
TEST_ASSERT_EQUAL_UINT64(time2, CP56Time2a_toMsTimestamp(StepPositionWithCP56Time2a_getTimestamp(spi2_dec)));
TEST_ASSERT_EQUAL_UINT64(time3, CP56Time2a_toMsTimestamp(StepPositionWithCP56Time2a_getTimestamp(spi3_dec)));
TEST_ASSERT_EQUAL_UINT64(time4, CP56Time2a_toMsTimestamp(StepPositionWithCP56Time2a_getTimestamp(spi4_dec)));
TEST_ASSERT_EQUAL_UINT64(time5, CP56Time2a_toMsTimestamp(StepPositionWithCP56Time2a_getTimestamp(spi5_dec)));
TEST_ASSERT_EQUAL_UINT64(time6, CP56Time2a_toMsTimestamp(StepPositionWithCP56Time2a_getTimestamp(spi6_dec)));
TEST_ASSERT_EQUAL_UINT64(time7, CP56Time2a_toMsTimestamp(StepPositionWithCP56Time2a_getTimestamp(spi7_dec)));
TEST_ASSERT_EQUAL_UINT64(time8, CP56Time2a_toMsTimestamp(StepPositionWithCP56Time2a_getTimestamp(spi8_dec)));
StepPositionWithCP56Time2a_destroy(spi1_dec);
StepPositionWithCP56Time2a_destroy(spi2_dec);
StepPositionWithCP56Time2a_destroy(spi3_dec);
StepPositionWithCP56Time2a_destroy(spi4_dec);
StepPositionWithCP56Time2a_destroy(spi5_dec);
StepPositionWithCP56Time2a_destroy(spi6_dec);
StepPositionWithCP56Time2a_destroy(spi7_dec);
StepPositionWithCP56Time2a_destroy(spi8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_addMaxNumberOfIOsToASDU(void)
{
struct sCS101_AppLayerParameters salParameters;
salParameters.maxSizeOfASDU = 100;
salParameters.originatorAddress = 0;
salParameters.sizeOfCA = 2;
salParameters.sizeOfCOT = 2;
salParameters.sizeOfIOA = 3;
salParameters.sizeOfTypeId = 1;
salParameters.sizeOfVSQ = 1;
CS101_ASDU asdu = CS101_ASDU_create(&salParameters, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
int ioa = 100;
bool added = false;
do
{
InformationObject io = (InformationObject)SinglePointInformation_create(NULL, ioa, true, IEC60870_QUALITY_GOOD);
added = CS101_ASDU_addInformationObject(asdu, io);
InformationObject_destroy(io);
ioa++;
} while (added);
CS101_ASDU_destroy(asdu);
TEST_ASSERT_EQUAL_INT(124, ioa);
}
void
test_SingleEventType(void)
{
tSingleEvent singleEvent = 0;
EventState eventState = SingleEvent_getEventState(&singleEvent);
TEST_ASSERT_EQUAL_INT(IEC60870_EVENTSTATE_INDETERMINATE_0, eventState);
QualityDescriptorP qdp = SingleEvent_getQDP(&singleEvent);
TEST_ASSERT_EQUAL_INT(0, qdp);
}
void
test_EventOfProtectionEquipmentWithTime(void)
{
#ifndef _WIN32
tSingleEvent singleEvent = 0;
struct sCP16Time2a elapsedTime;
struct sCP56Time2a timestamp;
EventOfProtectionEquipmentWithCP56Time2a e =
EventOfProtectionEquipmentWithCP56Time2a_create(NULL, 1, &singleEvent, &elapsedTime, &timestamp);
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)e);
CS101_ASDU_addInformationObject(asdu, (InformationObject)e);
CS101_ASDU_encode(asdu, f);
InformationObject_destroy((InformationObject)e);
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
InformationObject io = CS101_ASDU_getElement(asdu2, 1);
TEST_ASSERT_NOT_NULL(io);
EventOfProtectionEquipmentWithCP56Time2a e2 = (EventOfProtectionEquipmentWithCP56Time2a)io;
SingleEvent se = EventOfProtectionEquipmentWithCP56Time2a_getEvent(e2);
QualityDescriptorP qdp = SingleEvent_getQDP(se);
InformationObject_destroy(io);
CS101_ASDU_destroy(asdu2);
TEST_ASSERT_EQUAL_INT(0, qdp);
#endif
}
struct test_CS104SlaveConnectionIsRedundancyGroup_Info
{
bool running;
CS104_Slave slave;
};
static void*
test_CS104SlaveConnectionIsRedundancyGroup_enqueueThreadFunction(void* parameter)
{
struct test_CS104SlaveConnectionIsRedundancyGroup_Info* info =
(struct test_CS104SlaveConnectionIsRedundancyGroup_Info*)parameter;
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(info->slave);
int16_t scaledValue = 0;
while (info->running)
{
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_PERIODIC, 0, 1, false, false);
InformationObject io =
(InformationObject)MeasuredValueScaled_create(NULL, 110, scaledValue, IEC60870_QUALITY_GOOD);
scaledValue++;
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(info->slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
Thread_sleep(10);
}
return NULL;
}
void
test_CS104SlaveConnectionIsRedundancyGroup()
{
CS104_Slave slave = CS104_Slave_create(100, 100);
CS104_Slave_setServerMode(slave, CS104_MODE_CONNECTION_IS_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
struct test_CS104SlaveConnectionIsRedundancyGroup_Info info;
info.running = true;
info.slave = slave;
Thread enqueueThread =
Thread_create(test_CS104SlaveConnectionIsRedundancyGroup_enqueueThreadFunction, &info, false);
Thread_start(enqueueThread);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
int i;
for (i = 0; i < 50; i++)
{
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
Thread_sleep(10);
CS104_Connection_close(con);
}
info.running = false;
Thread_destroy(enqueueThread);
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
void
test_CS104SlaveSingleRedundancyGroup()
{
CS104_Slave slave = CS104_Slave_create(100, 100);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
struct test_CS104SlaveConnectionIsRedundancyGroup_Info info;
info.running = true;
info.slave = slave;
Thread enqueueThread =
Thread_create(test_CS104SlaveConnectionIsRedundancyGroup_enqueueThreadFunction, &info, false);
Thread_start(enqueueThread);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
int i;
for (i = 0; i < 50; i++)
{
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
CS104_Connection_close(con);
Thread_sleep(10);
}
info.running = false;
Thread_destroy(enqueueThread);
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
static void
test_CS104SlaveSingleRedundancyGroupMultipleConnectionsEventHandler(void* parameter, IMasterConnection connection,
CS104_PeerConnectionEvent event)
{
char ipAddrBuf[100];
ipAddrBuf[0] = 0;
IMasterConnection_getPeerAddress(connection, ipAddrBuf, 100);
}
void
test_CS104SlaveSingleRedundancyGroupMultipleConnections()
{
CS104_Slave slave = CS104_Slave_create(100, 100);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Slave_setMaxOpenConnections(slave, 20);
CS104_Slave_setConnectionEventHandler(slave, test_CS104SlaveSingleRedundancyGroupMultipleConnectionsEventHandler,
NULL);
struct test_CS104SlaveConnectionIsRedundancyGroup_Info info;
info.running = true;
info.slave = slave;
CS104_Connection cons[3];
int conState[3]; /* 0 = idle, 1 = connected, 2 = START_DT sent */
cons[0] = CS104_Connection_create("127.0.0.1", 20004);
cons[1] = CS104_Connection_create("127.0.0.1", 20004);
cons[2] = CS104_Connection_create("127.0.0.1", 20004);
conState[0] = 0;
conState[1] = 0;
conState[2] = 0;
Thread enqueueThread =
Thread_create(test_CS104SlaveConnectionIsRedundancyGroup_enqueueThreadFunction, &info, false);
Thread_start(enqueueThread);
int i;
for (i = 0; i < 200; i++)
{
// printf("round %i\n", i);
int con = rand() % 3;
if (conState[con] == 0)
{
bool result = CS104_Connection_connect(cons[con]);
TEST_ASSERT_TRUE(result);
conState[con] = 1;
}
else if (conState[con] == 1)
{
CS104_Connection_sendStartDT(cons[con]);
conState[con] = 2;
}
else if (conState[con] == 2)
{
CS104_Connection_close(cons[con]);
conState[con] = 0;
}
Thread_sleep(50);
}
CS104_Connection_destroy(cons[0]);
CS104_Connection_destroy(cons[1]);
CS104_Connection_destroy(cons[2]);
info.running = false;
Thread_destroy(enqueueThread);
CS104_Slave_destroy(slave);
}
struct stest_CS104SlaveEventQueue1
{
int asduHandlerCalled;
int spontCount;
int16_t lastScaledValue;
};
static bool
test_CS104SlaveEventQueue1_asduReceivedHandler(void* parameter, int address, CS101_ASDU asdu)
{
struct stest_CS104SlaveEventQueue1* info = (struct stest_CS104SlaveEventQueue1*)parameter;
info->asduHandlerCalled++;
if (CS101_ASDU_getCOT(asdu) == CS101_COT_SPONTANEOUS)
{
info->spontCount++;
if (CS101_ASDU_getTypeID(asdu) == M_ME_NB_1)
{
static uint8_t ioBuf[250];
MeasuredValueScaled mv = (MeasuredValueScaled)CS101_ASDU_getElementEx(asdu, (InformationObject)ioBuf, 0);
info->lastScaledValue = MeasuredValueScaled_getValue(mv);
}
}
return true;
}
struct sTestMessageQueueEntryInfo
{
uint64_t entryTimestamp;
unsigned int entryState : 2;
unsigned int size : 8;
};
void
test_CS104SlaveEventQueue1()
{
CS104_Slave slave = CS104_Slave_create(10, 10);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
struct stest_CS104SlaveEventQueue1 info;
info.asduHandlerCalled = 0;
info.spontCount = 0;
info.lastScaledValue = 0;
int16_t scaledValue = 0;
for (int i = 0; i < 15; i++)
{
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io =
(InformationObject)MeasuredValueScaled_create(NULL, 110, scaledValue, IEC60870_QUALITY_GOOD);
scaledValue++;
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
}
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
CS104_Connection_setASDUReceivedHandler(con, test_CS104SlaveEventQueue1_asduReceivedHandler, &info);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
Thread_sleep(500);
CS104_Connection_sendStopDT(con);
CS104_Connection_close(con);
TEST_ASSERT_EQUAL_INT(14, info.lastScaledValue);
info.asduHandlerCalled = 0;
info.spontCount = 0;
result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
for (int i = 0; i < 15; i++)
{
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io =
(InformationObject)MeasuredValueScaled_create(NULL, 110, scaledValue, IEC60870_QUALITY_GOOD);
scaledValue++;
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
Thread_sleep(10);
}
Thread_sleep(500);
CS104_Connection_close(con);
TEST_ASSERT_EQUAL_INT(15, info.asduHandlerCalled);
TEST_ASSERT_EQUAL_INT(15, info.spontCount);
TEST_ASSERT_EQUAL_INT(29, info.lastScaledValue);
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
void
test_CS104SlaveEventQueueOverflow()
{
CS104_Slave slave = CS104_Slave_create(10, 10);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
struct stest_CS104SlaveEventQueue1 info;
info.asduHandlerCalled = 0;
info.spontCount = 0;
info.lastScaledValue = 0;
int16_t scaledValue = 0;
for (int i = 0; i < 300; i++)
{
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io =
(InformationObject)MeasuredValueScaled_create(NULL, 110, scaledValue, IEC60870_QUALITY_GOOD);
scaledValue++;
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
}
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
CS104_Connection_setASDUReceivedHandler(con, test_CS104SlaveEventQueue1_asduReceivedHandler, &info);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
Thread_sleep(1500);
CS104_Connection_close(con);
int asduSize = 12;
int entrySize = sizeof(struct sTestMessageQueueEntryInfo) + asduSize;
int msgQueueCapacity = ((sizeof(struct sTestMessageQueueEntryInfo) + 256) * 10) / entrySize;
TEST_ASSERT_EQUAL_INT(299, info.lastScaledValue);
TEST_ASSERT_EQUAL_INT(msgQueueCapacity, info.asduHandlerCalled);
result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
for (int i = 0; i < 150; i++)
{
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io =
(InformationObject)MeasuredValueScaled_create(NULL, 110, scaledValue, IEC60870_QUALITY_GOOD);
scaledValue++;
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
Thread_sleep(10);
}
Thread_sleep(500);
CS104_Connection_close(con);
TEST_ASSERT_EQUAL_INT(msgQueueCapacity + 150, info.asduHandlerCalled);
TEST_ASSERT_EQUAL_INT(msgQueueCapacity + 150, info.spontCount);
TEST_ASSERT_EQUAL_INT(449, info.lastScaledValue);
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
void
test_CS104SlaveEventQueueOverflow2()
{
CS104_Slave slave = CS104_Slave_create(10, 10);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
struct stest_CS104SlaveEventQueue1 info;
info.asduHandlerCalled = 0;
info.spontCount = 0;
info.lastScaledValue = 0;
int16_t scaledValue = 0;
for (int i = 0; i < 300; i++)
{
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io =
(InformationObject)MeasuredValueScaled_create(NULL, 110, scaledValue, IEC60870_QUALITY_GOOD);
scaledValue++;
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
}
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
CS104_Connection_setASDUReceivedHandler(con, test_CS104SlaveEventQueue1_asduReceivedHandler, &info);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
Thread_sleep(500);
CS104_Connection_close(con);
int asduSize = 12;
int entrySize = sizeof(struct sTestMessageQueueEntryInfo) + asduSize;
int msgQueueCapacity = ((sizeof(struct sTestMessageQueueEntryInfo) + 256) * 10) / entrySize;
TEST_ASSERT_EQUAL_INT(299, info.lastScaledValue);
TEST_ASSERT_EQUAL_INT(msgQueueCapacity, info.asduHandlerCalled);
result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
int typeNo = 0;
for (int i = 0; i < 20000; i++)
{
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io;
if (typeNo == 0)
{
io = (InformationObject)MeasuredValueScaled_create(NULL, 110, scaledValue, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(newAsdu, io);
}
else if (typeNo == 1)
{
struct sCP56Time2a cp56;
CP56Time2a_createFromMsTimestamp(&cp56, Hal_getTimeInMs());
io = (InformationObject)MeasuredValueScaledWithCP56Time2a_create(NULL, 111, scaledValue,
IEC60870_QUALITY_GOOD, &cp56);
CS101_ASDU_addInformationObject(newAsdu, io);
}
else if (typeNo == 2)
{
io = (InformationObject)SinglePointInformation_create(NULL, 112, true, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(newAsdu, io);
}
else if (typeNo == 3)
{
io = (InformationObject)SinglePointInformation_create(NULL, 112, true, IEC60870_QUALITY_GOOD);
int j = 1;
while (CS101_ASDU_addInformationObject(newAsdu, io))
{
io = (InformationObject)SinglePointInformation_create((SinglePointInformation)io, 112 + j, true,
IEC60870_QUALITY_GOOD);
j++;
}
}
typeNo++;
if (typeNo == 4)
typeNo = 0;
scaledValue++;
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
// Thread_sleep(10);
}
Thread_sleep(500);
CS104_Connection_close(con);
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
void
test_CS104SlaveEventQueueCheckCapacity()
{
CS104_Slave slave = CS104_Slave_create(2, 2);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
struct stest_CS104SlaveEventQueue1 info;
info.asduHandlerCalled = 0;
info.spontCount = 0;
info.lastScaledValue = 0;
int16_t scaledValue = 0;
/* Fill queue with small messages */
int asduSize = 6 + 3 + 1;
int entrySize = sizeof(struct sTestMessageQueueEntryInfo) + asduSize;
int msgQueueCapacity = ((sizeof(struct sTestMessageQueueEntryInfo) + 256) * 2) / entrySize;
for (int i = 0; i < 299; i++)
{
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io = (InformationObject)SinglePointInformation_create(NULL, 101, true, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
if (i >= msgQueueCapacity)
TEST_ASSERT_EQUAL_INT(msgQueueCapacity, CS104_Slave_getNumberOfQueueEntries(slave, NULL));
else
TEST_ASSERT_EQUAL_INT(i + 1, CS104_Slave_getNumberOfQueueEntries(slave, NULL));
CS101_ASDU_destroy(newAsdu);
}
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
CS104_Connection_setASDUReceivedHandler(con, test_CS104SlaveEventQueue1_asduReceivedHandler, &info);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
Thread_sleep(1000);
CS104_Connection_close(con);
TEST_ASSERT_EQUAL_INT(msgQueueCapacity, info.asduHandlerCalled);
/* outstanding I messages that are not confirmed */
TEST_ASSERT_EQUAL_INT(0, CS104_Slave_getNumberOfQueueEntries(slave, NULL));
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
void
test_CS104SlaveEventQueueOverflow3()
{
/**
* Trigger code to remove multiple messages at once from the buffer
*/
CS104_Slave slave = CS104_Slave_create(2, 2);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
struct stest_CS104SlaveEventQueue1 info;
info.asduHandlerCalled = 0;
info.spontCount = 0;
info.lastScaledValue = 0;
int16_t scaledValue = 0;
/* Fill queue with small messages */
int asduSize = 6 + 3 + 1;
int entrySize = sizeof(struct sTestMessageQueueEntryInfo) + asduSize;
int msgQueueCapacity = ((sizeof(struct sTestMessageQueueEntryInfo) + 256) * 2) / entrySize;
for (int i = 0; i < 35; i++)
{
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io = (InformationObject)SinglePointInformation_create(NULL, 101, true, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
}
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
CS104_Connection_setASDUReceivedHandler(con, test_CS104SlaveEventQueue1_asduReceivedHandler, &info);
int count1 = CS104_Slave_getNumberOfQueueEntries(slave, NULL);
/* add a single large messages */
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_PERIODIC, 0, 1, false, false);
for (int i = 0; i < 50; i++)
{
SinglePointInformation spi = SinglePointInformation_create(NULL, 110, false, IEC60870_QUALITY_GOOD);
;
CS101_ASDU_addInformationObject(newAsdu, (InformationObject)spi);
InformationObject_destroy((InformationObject)spi);
}
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
int count2 = CS104_Slave_getNumberOfQueueEntries(slave, NULL);
/* check that multiple buffer entries were removed */
TEST_ASSERT_TRUE(count2 + 1 < count1);
info.asduHandlerCalled = 0;
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
Thread_sleep(500);
CS104_Connection_close(con);
TEST_ASSERT_EQUAL_INT(count2, info.asduHandlerCalled);
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
void
test_IpAddressHandling(void)
{
struct sCS104_IPAddress ipAddr1;
CS104_IPAddress_setFromString(&ipAddr1, "192.168.34.25");
TEST_ASSERT_EQUAL_INT(IP_ADDRESS_TYPE_IPV4, ipAddr1.type);
TEST_ASSERT_EQUAL_UINT8(192, ipAddr1.address[0]);
TEST_ASSERT_EQUAL_UINT8(168, ipAddr1.address[1]);
TEST_ASSERT_EQUAL_UINT8(34, ipAddr1.address[2]);
TEST_ASSERT_EQUAL_UINT8(25, ipAddr1.address[3]);
CS104_IPAddress_setFromString(&ipAddr1, "1:22:333:aaaa:b:c:d:e");
TEST_ASSERT_EQUAL_INT(IP_ADDRESS_TYPE_IPV6, ipAddr1.type);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[0]);
TEST_ASSERT_EQUAL_UINT8(0x01, ipAddr1.address[1]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[2]);
TEST_ASSERT_EQUAL_UINT8(0x22, ipAddr1.address[3]);
TEST_ASSERT_EQUAL_UINT8(0x03, ipAddr1.address[4]);
TEST_ASSERT_EQUAL_UINT8(0x33, ipAddr1.address[5]);
TEST_ASSERT_EQUAL_UINT8(0xaa, ipAddr1.address[6]);
TEST_ASSERT_EQUAL_UINT8(0xaa, ipAddr1.address[7]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[8]);
TEST_ASSERT_EQUAL_UINT8(0x0b, ipAddr1.address[9]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[10]);
TEST_ASSERT_EQUAL_UINT8(0x0c, ipAddr1.address[11]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[12]);
TEST_ASSERT_EQUAL_UINT8(0x0d, ipAddr1.address[13]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[14]);
TEST_ASSERT_EQUAL_UINT8(0x0e, ipAddr1.address[15]);
CS104_IPAddress_setFromString(&ipAddr1, "::2001:db8");
TEST_ASSERT_EQUAL_INT(IP_ADDRESS_TYPE_IPV6, ipAddr1.type);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[0]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[1]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[2]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[3]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[4]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[5]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[6]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[7]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[8]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[9]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[10]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[11]);
TEST_ASSERT_EQUAL_UINT8(0x20, ipAddr1.address[12]);
TEST_ASSERT_EQUAL_UINT8(0x01, ipAddr1.address[13]);
TEST_ASSERT_EQUAL_UINT8(0x0d, ipAddr1.address[14]);
TEST_ASSERT_EQUAL_UINT8(0xb8, ipAddr1.address[15]);
CS104_IPAddress_setFromString(&ipAddr1, "fe80::70d2:6cba:a994:2ced");
TEST_ASSERT_EQUAL_INT(IP_ADDRESS_TYPE_IPV6, ipAddr1.type);
TEST_ASSERT_EQUAL_UINT8(0xfe, ipAddr1.address[0]);
TEST_ASSERT_EQUAL_UINT8(0x80, ipAddr1.address[1]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[2]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[3]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[4]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[5]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[6]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[7]);
TEST_ASSERT_EQUAL_UINT8(0x70, ipAddr1.address[8]);
TEST_ASSERT_EQUAL_UINT8(0xd2, ipAddr1.address[9]);
TEST_ASSERT_EQUAL_UINT8(0x6c, ipAddr1.address[10]);
TEST_ASSERT_EQUAL_UINT8(0xba, ipAddr1.address[11]);
TEST_ASSERT_EQUAL_UINT8(0xa9, ipAddr1.address[12]);
TEST_ASSERT_EQUAL_UINT8(0x94, ipAddr1.address[13]);
TEST_ASSERT_EQUAL_UINT8(0x2c, ipAddr1.address[14]);
TEST_ASSERT_EQUAL_UINT8(0xed, ipAddr1.address[15]);
CS104_IPAddress_setFromString(&ipAddr1, "2001:db8:1::ab9:C0A8:102");
TEST_ASSERT_EQUAL_INT(IP_ADDRESS_TYPE_IPV6, ipAddr1.type);
TEST_ASSERT_EQUAL_UINT8(0x20, ipAddr1.address[0]);
TEST_ASSERT_EQUAL_UINT8(0x01, ipAddr1.address[1]);
TEST_ASSERT_EQUAL_UINT8(0x0d, ipAddr1.address[2]);
TEST_ASSERT_EQUAL_UINT8(0xb8, ipAddr1.address[3]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[4]);
TEST_ASSERT_EQUAL_UINT8(0x01, ipAddr1.address[5]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[6]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[7]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[8]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[9]);
TEST_ASSERT_EQUAL_UINT8(0x0a, ipAddr1.address[10]);
TEST_ASSERT_EQUAL_UINT8(0xb9, ipAddr1.address[11]);
TEST_ASSERT_EQUAL_UINT8(0xc0, ipAddr1.address[12]);
TEST_ASSERT_EQUAL_UINT8(0xa8, ipAddr1.address[13]);
TEST_ASSERT_EQUAL_UINT8(0x01, ipAddr1.address[14]);
TEST_ASSERT_EQUAL_UINT8(0x02, ipAddr1.address[15]);
CS104_IPAddress_setFromString(&ipAddr1, "::1");
TEST_ASSERT_EQUAL_INT(IP_ADDRESS_TYPE_IPV6, ipAddr1.type);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[0]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[1]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[2]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[3]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[4]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[5]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[6]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[7]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[8]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[9]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[10]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[11]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[12]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[13]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[14]);
TEST_ASSERT_EQUAL_UINT8(0x01, ipAddr1.address[15]);
CS104_IPAddress_setFromString(&ipAddr1, "::1");
TEST_ASSERT_EQUAL_INT(IP_ADDRESS_TYPE_IPV6, ipAddr1.type);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[0]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[1]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[2]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[3]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[4]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[5]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[6]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[7]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[8]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[9]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[10]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[11]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[12]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[13]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[14]);
TEST_ASSERT_EQUAL_UINT8(0x01, ipAddr1.address[15]);
CS104_IPAddress_setFromString(&ipAddr1, "::");
TEST_ASSERT_EQUAL_INT(IP_ADDRESS_TYPE_IPV6, ipAddr1.type);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[0]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[1]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[2]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[3]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[4]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[5]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[6]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[7]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[8]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[9]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[10]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[11]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[12]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[13]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[14]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[15]);
CS104_IPAddress_setFromString(&ipAddr1, "fe80:2001::");
TEST_ASSERT_EQUAL_INT(IP_ADDRESS_TYPE_IPV6, ipAddr1.type);
TEST_ASSERT_EQUAL_UINT8(0xfe, ipAddr1.address[0]);
TEST_ASSERT_EQUAL_UINT8(0x80, ipAddr1.address[1]);
TEST_ASSERT_EQUAL_UINT8(0x20, ipAddr1.address[2]);
TEST_ASSERT_EQUAL_UINT8(0x01, ipAddr1.address[3]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[4]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[5]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[6]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[7]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[8]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[9]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[10]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[11]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[12]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[13]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[14]);
TEST_ASSERT_EQUAL_UINT8(0x00, ipAddr1.address[15]);
}
void
test_DoublePointInformation(void)
{
DoublePointInformation dpi1;
DoublePointInformation dpi2;
DoublePointInformation dpi3;
dpi1 = DoublePointInformation_create(NULL, 101, IEC60870_DOUBLE_POINT_OFF, IEC60870_QUALITY_INVALID);
dpi2 = DoublePointInformation_create(NULL, 102, IEC60870_DOUBLE_POINT_ON, IEC60870_QUALITY_BLOCKED);
dpi3 = DoublePointInformation_create(NULL, 103, IEC60870_DOUBLE_POINT_INDETERMINATE, IEC60870_QUALITY_GOOD);
TEST_ASSERT_EQUAL_UINT8(IEC60870_DOUBLE_POINT_OFF, DoublePointInformation_getValue(dpi1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_DOUBLE_POINT_ON, DoublePointInformation_getValue(dpi2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_DOUBLE_POINT_INDETERMINATE, DoublePointInformation_getValue(dpi3));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dpi1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dpi2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dpi3);
InformationObject_destroy((InformationObject)dpi1);
InformationObject_destroy((InformationObject)dpi2);
InformationObject_destroy((InformationObject)dpi3);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(18, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(3, CS101_ASDU_getNumberOfElements(asdu2));
DoublePointInformation dpi1_dec = (DoublePointInformation)CS101_ASDU_getElement(asdu2, 0);
DoublePointInformation dpi2_dec = (DoublePointInformation)CS101_ASDU_getElement(asdu2, 1);
DoublePointInformation dpi3_dec = (DoublePointInformation)CS101_ASDU_getElement(asdu2, 2);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)dpi1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)dpi2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)dpi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, DoublePointInformation_getQuality(dpi1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_DOUBLE_POINT_OFF, DoublePointInformation_getValue(dpi1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, DoublePointInformation_getQuality(dpi2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_DOUBLE_POINT_ON, DoublePointInformation_getValue(dpi2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, DoublePointInformation_getQuality(dpi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_DOUBLE_POINT_INDETERMINATE, DoublePointInformation_getValue(dpi3_dec));
InformationObject_destroy((InformationObject)dpi1_dec);
InformationObject_destroy((InformationObject)dpi2_dec);
InformationObject_destroy((InformationObject)dpi3_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SinglePointInformation(void)
{
SinglePointInformation spi1;
SinglePointInformation spi2;
SinglePointInformation spi3;
SinglePointInformation spi4;
spi1 = SinglePointInformation_create(NULL, 101, true, IEC60870_QUALITY_INVALID);
spi2 = SinglePointInformation_create(NULL, 102, false, IEC60870_QUALITY_BLOCKED);
spi3 = SinglePointInformation_create(NULL, 103, true, IEC60870_QUALITY_GOOD);
/* invalid quality bit (overflow) is expected to be ignored */
spi4 = SinglePointInformation_create(NULL, 104, false, IEC60870_QUALITY_OVERFLOW);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, SinglePointInformation_getQuality(spi1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, SinglePointInformation_getQuality(spi2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality(spi3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality(spi4));
TEST_ASSERT_TRUE(SinglePointInformation_getValue(spi1));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi4);
SinglePointInformation_destroy(spi1);
SinglePointInformation_destroy(spi2);
SinglePointInformation_destroy(spi3);
SinglePointInformation_destroy(spi4);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(22, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(4, CS101_ASDU_getNumberOfElements(asdu2));
SinglePointInformation spi1_dec = (SinglePointInformation)CS101_ASDU_getElement(asdu2, 0);
SinglePointInformation spi2_dec = (SinglePointInformation)CS101_ASDU_getElement(asdu2, 1);
SinglePointInformation spi3_dec = (SinglePointInformation)CS101_ASDU_getElement(asdu2, 2);
SinglePointInformation spi4_dec = (SinglePointInformation)CS101_ASDU_getElement(asdu2, 3);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spi1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)spi2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)spi3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)spi4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, SinglePointInformation_getQuality(spi1_dec));
TEST_ASSERT_TRUE(SinglePointInformation_getValue(spi1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, SinglePointInformation_getQuality(spi2_dec));
TEST_ASSERT_FALSE(SinglePointInformation_getValue(spi2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality(spi3_dec));
TEST_ASSERT_TRUE(SinglePointInformation_getValue(spi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality(spi4_dec));
TEST_ASSERT_FALSE(SinglePointInformation_getValue(spi4_dec));
SinglePointInformation_destroy(spi1_dec);
SinglePointInformation_destroy(spi2_dec);
SinglePointInformation_destroy(spi3_dec);
SinglePointInformation_destroy(spi4_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SinglePointInformationSequence(void)
{
SinglePointInformation spi1;
SinglePointInformation spi2;
SinglePointInformation spi3;
SinglePointInformation spi4;
spi1 = SinglePointInformation_create(NULL, 101, true, IEC60870_QUALITY_INVALID);
spi2 = SinglePointInformation_create(NULL, 102, false, IEC60870_QUALITY_BLOCKED);
spi3 = SinglePointInformation_create(NULL, 103, true, IEC60870_QUALITY_GOOD);
/* invalid quality bit (overflow) is expected to be ignored */
spi4 = SinglePointInformation_create(NULL, 104, false, IEC60870_QUALITY_OVERFLOW);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, SinglePointInformation_getQuality(spi1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, SinglePointInformation_getQuality(spi2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality(spi3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality(spi4));
TEST_ASSERT_TRUE(SinglePointInformation_getValue(spi1));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, true, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi4);
SinglePointInformation_destroy(spi1);
SinglePointInformation_destroy(spi2);
SinglePointInformation_destroy(spi3);
SinglePointInformation_destroy(spi4);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(13, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(4, CS101_ASDU_getNumberOfElements(asdu2));
SinglePointInformation spi1_dec = (SinglePointInformation)CS101_ASDU_getElement(asdu2, 0);
SinglePointInformation spi2_dec = (SinglePointInformation)CS101_ASDU_getElement(asdu2, 1);
SinglePointInformation spi3_dec = (SinglePointInformation)CS101_ASDU_getElement(asdu2, 2);
SinglePointInformation spi4_dec = (SinglePointInformation)CS101_ASDU_getElement(asdu2, 3);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spi1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)spi2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)spi3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)spi4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, SinglePointInformation_getQuality(spi1_dec));
TEST_ASSERT_TRUE(SinglePointInformation_getValue(spi1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, SinglePointInformation_getQuality(spi2_dec));
TEST_ASSERT_FALSE(SinglePointInformation_getValue(spi2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality(spi3_dec));
TEST_ASSERT_TRUE(SinglePointInformation_getValue(spi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality(spi4_dec));
TEST_ASSERT_FALSE(SinglePointInformation_getValue(spi4_dec));
SinglePointInformation_destroy(spi1_dec);
SinglePointInformation_destroy(spi2_dec);
SinglePointInformation_destroy(spi3_dec);
SinglePointInformation_destroy(spi4_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_DoublePointWithCP24Time2a(void)
{
DoublePointWithCP24Time2a dpi1;
DoublePointWithCP24Time2a dpi2;
DoublePointWithCP24Time2a dpi3;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
struct sCP24Time2a cpTime1;
struct sCP24Time2a cpTime2;
struct sCP24Time2a cpTime3;
bzero(&cpTime1, sizeof(struct sCP24Time2a));
bzero(&cpTime2, sizeof(struct sCP24Time2a));
bzero(&cpTime3, sizeof(struct sCP24Time2a));
CP24Time2a_setMinute(&cpTime1, 12);
CP24Time2a_setMillisecond(&cpTime1, 24123);
CP24Time2a_setMinute(&cpTime2, 54);
CP24Time2a_setMillisecond(&cpTime2, 12345);
CP24Time2a_setMinute(&cpTime3, 00);
CP24Time2a_setMillisecond(&cpTime3, 00001);
dpi1 = DoublePointWithCP24Time2a_create(NULL, 101, IEC60870_DOUBLE_POINT_OFF, IEC60870_QUALITY_INVALID, &cpTime1);
dpi2 = DoublePointWithCP24Time2a_create(NULL, 102, IEC60870_DOUBLE_POINT_ON, IEC60870_QUALITY_BLOCKED, &cpTime2);
dpi3 = DoublePointWithCP24Time2a_create(NULL, 103, IEC60870_DOUBLE_POINT_INDETERMINATE, IEC60870_QUALITY_GOOD,
&cpTime3);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, DoublePointInformation_getQuality((DoublePointInformation)dpi1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, DoublePointInformation_getQuality((DoublePointInformation)dpi2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, DoublePointInformation_getQuality((DoublePointInformation)dpi3));
TEST_ASSERT_TRUE(DoublePointInformation_getQuality((DoublePointInformation)dpi1));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dpi1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dpi2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dpi3);
InformationObject_destroy((InformationObject)dpi1);
InformationObject_destroy((InformationObject)dpi2);
InformationObject_destroy((InformationObject)dpi3);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(27, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(3, CS101_ASDU_getNumberOfElements(asdu2));
DoublePointWithCP24Time2a dpi1_dec = (DoublePointWithCP24Time2a)CS101_ASDU_getElement(asdu2, 0);
DoublePointWithCP24Time2a dpi2_dec = (DoublePointWithCP24Time2a)CS101_ASDU_getElement(asdu2, 1);
DoublePointWithCP24Time2a dpi3_dec = (DoublePointWithCP24Time2a)CS101_ASDU_getElement(asdu2, 2);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)dpi1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)dpi2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)dpi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
DoublePointInformation_getQuality((DoublePointInformation)dpi1_dec));
TEST_ASSERT_TRUE(DoublePointInformation_getQuality((DoublePointInformation)dpi1_dec));
CP24Time2a time1_dec = DoublePointWithCP24Time2a_getTimestamp(dpi1_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time1_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time1_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
DoublePointInformation_getQuality((DoublePointInformation)dpi2_dec));
TEST_ASSERT_TRUE(DoublePointInformation_getQuality((DoublePointInformation)dpi2_dec));
CP24Time2a time2_dec = DoublePointWithCP24Time2a_getTimestamp(dpi2_dec);
TEST_ASSERT_EQUAL_INT(54, CP24Time2a_getMinute(time2_dec));
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getSecond(time2_dec));
TEST_ASSERT_EQUAL_INT(345, CP24Time2a_getMillisecond(time2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, DoublePointInformation_getQuality((DoublePointInformation)dpi3_dec));
TEST_ASSERT_TRUE(DoublePointInformation_getValue((DoublePointInformation)dpi3_dec));
CP24Time2a time3_dec = DoublePointWithCP24Time2a_getTimestamp(dpi3_dec);
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getMinute(time3_dec));
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getSecond(time3_dec));
TEST_ASSERT_EQUAL_INT(1, CP24Time2a_getMillisecond(time3_dec));
InformationObject_destroy((InformationObject)dpi1_dec);
InformationObject_destroy((InformationObject)dpi2_dec);
InformationObject_destroy((InformationObject)dpi3_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SinglePointWithCP24Time2a(void)
{
SinglePointWithCP24Time2a spi1;
SinglePointWithCP24Time2a spi2;
SinglePointWithCP24Time2a spi3;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
struct sCP24Time2a cpTime1;
struct sCP24Time2a cpTime2;
struct sCP24Time2a cpTime3;
bzero(&cpTime1, sizeof(struct sCP24Time2a));
bzero(&cpTime2, sizeof(struct sCP24Time2a));
bzero(&cpTime3, sizeof(struct sCP24Time2a));
CP24Time2a_setMinute(&cpTime1, 12);
CP24Time2a_setMillisecond(&cpTime1, 24123);
CP24Time2a_setMinute(&cpTime2, 54);
CP24Time2a_setMillisecond(&cpTime2, 12345);
CP24Time2a_setMinute(&cpTime3, 00);
CP24Time2a_setMillisecond(&cpTime3, 00001);
spi1 = SinglePointWithCP24Time2a_create(NULL, 101, true, IEC60870_QUALITY_INVALID, &cpTime1);
spi2 = SinglePointWithCP24Time2a_create(NULL, 102, false, IEC60870_QUALITY_BLOCKED, &cpTime2);
spi3 = SinglePointWithCP24Time2a_create(NULL, 103, true, IEC60870_QUALITY_GOOD, &cpTime3);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, SinglePointInformation_getQuality((SinglePointInformation)spi1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, SinglePointInformation_getQuality((SinglePointInformation)spi2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality((SinglePointInformation)spi3));
TEST_ASSERT_TRUE(SinglePointInformation_getValue((SinglePointInformation)spi1));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi3);
InformationObject_destroy((InformationObject)spi1);
InformationObject_destroy((InformationObject)spi2);
InformationObject_destroy((InformationObject)spi3);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(27, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(3, CS101_ASDU_getNumberOfElements(asdu2));
SinglePointWithCP24Time2a spi1_dec = (SinglePointWithCP24Time2a)CS101_ASDU_getElement(asdu2, 0);
SinglePointWithCP24Time2a spi2_dec = (SinglePointWithCP24Time2a)CS101_ASDU_getElement(asdu2, 1);
SinglePointWithCP24Time2a spi3_dec = (SinglePointWithCP24Time2a)CS101_ASDU_getElement(asdu2, 2);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spi1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)spi2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)spi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
SinglePointInformation_getQuality((SinglePointInformation)spi1_dec));
TEST_ASSERT_TRUE(SinglePointInformation_getValue((SinglePointInformation)spi1_dec));
CP24Time2a time1_dec = SinglePointWithCP24Time2a_getTimestamp(spi1_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time1_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time1_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
SinglePointInformation_getQuality((SinglePointInformation)spi2_dec));
TEST_ASSERT_FALSE(SinglePointInformation_getValue((SinglePointInformation)spi2_dec));
CP24Time2a time2_dec = SinglePointWithCP24Time2a_getTimestamp(spi2_dec);
TEST_ASSERT_EQUAL_INT(54, CP24Time2a_getMinute(time2_dec));
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getSecond(time2_dec));
TEST_ASSERT_EQUAL_INT(345, CP24Time2a_getMillisecond(time2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality((SinglePointInformation)spi3_dec));
TEST_ASSERT_TRUE(SinglePointInformation_getValue((SinglePointInformation)spi3_dec));
CP24Time2a time3_dec = SinglePointWithCP24Time2a_getTimestamp(spi3_dec);
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getMinute(time3_dec));
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getSecond(time3_dec));
TEST_ASSERT_EQUAL_INT(1, CP24Time2a_getMillisecond(time3_dec));
InformationObject_destroy((InformationObject)spi1_dec);
InformationObject_destroy((InformationObject)spi2_dec);
InformationObject_destroy((InformationObject)spi3_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_DoublePointWithCP56Time2a(void)
{
DoublePointWithCP56Time2a dpi1;
DoublePointWithCP56Time2a dpi2;
DoublePointWithCP56Time2a dpi3;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
struct sCP56Time2a cpTime1;
struct sCP56Time2a cpTime2;
struct sCP56Time2a cpTime3;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
CP56Time2a_createFromMsTimestamp(&cpTime2, time2);
CP56Time2a_createFromMsTimestamp(&cpTime3, time3);
dpi1 = DoublePointWithCP56Time2a_create(NULL, 101, IEC60870_DOUBLE_POINT_OFF, IEC60870_QUALITY_INVALID, &cpTime1);
dpi2 = DoublePointWithCP56Time2a_create(NULL, 102, IEC60870_DOUBLE_POINT_ON, IEC60870_QUALITY_BLOCKED, &cpTime2);
dpi3 = DoublePointWithCP56Time2a_create(NULL, 103, IEC60870_DOUBLE_POINT_INDETERMINATE, IEC60870_QUALITY_GOOD,
&cpTime3);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, DoublePointInformation_getQuality((DoublePointInformation)dpi1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, DoublePointInformation_getQuality((DoublePointInformation)dpi2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, DoublePointInformation_getQuality((DoublePointInformation)dpi3));
TEST_ASSERT_TRUE(DoublePointInformation_getValue((DoublePointInformation)dpi1));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dpi1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dpi2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dpi3);
InformationObject_destroy((InformationObject)dpi1);
InformationObject_destroy((InformationObject)dpi2);
InformationObject_destroy((InformationObject)dpi3);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(39, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(3, CS101_ASDU_getNumberOfElements(asdu2));
DoublePointWithCP56Time2a dpi1_dec = (DoublePointWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
DoublePointWithCP56Time2a dpi2_dec = (DoublePointWithCP56Time2a)CS101_ASDU_getElement(asdu2, 1);
DoublePointWithCP56Time2a dpi3_dec = (DoublePointWithCP56Time2a)CS101_ASDU_getElement(asdu2, 2);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)dpi1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)dpi2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)dpi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
DoublePointInformation_getQuality((DoublePointInformation)dpi1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_DOUBLE_POINT_OFF,
DoublePointInformation_getValue((DoublePointInformation)dpi1_dec));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(DoublePointWithCP56Time2a_getTimestamp(dpi1_dec)));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
DoublePointInformation_getQuality((DoublePointInformation)dpi2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_DOUBLE_POINT_ON,
DoublePointInformation_getValue((DoublePointInformation)dpi2_dec));
TEST_ASSERT_EQUAL_UINT64(time2, CP56Time2a_toMsTimestamp(DoublePointWithCP56Time2a_getTimestamp(dpi2_dec)));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, DoublePointInformation_getQuality((DoublePointInformation)dpi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_DOUBLE_POINT_INDETERMINATE,
DoublePointInformation_getValue((DoublePointInformation)dpi3_dec));
TEST_ASSERT_EQUAL_UINT64(time3, CP56Time2a_toMsTimestamp(DoublePointWithCP56Time2a_getTimestamp(dpi3_dec)));
InformationObject_destroy((InformationObject)dpi1_dec);
InformationObject_destroy((InformationObject)dpi2_dec);
InformationObject_destroy((InformationObject)dpi3_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SinglePointWithCP56Time2a(void)
{
SinglePointWithCP56Time2a spi1;
SinglePointWithCP56Time2a spi2;
SinglePointWithCP56Time2a spi3;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
struct sCP56Time2a cpTime1;
struct sCP56Time2a cpTime2;
struct sCP56Time2a cpTime3;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
CP56Time2a_createFromMsTimestamp(&cpTime2, time2);
CP56Time2a_createFromMsTimestamp(&cpTime3, time3);
spi1 = SinglePointWithCP56Time2a_create(NULL, 101, true, IEC60870_QUALITY_INVALID, &cpTime1);
spi2 = SinglePointWithCP56Time2a_create(NULL, 102, false, IEC60870_QUALITY_BLOCKED, &cpTime2);
spi3 = SinglePointWithCP56Time2a_create(NULL, 103, true, IEC60870_QUALITY_GOOD, &cpTime3);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, SinglePointInformation_getQuality((SinglePointInformation)spi1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, SinglePointInformation_getQuality((SinglePointInformation)spi2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality((SinglePointInformation)spi3));
TEST_ASSERT_TRUE(SinglePointInformation_getValue((SinglePointInformation)spi1));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spi3);
InformationObject_destroy((InformationObject)spi1);
InformationObject_destroy((InformationObject)spi2);
InformationObject_destroy((InformationObject)spi3);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(39, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(3, CS101_ASDU_getNumberOfElements(asdu2));
SinglePointWithCP56Time2a spi1_dec = (SinglePointWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
SinglePointWithCP56Time2a spi2_dec = (SinglePointWithCP56Time2a)CS101_ASDU_getElement(asdu2, 1);
SinglePointWithCP56Time2a spi3_dec = (SinglePointWithCP56Time2a)CS101_ASDU_getElement(asdu2, 2);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spi1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)spi2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)spi3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
SinglePointInformation_getQuality((SinglePointInformation)spi1_dec));
TEST_ASSERT_TRUE(SinglePointInformation_getValue((SinglePointInformation)spi1_dec));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(SinglePointWithCP56Time2a_getTimestamp(spi1_dec)));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
SinglePointInformation_getQuality((SinglePointInformation)spi2_dec));
TEST_ASSERT_FALSE(SinglePointInformation_getValue((SinglePointInformation)spi2_dec));
TEST_ASSERT_EQUAL_UINT64(time2, CP56Time2a_toMsTimestamp(SinglePointWithCP56Time2a_getTimestamp(spi2_dec)));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, SinglePointInformation_getQuality((SinglePointInformation)spi3_dec));
TEST_ASSERT_TRUE(SinglePointInformation_getValue((SinglePointInformation)spi3_dec));
TEST_ASSERT_EQUAL_UINT64(time3, CP56Time2a_toMsTimestamp(SinglePointWithCP56Time2a_getTimestamp(spi3_dec)));
InformationObject_destroy((InformationObject)spi1_dec);
InformationObject_destroy((InformationObject)spi2_dec);
InformationObject_destroy((InformationObject)spi3_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_NormalizeMeasureValueWithoutQuality(void)
{
MeasuredValueNormalizedWithoutQuality nmv1;
nmv1 = MeasuredValueNormalizedWithoutQuality_create(NULL, 101, 0.5f);
TEST_ASSERT_FLOAT_WITHIN(
0.01f, 0.5f, MeasuredValueNormalizedWithoutQuality_getValue((MeasuredValueNormalizedWithoutQuality)nmv1));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv1);
MeasuredValueNormalizedWithoutQuality_destroy(nmv1);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(11, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
MeasuredValueNormalizedWithoutQuality nmv1_dec =
(MeasuredValueNormalizedWithoutQuality)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)nmv1_dec));
TEST_ASSERT_FLOAT_WITHIN(
0.01f, 0.5f, MeasuredValueNormalizedWithoutQuality_getValue((MeasuredValueNormalizedWithoutQuality)nmv1_dec));
MeasuredValueNormalizedWithoutQuality_destroy(nmv1_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_NormalizeMeasureValue(void)
{
MeasuredValueNormalized nmv1;
MeasuredValueNormalized nmv2;
MeasuredValueNormalized nmv3;
MeasuredValueNormalized nmv4;
MeasuredValueNormalized nmv5;
MeasuredValueNormalized nmv6;
MeasuredValueNormalized nmv7;
MeasuredValueNormalized nmv8;
nmv1 = MeasuredValueNormalized_create(NULL, 101, -0.5f, IEC60870_QUALITY_GOOD);
nmv2 = MeasuredValueNormalized_create(NULL, 102, -0.2f, IEC60870_QUALITY_OVERFLOW);
nmv3 = MeasuredValueNormalized_create(NULL, 103, -0.1f, IEC60870_QUALITY_RESERVED);
nmv4 = MeasuredValueNormalized_create(NULL, 104, 0, IEC60870_QUALITY_ELAPSED_TIME_INVALID);
nmv5 = MeasuredValueNormalized_create(NULL, 105, 0.2f, IEC60870_QUALITY_BLOCKED);
nmv6 = MeasuredValueNormalized_create(NULL, 106, 0.3f, IEC60870_QUALITY_SUBSTITUTED);
nmv7 = MeasuredValueNormalized_create(NULL, 107, 0.4f, IEC60870_QUALITY_NON_TOPICAL);
nmv8 = MeasuredValueNormalized_create(NULL, 108, 0.5f, IEC60870_QUALITY_INVALID);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv8));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv1));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv2));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.1f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv3));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv4));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv5));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.3f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv6));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.4f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv7));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv8);
MeasuredValueNormalized_destroy(nmv1);
MeasuredValueNormalized_destroy(nmv2);
MeasuredValueNormalized_destroy(nmv3);
MeasuredValueNormalized_destroy(nmv4);
MeasuredValueNormalized_destroy(nmv5);
MeasuredValueNormalized_destroy(nmv6);
MeasuredValueNormalized_destroy(nmv7);
MeasuredValueNormalized_destroy(nmv8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(54, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
MeasuredValueNormalized nmv1_dec = (MeasuredValueNormalized)CS101_ASDU_getElement(asdu2, 0);
MeasuredValueNormalized nmv2_dec = (MeasuredValueNormalized)CS101_ASDU_getElement(asdu2, 1);
MeasuredValueNormalized nmv3_dec = (MeasuredValueNormalized)CS101_ASDU_getElement(asdu2, 2);
MeasuredValueNormalized nmv4_dec = (MeasuredValueNormalized)CS101_ASDU_getElement(asdu2, 3);
MeasuredValueNormalized nmv5_dec = (MeasuredValueNormalized)CS101_ASDU_getElement(asdu2, 4);
MeasuredValueNormalized nmv6_dec = (MeasuredValueNormalized)CS101_ASDU_getElement(asdu2, 5);
MeasuredValueNormalized nmv7_dec = (MeasuredValueNormalized)CS101_ASDU_getElement(asdu2, 6);
MeasuredValueNormalized nmv8_dec = (MeasuredValueNormalized)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)nmv1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)nmv2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)nmv3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)nmv4_dec));
TEST_ASSERT_EQUAL_INT(105, InformationObject_getObjectAddress((InformationObject)nmv5_dec));
TEST_ASSERT_EQUAL_INT(106, InformationObject_getObjectAddress((InformationObject)nmv6_dec));
TEST_ASSERT_EQUAL_INT(107, InformationObject_getObjectAddress((InformationObject)nmv7_dec));
TEST_ASSERT_EQUAL_INT(108, InformationObject_getObjectAddress((InformationObject)nmv8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv8_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv1_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv2_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.1f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv3_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv4_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv5_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.3f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv6_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.4f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv7_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv8_dec));
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)nmv1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)nmv2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)nmv3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)nmv4_dec));
TEST_ASSERT_EQUAL_INT(105, InformationObject_getObjectAddress((InformationObject)nmv5_dec));
TEST_ASSERT_EQUAL_INT(106, InformationObject_getObjectAddress((InformationObject)nmv6_dec));
TEST_ASSERT_EQUAL_INT(107, InformationObject_getObjectAddress((InformationObject)nmv7_dec));
TEST_ASSERT_EQUAL_INT(108, InformationObject_getObjectAddress((InformationObject)nmv8_dec));
MeasuredValueNormalized_destroy(nmv1_dec);
MeasuredValueNormalized_destroy(nmv2_dec);
MeasuredValueNormalized_destroy(nmv3_dec);
MeasuredValueNormalized_destroy(nmv4_dec);
MeasuredValueNormalized_destroy(nmv5_dec);
MeasuredValueNormalized_destroy(nmv6_dec);
MeasuredValueNormalized_destroy(nmv7_dec);
MeasuredValueNormalized_destroy(nmv8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_MeasuredValueNormalizedWithCP24Time2a(void)
{
MeasuredValueNormalizedWithCP24Time2a nmv1;
MeasuredValueNormalizedWithCP24Time2a nmv2;
MeasuredValueNormalizedWithCP24Time2a nmv3;
MeasuredValueNormalizedWithCP24Time2a nmv4;
MeasuredValueNormalizedWithCP24Time2a nmv5;
MeasuredValueNormalizedWithCP24Time2a nmv6;
MeasuredValueNormalizedWithCP24Time2a nmv7;
MeasuredValueNormalizedWithCP24Time2a nmv8;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
uint64_t time4 = time3 + 1000;
uint64_t time5 = time4 + 1000;
uint64_t time6 = time5 + 1000;
uint64_t time7 = time6 + 1000;
uint64_t time8 = time7 + 1000;
struct sCP24Time2a cpTime1;
struct sCP24Time2a cpTime2;
struct sCP24Time2a cpTime3;
struct sCP24Time2a cpTime4;
struct sCP24Time2a cpTime5;
struct sCP24Time2a cpTime6;
struct sCP24Time2a cpTime7;
struct sCP24Time2a cpTime8;
bzero(&cpTime1, sizeof(struct sCP24Time2a));
bzero(&cpTime2, sizeof(struct sCP24Time2a));
bzero(&cpTime3, sizeof(struct sCP24Time2a));
bzero(&cpTime4, sizeof(struct sCP24Time2a));
bzero(&cpTime5, sizeof(struct sCP24Time2a));
bzero(&cpTime6, sizeof(struct sCP24Time2a));
bzero(&cpTime7, sizeof(struct sCP24Time2a));
bzero(&cpTime8, sizeof(struct sCP24Time2a));
CP24Time2a_setMinute(&cpTime1, 12);
CP24Time2a_setMillisecond(&cpTime1, 24123);
CP24Time2a_setMinute(&cpTime2, 54);
CP24Time2a_setMillisecond(&cpTime2, 12345);
CP24Time2a_setMinute(&cpTime3, 00);
CP24Time2a_setMillisecond(&cpTime3, 00001);
CP24Time2a_setMinute(&cpTime4, 12);
CP24Time2a_setMillisecond(&cpTime4, 24123);
CP24Time2a_setMinute(&cpTime5, 12);
CP24Time2a_setMillisecond(&cpTime5, 24123);
CP24Time2a_setMinute(&cpTime6, 12);
CP24Time2a_setMillisecond(&cpTime6, 24123);
CP24Time2a_setMinute(&cpTime7, 12);
CP24Time2a_setMillisecond(&cpTime7, 24123);
CP24Time2a_setMinute(&cpTime8, 12);
CP24Time2a_setMillisecond(&cpTime8, 24123);
nmv1 = MeasuredValueNormalizedWithCP24Time2a_create(NULL, 101, -0.5f, IEC60870_QUALITY_GOOD, &cpTime1);
nmv2 = MeasuredValueNormalizedWithCP24Time2a_create(NULL, 102, -0.2f, IEC60870_QUALITY_OVERFLOW, &cpTime2);
nmv3 = MeasuredValueNormalizedWithCP24Time2a_create(NULL, 103, -0.1f, IEC60870_QUALITY_RESERVED, &cpTime3);
nmv4 = MeasuredValueNormalizedWithCP24Time2a_create(NULL, 104, 0, IEC60870_QUALITY_ELAPSED_TIME_INVALID, &cpTime4);
nmv5 = MeasuredValueNormalizedWithCP24Time2a_create(NULL, 105, 0.2f, IEC60870_QUALITY_BLOCKED, &cpTime5);
nmv6 = MeasuredValueNormalizedWithCP24Time2a_create(NULL, 106, 0.3f, IEC60870_QUALITY_SUBSTITUTED, &cpTime6);
nmv7 = MeasuredValueNormalizedWithCP24Time2a_create(NULL, 107, 0.4f, IEC60870_QUALITY_NON_TOPICAL, &cpTime7);
nmv8 = MeasuredValueNormalizedWithCP24Time2a_create(NULL, 108, 0.5f, IEC60870_QUALITY_INVALID, &cpTime8);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv8));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv1));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv2));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.1f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv3));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv4));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv5));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.3f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv6));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.4f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv7));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv8);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv1);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv2);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv3);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv4);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv5);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv6);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv7);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(78, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
MeasuredValueNormalizedWithCP24Time2a nmv1_dec =
(MeasuredValueNormalizedWithCP24Time2a)CS101_ASDU_getElement(asdu2, 0);
MeasuredValueNormalizedWithCP24Time2a nmv2_dec =
(MeasuredValueNormalizedWithCP24Time2a)CS101_ASDU_getElement(asdu2, 1);
MeasuredValueNormalizedWithCP24Time2a nmv3_dec =
(MeasuredValueNormalizedWithCP24Time2a)CS101_ASDU_getElement(asdu2, 2);
MeasuredValueNormalizedWithCP24Time2a nmv4_dec =
(MeasuredValueNormalizedWithCP24Time2a)CS101_ASDU_getElement(asdu2, 3);
MeasuredValueNormalizedWithCP24Time2a nmv5_dec =
(MeasuredValueNormalizedWithCP24Time2a)CS101_ASDU_getElement(asdu2, 4);
MeasuredValueNormalizedWithCP24Time2a nmv6_dec =
(MeasuredValueNormalizedWithCP24Time2a)CS101_ASDU_getElement(asdu2, 5);
MeasuredValueNormalizedWithCP24Time2a nmv7_dec =
(MeasuredValueNormalizedWithCP24Time2a)CS101_ASDU_getElement(asdu2, 6);
MeasuredValueNormalizedWithCP24Time2a nmv8_dec =
(MeasuredValueNormalizedWithCP24Time2a)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)nmv1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)nmv2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)nmv3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)nmv4_dec));
TEST_ASSERT_EQUAL_INT(105, InformationObject_getObjectAddress((InformationObject)nmv5_dec));
TEST_ASSERT_EQUAL_INT(106, InformationObject_getObjectAddress((InformationObject)nmv6_dec));
TEST_ASSERT_EQUAL_INT(107, InformationObject_getObjectAddress((InformationObject)nmv7_dec));
TEST_ASSERT_EQUAL_INT(108, InformationObject_getObjectAddress((InformationObject)nmv8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv8_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv1_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv2_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.1f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv3_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv4_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv5_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.3f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv6_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.4f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv7_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv8_dec));
CP24Time2a time1_dec = MeasuredValueNormalizedWithCP24Time2a_getTimestamp(nmv1_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time1_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time1_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time1_dec));
CP24Time2a time2_dec = MeasuredValueNormalizedWithCP24Time2a_getTimestamp(nmv2_dec);
TEST_ASSERT_EQUAL_INT(54, CP24Time2a_getMinute(time2_dec));
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getSecond(time2_dec));
TEST_ASSERT_EQUAL_INT(345, CP24Time2a_getMillisecond(time2_dec));
CP24Time2a time3_dec = MeasuredValueNormalizedWithCP24Time2a_getTimestamp(nmv3_dec);
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getMinute(time3_dec));
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getSecond(time3_dec));
TEST_ASSERT_EQUAL_INT(1, CP24Time2a_getMillisecond(time3_dec));
CP24Time2a time4_dec = MeasuredValueNormalizedWithCP24Time2a_getTimestamp(nmv4_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time4_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time4_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time4_dec));
CP24Time2a time5_dec = MeasuredValueNormalizedWithCP24Time2a_getTimestamp(nmv5_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time5_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time5_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time5_dec));
CP24Time2a time6_dec = MeasuredValueNormalizedWithCP24Time2a_getTimestamp(nmv6_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time6_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time6_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time6_dec));
CP24Time2a time7_dec = MeasuredValueNormalizedWithCP24Time2a_getTimestamp(nmv7_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time7_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time7_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time7_dec));
CP24Time2a time8_dec = MeasuredValueNormalizedWithCP24Time2a_getTimestamp(nmv8_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time8_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time8_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time8_dec));
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv1_dec);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv2_dec);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv3_dec);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv4_dec);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv5_dec);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv6_dec);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv7_dec);
MeasuredValueNormalizedWithCP24Time2a_destroy(nmv8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_MeasuredValueNormalizedWithCP56Time2a(void)
{
MeasuredValueNormalizedWithCP56Time2a nmv1;
MeasuredValueNormalizedWithCP56Time2a nmv2;
MeasuredValueNormalizedWithCP56Time2a nmv3;
MeasuredValueNormalizedWithCP56Time2a nmv4;
MeasuredValueNormalizedWithCP56Time2a nmv5;
MeasuredValueNormalizedWithCP56Time2a nmv6;
MeasuredValueNormalizedWithCP56Time2a nmv7;
MeasuredValueNormalizedWithCP56Time2a nmv8;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
uint64_t time4 = time3 + 1000;
uint64_t time5 = time4 + 1000;
uint64_t time6 = time5 + 1000;
uint64_t time7 = time6 + 1000;
uint64_t time8 = time7 + 1000;
struct sCP56Time2a cpTime1;
struct sCP56Time2a cpTime2;
struct sCP56Time2a cpTime3;
struct sCP56Time2a cpTime4;
struct sCP56Time2a cpTime5;
struct sCP56Time2a cpTime6;
struct sCP56Time2a cpTime7;
struct sCP56Time2a cpTime8;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
CP56Time2a_createFromMsTimestamp(&cpTime2, time2);
CP56Time2a_createFromMsTimestamp(&cpTime3, time3);
CP56Time2a_createFromMsTimestamp(&cpTime4, time4);
CP56Time2a_createFromMsTimestamp(&cpTime5, time5);
CP56Time2a_createFromMsTimestamp(&cpTime6, time6);
CP56Time2a_createFromMsTimestamp(&cpTime7, time7);
CP56Time2a_createFromMsTimestamp(&cpTime8, time8);
nmv1 = MeasuredValueNormalizedWithCP56Time2a_create(NULL, 101, -0.5f, IEC60870_QUALITY_GOOD, &cpTime1);
nmv2 = MeasuredValueNormalizedWithCP56Time2a_create(NULL, 102, -0.2f, IEC60870_QUALITY_OVERFLOW, &cpTime2);
nmv3 = MeasuredValueNormalizedWithCP56Time2a_create(NULL, 103, -0.1f, IEC60870_QUALITY_RESERVED, &cpTime3);
nmv4 = MeasuredValueNormalizedWithCP56Time2a_create(NULL, 104, 0, IEC60870_QUALITY_ELAPSED_TIME_INVALID, &cpTime4);
nmv5 = MeasuredValueNormalizedWithCP56Time2a_create(NULL, 105, 0.2f, IEC60870_QUALITY_BLOCKED, &cpTime5);
nmv6 = MeasuredValueNormalizedWithCP56Time2a_create(NULL, 106, 0.3f, IEC60870_QUALITY_SUBSTITUTED, &cpTime6);
nmv7 = MeasuredValueNormalizedWithCP56Time2a_create(NULL, 107, 0.4f, IEC60870_QUALITY_NON_TOPICAL, &cpTime7);
nmv8 = MeasuredValueNormalizedWithCP56Time2a_create(NULL, 108, 0.5f, IEC60870_QUALITY_INVALID, &cpTime8);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv8));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv1));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv2));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.1f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv3));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv4));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv5));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.3f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv6));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.4f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv7));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)nmv8);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv1);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv2);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv3);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv4);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv5);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv6);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv7);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(110, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
MeasuredValueNormalizedWithCP56Time2a nmv1_dec =
(MeasuredValueNormalizedWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
MeasuredValueNormalizedWithCP56Time2a nmv2_dec =
(MeasuredValueNormalizedWithCP56Time2a)CS101_ASDU_getElement(asdu2, 1);
MeasuredValueNormalizedWithCP56Time2a nmv3_dec =
(MeasuredValueNormalizedWithCP56Time2a)CS101_ASDU_getElement(asdu2, 2);
MeasuredValueNormalizedWithCP56Time2a nmv4_dec =
(MeasuredValueNormalizedWithCP56Time2a)CS101_ASDU_getElement(asdu2, 3);
MeasuredValueNormalizedWithCP56Time2a nmv5_dec =
(MeasuredValueNormalizedWithCP56Time2a)CS101_ASDU_getElement(asdu2, 4);
MeasuredValueNormalizedWithCP56Time2a nmv6_dec =
(MeasuredValueNormalizedWithCP56Time2a)CS101_ASDU_getElement(asdu2, 5);
MeasuredValueNormalizedWithCP56Time2a nmv7_dec =
(MeasuredValueNormalizedWithCP56Time2a)CS101_ASDU_getElement(asdu2, 6);
MeasuredValueNormalizedWithCP56Time2a nmv8_dec =
(MeasuredValueNormalizedWithCP56Time2a)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)nmv1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)nmv2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)nmv3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)nmv4_dec));
TEST_ASSERT_EQUAL_INT(105, InformationObject_getObjectAddress((InformationObject)nmv5_dec));
TEST_ASSERT_EQUAL_INT(106, InformationObject_getObjectAddress((InformationObject)nmv6_dec));
TEST_ASSERT_EQUAL_INT(107, InformationObject_getObjectAddress((InformationObject)nmv7_dec));
TEST_ASSERT_EQUAL_INT(108, InformationObject_getObjectAddress((InformationObject)nmv8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID,
MeasuredValueNormalized_getQuality((MeasuredValueNormalized)nmv8_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv1_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv2_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, -0.1f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv3_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv4_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.2f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv5_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.3f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv6_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.4f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv7_dec));
TEST_ASSERT_FLOAT_WITHIN(0.01f, 0.5f, MeasuredValueNormalized_getValue((MeasuredValueNormalized)nmv8_dec));
TEST_ASSERT_EQUAL_UINT64(time1,
CP56Time2a_toMsTimestamp(MeasuredValueNormalizedWithCP56Time2a_getTimestamp(nmv1_dec)));
TEST_ASSERT_EQUAL_UINT64(time2,
CP56Time2a_toMsTimestamp(MeasuredValueNormalizedWithCP56Time2a_getTimestamp(nmv2_dec)));
TEST_ASSERT_EQUAL_UINT64(time3,
CP56Time2a_toMsTimestamp(MeasuredValueNormalizedWithCP56Time2a_getTimestamp(nmv3_dec)));
TEST_ASSERT_EQUAL_UINT64(time4,
CP56Time2a_toMsTimestamp(MeasuredValueNormalizedWithCP56Time2a_getTimestamp(nmv4_dec)));
TEST_ASSERT_EQUAL_UINT64(time5,
CP56Time2a_toMsTimestamp(MeasuredValueNormalizedWithCP56Time2a_getTimestamp(nmv5_dec)));
TEST_ASSERT_EQUAL_UINT64(time6,
CP56Time2a_toMsTimestamp(MeasuredValueNormalizedWithCP56Time2a_getTimestamp(nmv6_dec)));
TEST_ASSERT_EQUAL_UINT64(time7,
CP56Time2a_toMsTimestamp(MeasuredValueNormalizedWithCP56Time2a_getTimestamp(nmv7_dec)));
TEST_ASSERT_EQUAL_UINT64(time8,
CP56Time2a_toMsTimestamp(MeasuredValueNormalizedWithCP56Time2a_getTimestamp(nmv8_dec)));
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv1_dec);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv2_dec);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv3_dec);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv4_dec);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv5_dec);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv6_dec);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv7_dec);
MeasuredValueNormalizedWithCP56Time2a_destroy(nmv8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_MeasuredValueScaled(void)
{
MeasuredValueScaled mvs1;
MeasuredValueScaled mvs2;
MeasuredValueScaled mvs3;
MeasuredValueScaled mvs4;
MeasuredValueScaled mvs5;
MeasuredValueScaled mvs6;
MeasuredValueScaled mvs7;
MeasuredValueScaled mvs8;
mvs1 = MeasuredValueScaled_create(NULL, 101, INT16_MAX, IEC60870_QUALITY_GOOD);
mvs2 = MeasuredValueScaled_create(NULL, 102, INT16_MAX, IEC60870_QUALITY_OVERFLOW);
mvs3 = MeasuredValueScaled_create(NULL, 103, INT16_MAX, IEC60870_QUALITY_RESERVED);
mvs4 = MeasuredValueScaled_create(NULL, 104, INT16_MAX, IEC60870_QUALITY_ELAPSED_TIME_INVALID);
mvs5 = MeasuredValueScaled_create(NULL, 105, INT16_MIN, IEC60870_QUALITY_BLOCKED);
mvs6 = MeasuredValueScaled_create(NULL, 106, INT16_MIN, IEC60870_QUALITY_SUBSTITUTED);
mvs7 = MeasuredValueScaled_create(NULL, 107, INT16_MIN, IEC60870_QUALITY_NON_TOPICAL);
mvs8 = MeasuredValueScaled_create(NULL, 108, INT16_MIN, IEC60870_QUALITY_INVALID);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs8));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs1));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs2));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs3));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs4));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs5));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs6));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs7));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs8);
MeasuredValueScaled_destroy(mvs1);
MeasuredValueScaled_destroy(mvs2);
MeasuredValueScaled_destroy(mvs3);
MeasuredValueScaled_destroy(mvs4);
MeasuredValueScaled_destroy(mvs5);
MeasuredValueScaled_destroy(mvs6);
MeasuredValueScaled_destroy(mvs7);
MeasuredValueScaled_destroy(mvs8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(54, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
MeasuredValueScaled mvs1_dec = (MeasuredValueScaled)CS101_ASDU_getElement(asdu2, 0);
MeasuredValueScaled mvs2_dec = (MeasuredValueScaled)CS101_ASDU_getElement(asdu2, 1);
MeasuredValueScaled mvs3_dec = (MeasuredValueScaled)CS101_ASDU_getElement(asdu2, 2);
MeasuredValueScaled mvs4_dec = (MeasuredValueScaled)CS101_ASDU_getElement(asdu2, 3);
MeasuredValueScaled mvs5_dec = (MeasuredValueScaled)CS101_ASDU_getElement(asdu2, 4);
MeasuredValueScaled mvs6_dec = (MeasuredValueScaled)CS101_ASDU_getElement(asdu2, 5);
MeasuredValueScaled mvs7_dec = (MeasuredValueScaled)CS101_ASDU_getElement(asdu2, 6);
MeasuredValueScaled mvs8_dec = (MeasuredValueScaled)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)mvs1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)mvs2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)mvs3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)mvs4_dec));
TEST_ASSERT_EQUAL_INT(105, InformationObject_getObjectAddress((InformationObject)mvs5_dec));
TEST_ASSERT_EQUAL_INT(106, InformationObject_getObjectAddress((InformationObject)mvs6_dec));
TEST_ASSERT_EQUAL_INT(107, InformationObject_getObjectAddress((InformationObject)mvs7_dec));
TEST_ASSERT_EQUAL_INT(108, InformationObject_getObjectAddress((InformationObject)mvs8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs8_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs1_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs2_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs3_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs4_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs5_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs6_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs7_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs8_dec));
MeasuredValueScaled_destroy(mvs1_dec);
MeasuredValueScaled_destroy(mvs2_dec);
MeasuredValueScaled_destroy(mvs3_dec);
MeasuredValueScaled_destroy(mvs4_dec);
MeasuredValueScaled_destroy(mvs5_dec);
MeasuredValueScaled_destroy(mvs6_dec);
MeasuredValueScaled_destroy(mvs7_dec);
MeasuredValueScaled_destroy(mvs8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_MeasuredValueScaledWithCP24Time2a(void)
{
MeasuredValueScaledWithCP24Time2a mvs1;
MeasuredValueScaledWithCP24Time2a mvs2;
MeasuredValueScaledWithCP24Time2a mvs3;
MeasuredValueScaledWithCP24Time2a mvs4;
MeasuredValueScaledWithCP24Time2a mvs5;
MeasuredValueScaledWithCP24Time2a mvs6;
MeasuredValueScaledWithCP24Time2a mvs7;
MeasuredValueScaledWithCP24Time2a mvs8;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
uint64_t time4 = time3 + 1000;
uint64_t time5 = time4 + 1000;
uint64_t time6 = time5 + 1000;
uint64_t time7 = time6 + 1000;
uint64_t time8 = time7 + 1000;
struct sCP24Time2a cpTime1;
struct sCP24Time2a cpTime2;
struct sCP24Time2a cpTime3;
struct sCP24Time2a cpTime4;
struct sCP24Time2a cpTime5;
struct sCP24Time2a cpTime6;
struct sCP24Time2a cpTime7;
struct sCP24Time2a cpTime8;
bzero(&cpTime1, sizeof(struct sCP24Time2a));
bzero(&cpTime2, sizeof(struct sCP24Time2a));
bzero(&cpTime3, sizeof(struct sCP24Time2a));
bzero(&cpTime4, sizeof(struct sCP24Time2a));
bzero(&cpTime5, sizeof(struct sCP24Time2a));
bzero(&cpTime6, sizeof(struct sCP24Time2a));
bzero(&cpTime7, sizeof(struct sCP24Time2a));
bzero(&cpTime8, sizeof(struct sCP24Time2a));
CP24Time2a_setMinute(&cpTime1, 12);
CP24Time2a_setMillisecond(&cpTime1, 24123);
CP24Time2a_setMinute(&cpTime2, 54);
CP24Time2a_setMillisecond(&cpTime2, 12345);
CP24Time2a_setMinute(&cpTime3, 00);
CP24Time2a_setMillisecond(&cpTime3, 00001);
CP24Time2a_setMinute(&cpTime4, 12);
CP24Time2a_setMillisecond(&cpTime4, 24123);
CP24Time2a_setMinute(&cpTime5, 12);
CP24Time2a_setMillisecond(&cpTime5, 24123);
CP24Time2a_setMinute(&cpTime6, 12);
CP24Time2a_setMillisecond(&cpTime6, 24123);
CP24Time2a_setMinute(&cpTime7, 12);
CP24Time2a_setMillisecond(&cpTime7, 24123);
CP24Time2a_setMinute(&cpTime8, 12);
CP24Time2a_setMillisecond(&cpTime8, 24123);
mvs1 = MeasuredValueScaledWithCP24Time2a_create(NULL, 101, INT16_MAX, IEC60870_QUALITY_GOOD, &cpTime1);
mvs2 = MeasuredValueScaledWithCP24Time2a_create(NULL, 102, INT16_MAX, IEC60870_QUALITY_OVERFLOW, &cpTime2);
mvs3 = MeasuredValueScaledWithCP24Time2a_create(NULL, 103, INT16_MAX, IEC60870_QUALITY_RESERVED, &cpTime3);
mvs4 =
MeasuredValueScaledWithCP24Time2a_create(NULL, 104, INT16_MAX, IEC60870_QUALITY_ELAPSED_TIME_INVALID, &cpTime4);
mvs5 = MeasuredValueScaledWithCP24Time2a_create(NULL, 105, INT16_MIN, IEC60870_QUALITY_BLOCKED, &cpTime5);
mvs6 = MeasuredValueScaledWithCP24Time2a_create(NULL, 106, INT16_MIN, IEC60870_QUALITY_SUBSTITUTED, &cpTime6);
mvs7 = MeasuredValueScaledWithCP24Time2a_create(NULL, 107, INT16_MIN, IEC60870_QUALITY_NON_TOPICAL, &cpTime7);
mvs8 = MeasuredValueScaledWithCP24Time2a_create(NULL, 108, INT16_MIN, IEC60870_QUALITY_INVALID, &cpTime8);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs8));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs1));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs2));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs3));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs4));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs5));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs6));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs7));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs8);
MeasuredValueScaledWithCP24Time2a_destroy(mvs1);
MeasuredValueScaledWithCP24Time2a_destroy(mvs2);
MeasuredValueScaledWithCP24Time2a_destroy(mvs3);
MeasuredValueScaledWithCP24Time2a_destroy(mvs4);
MeasuredValueScaledWithCP24Time2a_destroy(mvs5);
MeasuredValueScaledWithCP24Time2a_destroy(mvs6);
MeasuredValueScaledWithCP24Time2a_destroy(mvs7);
MeasuredValueScaledWithCP24Time2a_destroy(mvs8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(78, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
MeasuredValueScaledWithCP24Time2a mvs1_dec = (MeasuredValueScaledWithCP24Time2a)CS101_ASDU_getElement(asdu2, 0);
MeasuredValueScaledWithCP24Time2a mvs2_dec = (MeasuredValueScaledWithCP24Time2a)CS101_ASDU_getElement(asdu2, 1);
MeasuredValueScaledWithCP24Time2a mvs3_dec = (MeasuredValueScaledWithCP24Time2a)CS101_ASDU_getElement(asdu2, 2);
MeasuredValueScaledWithCP24Time2a mvs4_dec = (MeasuredValueScaledWithCP24Time2a)CS101_ASDU_getElement(asdu2, 3);
MeasuredValueScaledWithCP24Time2a mvs5_dec = (MeasuredValueScaledWithCP24Time2a)CS101_ASDU_getElement(asdu2, 4);
MeasuredValueScaledWithCP24Time2a mvs6_dec = (MeasuredValueScaledWithCP24Time2a)CS101_ASDU_getElement(asdu2, 5);
MeasuredValueScaledWithCP24Time2a mvs7_dec = (MeasuredValueScaledWithCP24Time2a)CS101_ASDU_getElement(asdu2, 6);
MeasuredValueScaledWithCP24Time2a mvs8_dec = (MeasuredValueScaledWithCP24Time2a)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)mvs1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)mvs2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)mvs3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)mvs4_dec));
TEST_ASSERT_EQUAL_INT(105, InformationObject_getObjectAddress((InformationObject)mvs5_dec));
TEST_ASSERT_EQUAL_INT(106, InformationObject_getObjectAddress((InformationObject)mvs6_dec));
TEST_ASSERT_EQUAL_INT(107, InformationObject_getObjectAddress((InformationObject)mvs7_dec));
TEST_ASSERT_EQUAL_INT(108, InformationObject_getObjectAddress((InformationObject)mvs8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs8_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs1_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs2_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs3_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs4_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs5_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs6_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs7_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs8_dec));
CP24Time2a time1_dec = MeasuredValueScaledWithCP24Time2a_getTimestamp(mvs1_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time1_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time1_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time1_dec));
CP24Time2a time2_dec = MeasuredValueScaledWithCP24Time2a_getTimestamp(mvs2_dec);
TEST_ASSERT_EQUAL_INT(54, CP24Time2a_getMinute(time2_dec));
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getSecond(time2_dec));
TEST_ASSERT_EQUAL_INT(345, CP24Time2a_getMillisecond(time2_dec));
CP24Time2a time3_dec = MeasuredValueScaledWithCP24Time2a_getTimestamp(mvs3_dec);
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getMinute(time3_dec));
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getSecond(time3_dec));
TEST_ASSERT_EQUAL_INT(1, CP24Time2a_getMillisecond(time3_dec));
CP24Time2a time4_dec = MeasuredValueScaledWithCP24Time2a_getTimestamp(mvs4_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time4_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time4_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time4_dec));
CP24Time2a time5_dec = MeasuredValueScaledWithCP24Time2a_getTimestamp(mvs5_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time5_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time5_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time5_dec));
CP24Time2a time6_dec = MeasuredValueScaledWithCP24Time2a_getTimestamp(mvs6_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time6_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time6_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time6_dec));
CP24Time2a time7_dec = MeasuredValueScaledWithCP24Time2a_getTimestamp(mvs7_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time7_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time7_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time7_dec));
CP24Time2a time8_dec = MeasuredValueScaledWithCP24Time2a_getTimestamp(mvs8_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time8_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time8_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time8_dec));
MeasuredValueScaledWithCP24Time2a_destroy(mvs1_dec);
MeasuredValueScaledWithCP24Time2a_destroy(mvs2_dec);
MeasuredValueScaledWithCP24Time2a_destroy(mvs3_dec);
MeasuredValueScaledWithCP24Time2a_destroy(mvs4_dec);
MeasuredValueScaledWithCP24Time2a_destroy(mvs5_dec);
MeasuredValueScaledWithCP24Time2a_destroy(mvs6_dec);
MeasuredValueScaledWithCP24Time2a_destroy(mvs7_dec);
MeasuredValueScaledWithCP24Time2a_destroy(mvs8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_MeasuredValueScaledWithCP56Time2a(void)
{
MeasuredValueScaledWithCP56Time2a mvs1;
MeasuredValueScaledWithCP56Time2a mvs2;
MeasuredValueScaledWithCP56Time2a mvs3;
MeasuredValueScaledWithCP56Time2a mvs4;
MeasuredValueScaledWithCP56Time2a mvs5;
MeasuredValueScaledWithCP56Time2a mvs6;
MeasuredValueScaledWithCP56Time2a mvs7;
MeasuredValueScaledWithCP56Time2a mvs8;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
uint64_t time4 = time3 + 1000;
uint64_t time5 = time4 + 1000;
uint64_t time6 = time5 + 1000;
uint64_t time7 = time6 + 1000;
uint64_t time8 = time7 + 1000;
struct sCP56Time2a cpTime1;
struct sCP56Time2a cpTime2;
struct sCP56Time2a cpTime3;
struct sCP56Time2a cpTime4;
struct sCP56Time2a cpTime5;
struct sCP56Time2a cpTime6;
struct sCP56Time2a cpTime7;
struct sCP56Time2a cpTime8;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
CP56Time2a_createFromMsTimestamp(&cpTime2, time2);
CP56Time2a_createFromMsTimestamp(&cpTime3, time3);
CP56Time2a_createFromMsTimestamp(&cpTime4, time4);
CP56Time2a_createFromMsTimestamp(&cpTime5, time5);
CP56Time2a_createFromMsTimestamp(&cpTime6, time6);
CP56Time2a_createFromMsTimestamp(&cpTime7, time7);
CP56Time2a_createFromMsTimestamp(&cpTime8, time8);
mvs1 = MeasuredValueScaledWithCP56Time2a_create(NULL, 101, INT16_MAX, IEC60870_QUALITY_GOOD, &cpTime1);
mvs2 = MeasuredValueScaledWithCP56Time2a_create(NULL, 102, INT16_MAX, IEC60870_QUALITY_OVERFLOW, &cpTime2);
mvs3 = MeasuredValueScaledWithCP56Time2a_create(NULL, 103, INT16_MAX, IEC60870_QUALITY_RESERVED, &cpTime3);
mvs4 =
MeasuredValueScaledWithCP56Time2a_create(NULL, 104, INT16_MAX, IEC60870_QUALITY_ELAPSED_TIME_INVALID, &cpTime4);
mvs5 = MeasuredValueScaledWithCP56Time2a_create(NULL, 105, INT16_MIN, IEC60870_QUALITY_BLOCKED, &cpTime5);
mvs6 = MeasuredValueScaledWithCP56Time2a_create(NULL, 106, INT16_MIN, IEC60870_QUALITY_SUBSTITUTED, &cpTime6);
mvs7 = MeasuredValueScaledWithCP56Time2a_create(NULL, 107, INT16_MIN, IEC60870_QUALITY_NON_TOPICAL, &cpTime7);
mvs8 = MeasuredValueScaledWithCP56Time2a_create(NULL, 108, INT16_MIN, IEC60870_QUALITY_INVALID, &cpTime8);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs8));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs1));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs2));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs3));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs4));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs5));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs6));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs7));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs8);
MeasuredValueScaledWithCP56Time2a_destroy(mvs1);
MeasuredValueScaledWithCP56Time2a_destroy(mvs2);
MeasuredValueScaledWithCP56Time2a_destroy(mvs3);
MeasuredValueScaledWithCP56Time2a_destroy(mvs4);
MeasuredValueScaledWithCP56Time2a_destroy(mvs5);
MeasuredValueScaledWithCP56Time2a_destroy(mvs6);
MeasuredValueScaledWithCP56Time2a_destroy(mvs7);
MeasuredValueScaledWithCP56Time2a_destroy(mvs8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(110, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
MeasuredValueScaledWithCP56Time2a mvs1_dec = (MeasuredValueScaledWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
MeasuredValueScaledWithCP56Time2a mvs2_dec = (MeasuredValueScaledWithCP56Time2a)CS101_ASDU_getElement(asdu2, 1);
MeasuredValueScaledWithCP56Time2a mvs3_dec = (MeasuredValueScaledWithCP56Time2a)CS101_ASDU_getElement(asdu2, 2);
MeasuredValueScaledWithCP56Time2a mvs4_dec = (MeasuredValueScaledWithCP56Time2a)CS101_ASDU_getElement(asdu2, 3);
MeasuredValueScaledWithCP56Time2a mvs5_dec = (MeasuredValueScaledWithCP56Time2a)CS101_ASDU_getElement(asdu2, 4);
MeasuredValueScaledWithCP56Time2a mvs6_dec = (MeasuredValueScaledWithCP56Time2a)CS101_ASDU_getElement(asdu2, 5);
MeasuredValueScaledWithCP56Time2a mvs7_dec = (MeasuredValueScaledWithCP56Time2a)CS101_ASDU_getElement(asdu2, 6);
MeasuredValueScaledWithCP56Time2a mvs8_dec = (MeasuredValueScaledWithCP56Time2a)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)mvs1_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)mvs2_dec));
TEST_ASSERT_EQUAL_INT(103, InformationObject_getObjectAddress((InformationObject)mvs3_dec));
TEST_ASSERT_EQUAL_INT(104, InformationObject_getObjectAddress((InformationObject)mvs4_dec));
TEST_ASSERT_EQUAL_INT(105, InformationObject_getObjectAddress((InformationObject)mvs5_dec));
TEST_ASSERT_EQUAL_INT(106, InformationObject_getObjectAddress((InformationObject)mvs6_dec));
TEST_ASSERT_EQUAL_INT(107, InformationObject_getObjectAddress((InformationObject)mvs7_dec));
TEST_ASSERT_EQUAL_INT(108, InformationObject_getObjectAddress((InformationObject)mvs8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL,
MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueScaled_getQuality((MeasuredValueScaled)mvs8_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs1_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs2_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs3_dec));
TEST_ASSERT_EQUAL_INT(INT16_MAX, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs4_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs5_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs6_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs7_dec));
TEST_ASSERT_EQUAL_INT(INT16_MIN, MeasuredValueScaled_getValue((MeasuredValueScaled)mvs8_dec));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(MeasuredValueScaledWithCP56Time2a_getTimestamp(mvs1_dec)));
TEST_ASSERT_EQUAL_UINT64(time2, CP56Time2a_toMsTimestamp(MeasuredValueScaledWithCP56Time2a_getTimestamp(mvs2_dec)));
TEST_ASSERT_EQUAL_UINT64(time3, CP56Time2a_toMsTimestamp(MeasuredValueScaledWithCP56Time2a_getTimestamp(mvs3_dec)));
TEST_ASSERT_EQUAL_UINT64(time4, CP56Time2a_toMsTimestamp(MeasuredValueScaledWithCP56Time2a_getTimestamp(mvs4_dec)));
TEST_ASSERT_EQUAL_UINT64(time5, CP56Time2a_toMsTimestamp(MeasuredValueScaledWithCP56Time2a_getTimestamp(mvs5_dec)));
TEST_ASSERT_EQUAL_UINT64(time6, CP56Time2a_toMsTimestamp(MeasuredValueScaledWithCP56Time2a_getTimestamp(mvs6_dec)));
TEST_ASSERT_EQUAL_UINT64(time7, CP56Time2a_toMsTimestamp(MeasuredValueScaledWithCP56Time2a_getTimestamp(mvs7_dec)));
TEST_ASSERT_EQUAL_UINT64(time8, CP56Time2a_toMsTimestamp(MeasuredValueScaledWithCP56Time2a_getTimestamp(mvs8_dec)));
MeasuredValueScaledWithCP56Time2a_destroy(mvs1_dec);
MeasuredValueScaledWithCP56Time2a_destroy(mvs2_dec);
MeasuredValueScaledWithCP56Time2a_destroy(mvs3_dec);
MeasuredValueScaledWithCP56Time2a_destroy(mvs4_dec);
MeasuredValueScaledWithCP56Time2a_destroy(mvs5_dec);
MeasuredValueScaledWithCP56Time2a_destroy(mvs6_dec);
MeasuredValueScaledWithCP56Time2a_destroy(mvs7_dec);
MeasuredValueScaledWithCP56Time2a_destroy(mvs8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_MeasuredValueShort(void)
{
MeasuredValueShort mvs1;
MeasuredValueShort mvs2;
MeasuredValueShort mvs3;
MeasuredValueShort mvs4;
MeasuredValueShort mvs5;
MeasuredValueShort mvs6;
MeasuredValueShort mvs7;
MeasuredValueShort mvs8;
mvs1 = MeasuredValueShort_create(NULL, 101, 10.5f, IEC60870_QUALITY_GOOD);
mvs2 = MeasuredValueShort_create(NULL, 102, 11.5f, IEC60870_QUALITY_OVERFLOW);
mvs3 = MeasuredValueShort_create(NULL, 103, 12.5f, IEC60870_QUALITY_RESERVED);
mvs4 = MeasuredValueShort_create(NULL, 104, 13.5f, IEC60870_QUALITY_ELAPSED_TIME_INVALID);
mvs5 = MeasuredValueShort_create(NULL, 105, 14.5f, IEC60870_QUALITY_BLOCKED);
mvs6 = MeasuredValueShort_create(NULL, 106, 15.5f, IEC60870_QUALITY_SUBSTITUTED);
mvs7 = MeasuredValueShort_create(NULL, 107, 16.5f, IEC60870_QUALITY_NON_TOPICAL);
mvs8 = MeasuredValueShort_create(NULL, 108, 17.5f, IEC60870_QUALITY_INVALID);
TEST_ASSERT_EQUAL_FLOAT(10.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs1));
TEST_ASSERT_EQUAL_FLOAT(11.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs2));
TEST_ASSERT_EQUAL_FLOAT(12.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs3));
TEST_ASSERT_EQUAL_FLOAT(13.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs4));
TEST_ASSERT_EQUAL_FLOAT(14.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs5));
TEST_ASSERT_EQUAL_FLOAT(15.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs6));
TEST_ASSERT_EQUAL_FLOAT(16.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs7));
TEST_ASSERT_EQUAL_FLOAT(17.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs8));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueShort_getQuality(mvs1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueShort_getQuality(mvs2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueShort_getQuality(mvs3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID, MeasuredValueShort_getQuality(mvs4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueShort_getQuality(mvs5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, MeasuredValueShort_getQuality(mvs6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, MeasuredValueShort_getQuality(mvs7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueShort_getQuality(mvs8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs8);
MeasuredValueShort_destroy(mvs1);
MeasuredValueShort_destroy(mvs2);
MeasuredValueShort_destroy(mvs3);
MeasuredValueShort_destroy(mvs4);
MeasuredValueShort_destroy(mvs5);
MeasuredValueShort_destroy(mvs6);
MeasuredValueShort_destroy(mvs7);
MeasuredValueShort_destroy(mvs8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(70, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
MeasuredValueShort mvs1_dec = (MeasuredValueShort)CS101_ASDU_getElement(asdu2, 0);
MeasuredValueShort mvs2_dec = (MeasuredValueShort)CS101_ASDU_getElement(asdu2, 1);
MeasuredValueShort mvs3_dec = (MeasuredValueShort)CS101_ASDU_getElement(asdu2, 2);
MeasuredValueShort mvs4_dec = (MeasuredValueShort)CS101_ASDU_getElement(asdu2, 3);
MeasuredValueShort mvs5_dec = (MeasuredValueShort)CS101_ASDU_getElement(asdu2, 4);
MeasuredValueShort mvs6_dec = (MeasuredValueShort)CS101_ASDU_getElement(asdu2, 5);
MeasuredValueShort mvs7_dec = (MeasuredValueShort)CS101_ASDU_getElement(asdu2, 6);
MeasuredValueShort mvs8_dec = (MeasuredValueShort)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_FLOAT(10.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs1_dec));
TEST_ASSERT_EQUAL_FLOAT(11.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs2_dec));
TEST_ASSERT_EQUAL_FLOAT(12.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs3_dec));
TEST_ASSERT_EQUAL_FLOAT(13.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs4_dec));
TEST_ASSERT_EQUAL_FLOAT(14.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs5_dec));
TEST_ASSERT_EQUAL_FLOAT(15.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs6_dec));
TEST_ASSERT_EQUAL_FLOAT(16.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs7_dec));
TEST_ASSERT_EQUAL_FLOAT(17.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueShort_getQuality(mvs1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueShort_getQuality(mvs2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueShort_getQuality(mvs3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID, MeasuredValueShort_getQuality(mvs4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueShort_getQuality(mvs5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, MeasuredValueShort_getQuality(mvs6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, MeasuredValueShort_getQuality(mvs7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueShort_getQuality(mvs8_dec));
MeasuredValueShort_destroy(mvs1_dec);
MeasuredValueShort_destroy(mvs2_dec);
MeasuredValueShort_destroy(mvs3_dec);
MeasuredValueShort_destroy(mvs4_dec);
MeasuredValueShort_destroy(mvs5_dec);
MeasuredValueShort_destroy(mvs6_dec);
MeasuredValueShort_destroy(mvs7_dec);
MeasuredValueShort_destroy(mvs8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_MeasuredValueShortWithCP24Time2a(void)
{
MeasuredValueShortWithCP24Time2a mvs1;
MeasuredValueShortWithCP24Time2a mvs2;
MeasuredValueShortWithCP24Time2a mvs3;
MeasuredValueShortWithCP24Time2a mvs4;
MeasuredValueShortWithCP24Time2a mvs5;
MeasuredValueShortWithCP24Time2a mvs6;
MeasuredValueShortWithCP24Time2a mvs7;
MeasuredValueShortWithCP24Time2a mvs8;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
uint64_t time4 = time3 + 1000;
uint64_t time5 = time4 + 1000;
uint64_t time6 = time5 + 1000;
uint64_t time7 = time6 + 1000;
uint64_t time8 = time7 + 1000;
struct sCP24Time2a cpTime1;
struct sCP24Time2a cpTime2;
struct sCP24Time2a cpTime3;
struct sCP24Time2a cpTime4;
struct sCP24Time2a cpTime5;
struct sCP24Time2a cpTime6;
struct sCP24Time2a cpTime7;
struct sCP24Time2a cpTime8;
bzero(&cpTime1, sizeof(struct sCP24Time2a));
bzero(&cpTime2, sizeof(struct sCP24Time2a));
bzero(&cpTime3, sizeof(struct sCP24Time2a));
bzero(&cpTime4, sizeof(struct sCP24Time2a));
bzero(&cpTime5, sizeof(struct sCP24Time2a));
bzero(&cpTime6, sizeof(struct sCP24Time2a));
bzero(&cpTime7, sizeof(struct sCP24Time2a));
bzero(&cpTime8, sizeof(struct sCP24Time2a));
CP24Time2a_setMinute(&cpTime1, 12);
CP24Time2a_setMillisecond(&cpTime1, 24123);
CP24Time2a_setMinute(&cpTime2, 54);
CP24Time2a_setMillisecond(&cpTime2, 12345);
CP24Time2a_setMinute(&cpTime3, 00);
CP24Time2a_setMillisecond(&cpTime3, 00001);
CP24Time2a_setMinute(&cpTime4, 12);
CP24Time2a_setMillisecond(&cpTime4, 24123);
CP24Time2a_setMinute(&cpTime5, 12);
CP24Time2a_setMillisecond(&cpTime5, 24123);
CP24Time2a_setMinute(&cpTime6, 12);
CP24Time2a_setMillisecond(&cpTime6, 24123);
CP24Time2a_setMinute(&cpTime7, 12);
CP24Time2a_setMillisecond(&cpTime7, 24123);
CP24Time2a_setMinute(&cpTime8, 12);
CP24Time2a_setMillisecond(&cpTime8, 24123);
mvs1 = MeasuredValueShortWithCP24Time2a_create(NULL, 101, 10.5f, IEC60870_QUALITY_GOOD, &cpTime1);
mvs2 = MeasuredValueShortWithCP24Time2a_create(NULL, 102, 11.5f, IEC60870_QUALITY_OVERFLOW, &cpTime2);
mvs3 = MeasuredValueShortWithCP24Time2a_create(NULL, 103, 12.5f, IEC60870_QUALITY_RESERVED, &cpTime3);
mvs4 = MeasuredValueShortWithCP24Time2a_create(NULL, 104, 13.5f, IEC60870_QUALITY_ELAPSED_TIME_INVALID, &cpTime4);
mvs5 = MeasuredValueShortWithCP24Time2a_create(NULL, 105, 14.5f, IEC60870_QUALITY_BLOCKED, &cpTime5);
mvs6 = MeasuredValueShortWithCP24Time2a_create(NULL, 106, 15.5f, IEC60870_QUALITY_SUBSTITUTED, &cpTime6);
mvs7 = MeasuredValueShortWithCP24Time2a_create(NULL, 107, 16.5f, IEC60870_QUALITY_NON_TOPICAL, &cpTime7);
mvs8 = MeasuredValueShortWithCP24Time2a_create(NULL, 108, 17.5f, IEC60870_QUALITY_INVALID, &cpTime8);
TEST_ASSERT_EQUAL_FLOAT(10.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs1));
TEST_ASSERT_EQUAL_FLOAT(11.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs2));
TEST_ASSERT_EQUAL_FLOAT(12.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs3));
TEST_ASSERT_EQUAL_FLOAT(13.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs4));
TEST_ASSERT_EQUAL_FLOAT(14.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs5));
TEST_ASSERT_EQUAL_FLOAT(15.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs6));
TEST_ASSERT_EQUAL_FLOAT(16.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs7));
TEST_ASSERT_EQUAL_FLOAT(17.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs8));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueShort_getQuality((MeasuredValueShort)mvs1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueShort_getQuality((MeasuredValueShort)mvs2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueShort_getQuality((MeasuredValueShort)mvs4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, MeasuredValueShort_getQuality((MeasuredValueShort)mvs7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueShort_getQuality((MeasuredValueShort)mvs8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs8);
MeasuredValueShortWithCP24Time2a_destroy(mvs1);
MeasuredValueShortWithCP24Time2a_destroy(mvs2);
MeasuredValueShortWithCP24Time2a_destroy(mvs3);
MeasuredValueShortWithCP24Time2a_destroy(mvs4);
MeasuredValueShortWithCP24Time2a_destroy(mvs5);
MeasuredValueShortWithCP24Time2a_destroy(mvs6);
MeasuredValueShortWithCP24Time2a_destroy(mvs7);
MeasuredValueShortWithCP24Time2a_destroy(mvs8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(94, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
MeasuredValueShortWithCP24Time2a mvs1_dec = (MeasuredValueShortWithCP24Time2a)CS101_ASDU_getElement(asdu2, 0);
MeasuredValueShortWithCP24Time2a mvs2_dec = (MeasuredValueShortWithCP24Time2a)CS101_ASDU_getElement(asdu2, 1);
MeasuredValueShortWithCP24Time2a mvs3_dec = (MeasuredValueShortWithCP24Time2a)CS101_ASDU_getElement(asdu2, 2);
MeasuredValueShortWithCP24Time2a mvs4_dec = (MeasuredValueShortWithCP24Time2a)CS101_ASDU_getElement(asdu2, 3);
MeasuredValueShortWithCP24Time2a mvs5_dec = (MeasuredValueShortWithCP24Time2a)CS101_ASDU_getElement(asdu2, 4);
MeasuredValueShortWithCP24Time2a mvs6_dec = (MeasuredValueShortWithCP24Time2a)CS101_ASDU_getElement(asdu2, 5);
MeasuredValueShortWithCP24Time2a mvs7_dec = (MeasuredValueShortWithCP24Time2a)CS101_ASDU_getElement(asdu2, 6);
MeasuredValueShortWithCP24Time2a mvs8_dec = (MeasuredValueShortWithCP24Time2a)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_FLOAT(10.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs1_dec));
TEST_ASSERT_EQUAL_FLOAT(11.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs2_dec));
TEST_ASSERT_EQUAL_FLOAT(12.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs3_dec));
TEST_ASSERT_EQUAL_FLOAT(13.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs4_dec));
TEST_ASSERT_EQUAL_FLOAT(14.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs5_dec));
TEST_ASSERT_EQUAL_FLOAT(15.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs6_dec));
TEST_ASSERT_EQUAL_FLOAT(16.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs7_dec));
TEST_ASSERT_EQUAL_FLOAT(17.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueShort_getQuality((MeasuredValueShort)mvs1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueShort_getQuality((MeasuredValueShort)mvs2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueShort_getQuality((MeasuredValueShort)mvs4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, MeasuredValueShort_getQuality((MeasuredValueShort)mvs7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueShort_getQuality((MeasuredValueShort)mvs8_dec));
CP24Time2a time1_dec = MeasuredValueShortWithCP24Time2a_getTimestamp(mvs1_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time1_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time1_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time1_dec));
CP24Time2a time2_dec = MeasuredValueShortWithCP24Time2a_getTimestamp(mvs2_dec);
TEST_ASSERT_EQUAL_INT(54, CP24Time2a_getMinute(time2_dec));
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getSecond(time2_dec));
TEST_ASSERT_EQUAL_INT(345, CP24Time2a_getMillisecond(time2_dec));
CP24Time2a time3_dec = MeasuredValueShortWithCP24Time2a_getTimestamp(mvs3_dec);
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getMinute(time3_dec));
TEST_ASSERT_EQUAL_INT(00, CP24Time2a_getSecond(time3_dec));
TEST_ASSERT_EQUAL_INT(1, CP24Time2a_getMillisecond(time3_dec));
CP24Time2a time4_dec = MeasuredValueShortWithCP24Time2a_getTimestamp(mvs4_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time4_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time4_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time4_dec));
CP24Time2a time5_dec = MeasuredValueShortWithCP24Time2a_getTimestamp(mvs5_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time5_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time5_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time5_dec));
CP24Time2a time6_dec = MeasuredValueShortWithCP24Time2a_getTimestamp(mvs6_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time6_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time6_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time6_dec));
CP24Time2a time7_dec = MeasuredValueShortWithCP24Time2a_getTimestamp(mvs7_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time7_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time7_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time7_dec));
CP24Time2a time8_dec = MeasuredValueShortWithCP24Time2a_getTimestamp(mvs8_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time8_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time8_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time8_dec));
MeasuredValueShortWithCP24Time2a_destroy(mvs1_dec);
MeasuredValueShortWithCP24Time2a_destroy(mvs2_dec);
MeasuredValueShortWithCP24Time2a_destroy(mvs3_dec);
MeasuredValueShortWithCP24Time2a_destroy(mvs4_dec);
MeasuredValueShortWithCP24Time2a_destroy(mvs5_dec);
MeasuredValueShortWithCP24Time2a_destroy(mvs6_dec);
MeasuredValueShortWithCP24Time2a_destroy(mvs7_dec);
MeasuredValueShortWithCP24Time2a_destroy(mvs8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_MeasuredValueShortWithCP56Time2a(void)
{
MeasuredValueShortWithCP56Time2a mvs1;
MeasuredValueShortWithCP56Time2a mvs2;
MeasuredValueShortWithCP56Time2a mvs3;
MeasuredValueShortWithCP56Time2a mvs4;
MeasuredValueShortWithCP56Time2a mvs5;
MeasuredValueShortWithCP56Time2a mvs6;
MeasuredValueShortWithCP56Time2a mvs7;
MeasuredValueShortWithCP56Time2a mvs8;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
uint64_t time3 = time2 + 1000;
uint64_t time4 = time3 + 1000;
uint64_t time5 = time4 + 1000;
uint64_t time6 = time5 + 1000;
uint64_t time7 = time6 + 1000;
uint64_t time8 = time7 + 1000;
struct sCP56Time2a cpTime1;
struct sCP56Time2a cpTime2;
struct sCP56Time2a cpTime3;
struct sCP56Time2a cpTime4;
struct sCP56Time2a cpTime5;
struct sCP56Time2a cpTime6;
struct sCP56Time2a cpTime7;
struct sCP56Time2a cpTime8;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
CP56Time2a_createFromMsTimestamp(&cpTime2, time2);
CP56Time2a_createFromMsTimestamp(&cpTime3, time3);
CP56Time2a_createFromMsTimestamp(&cpTime4, time4);
CP56Time2a_createFromMsTimestamp(&cpTime5, time5);
CP56Time2a_createFromMsTimestamp(&cpTime6, time6);
CP56Time2a_createFromMsTimestamp(&cpTime7, time7);
CP56Time2a_createFromMsTimestamp(&cpTime8, time8);
mvs1 = MeasuredValueShortWithCP56Time2a_create(NULL, 101, 10.5f, IEC60870_QUALITY_GOOD, &cpTime1);
mvs2 = MeasuredValueShortWithCP56Time2a_create(NULL, 102, 11.5f, IEC60870_QUALITY_OVERFLOW, &cpTime2);
mvs3 = MeasuredValueShortWithCP56Time2a_create(NULL, 103, 12.5f, IEC60870_QUALITY_RESERVED, &cpTime3);
mvs4 = MeasuredValueShortWithCP56Time2a_create(NULL, 104, 13.5f, IEC60870_QUALITY_ELAPSED_TIME_INVALID, &cpTime4);
mvs5 = MeasuredValueShortWithCP56Time2a_create(NULL, 105, 14.5f, IEC60870_QUALITY_BLOCKED, &cpTime5);
mvs6 = MeasuredValueShortWithCP56Time2a_create(NULL, 106, 15.5f, IEC60870_QUALITY_SUBSTITUTED, &cpTime6);
mvs7 = MeasuredValueShortWithCP56Time2a_create(NULL, 107, 16.5f, IEC60870_QUALITY_NON_TOPICAL, &cpTime7);
mvs8 = MeasuredValueShortWithCP56Time2a_create(NULL, 108, 17.5f, IEC60870_QUALITY_INVALID, &cpTime8);
TEST_ASSERT_EQUAL_FLOAT(10.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs1));
TEST_ASSERT_EQUAL_FLOAT(11.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs2));
TEST_ASSERT_EQUAL_FLOAT(12.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs3));
TEST_ASSERT_EQUAL_FLOAT(13.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs4));
TEST_ASSERT_EQUAL_FLOAT(14.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs5));
TEST_ASSERT_EQUAL_FLOAT(15.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs6));
TEST_ASSERT_EQUAL_FLOAT(16.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs7));
TEST_ASSERT_EQUAL_FLOAT(17.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs8));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueShort_getQuality((MeasuredValueShort)mvs1));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueShort_getQuality((MeasuredValueShort)mvs2));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs3));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueShort_getQuality((MeasuredValueShort)mvs4));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs5));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs6));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, MeasuredValueShort_getQuality((MeasuredValueShort)mvs7));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueShort_getQuality((MeasuredValueShort)mvs8));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs3);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs4);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs5);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs6);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs7);
CS101_ASDU_addInformationObject(asdu, (InformationObject)mvs8);
MeasuredValueShortWithCP56Time2a_destroy(mvs1);
MeasuredValueShortWithCP56Time2a_destroy(mvs2);
MeasuredValueShortWithCP56Time2a_destroy(mvs3);
MeasuredValueShortWithCP56Time2a_destroy(mvs4);
MeasuredValueShortWithCP56Time2a_destroy(mvs5);
MeasuredValueShortWithCP56Time2a_destroy(mvs6);
MeasuredValueShortWithCP56Time2a_destroy(mvs7);
MeasuredValueShortWithCP56Time2a_destroy(mvs8);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(126, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(8, CS101_ASDU_getNumberOfElements(asdu2));
MeasuredValueShortWithCP56Time2a mvs1_dec = (MeasuredValueShortWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
MeasuredValueShortWithCP56Time2a mvs2_dec = (MeasuredValueShortWithCP56Time2a)CS101_ASDU_getElement(asdu2, 1);
MeasuredValueShortWithCP56Time2a mvs3_dec = (MeasuredValueShortWithCP56Time2a)CS101_ASDU_getElement(asdu2, 2);
MeasuredValueShortWithCP56Time2a mvs4_dec = (MeasuredValueShortWithCP56Time2a)CS101_ASDU_getElement(asdu2, 3);
MeasuredValueShortWithCP56Time2a mvs5_dec = (MeasuredValueShortWithCP56Time2a)CS101_ASDU_getElement(asdu2, 4);
MeasuredValueShortWithCP56Time2a mvs6_dec = (MeasuredValueShortWithCP56Time2a)CS101_ASDU_getElement(asdu2, 5);
MeasuredValueShortWithCP56Time2a mvs7_dec = (MeasuredValueShortWithCP56Time2a)CS101_ASDU_getElement(asdu2, 6);
MeasuredValueShortWithCP56Time2a mvs8_dec = (MeasuredValueShortWithCP56Time2a)CS101_ASDU_getElement(asdu2, 7);
TEST_ASSERT_EQUAL_FLOAT(10.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs1_dec));
TEST_ASSERT_EQUAL_FLOAT(11.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs2_dec));
TEST_ASSERT_EQUAL_FLOAT(12.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs3_dec));
TEST_ASSERT_EQUAL_FLOAT(13.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs4_dec));
TEST_ASSERT_EQUAL_FLOAT(14.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs5_dec));
TEST_ASSERT_EQUAL_FLOAT(15.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs6_dec));
TEST_ASSERT_EQUAL_FLOAT(16.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs7_dec));
TEST_ASSERT_EQUAL_FLOAT(17.5f, MeasuredValueShort_getValue((MeasuredValueShort)mvs8_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, MeasuredValueShort_getQuality((MeasuredValueShort)mvs1_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_OVERFLOW, MeasuredValueShort_getQuality((MeasuredValueShort)mvs2_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_RESERVED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs3_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_ELAPSED_TIME_INVALID,
MeasuredValueShort_getQuality((MeasuredValueShort)mvs4_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_BLOCKED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs5_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_SUBSTITUTED, MeasuredValueShort_getQuality((MeasuredValueShort)mvs6_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_NON_TOPICAL, MeasuredValueShort_getQuality((MeasuredValueShort)mvs7_dec));
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, MeasuredValueShort_getQuality((MeasuredValueShort)mvs8_dec));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(MeasuredValueShortWithCP56Time2a_getTimestamp(mvs1_dec)));
TEST_ASSERT_EQUAL_UINT64(time2, CP56Time2a_toMsTimestamp(MeasuredValueShortWithCP56Time2a_getTimestamp(mvs2_dec)));
TEST_ASSERT_EQUAL_UINT64(time3, CP56Time2a_toMsTimestamp(MeasuredValueShortWithCP56Time2a_getTimestamp(mvs3_dec)));
TEST_ASSERT_EQUAL_UINT64(time4, CP56Time2a_toMsTimestamp(MeasuredValueShortWithCP56Time2a_getTimestamp(mvs4_dec)));
TEST_ASSERT_EQUAL_UINT64(time5, CP56Time2a_toMsTimestamp(MeasuredValueShortWithCP56Time2a_getTimestamp(mvs5_dec)));
TEST_ASSERT_EQUAL_UINT64(time6, CP56Time2a_toMsTimestamp(MeasuredValueShortWithCP56Time2a_getTimestamp(mvs6_dec)));
TEST_ASSERT_EQUAL_UINT64(time7, CP56Time2a_toMsTimestamp(MeasuredValueShortWithCP56Time2a_getTimestamp(mvs7_dec)));
TEST_ASSERT_EQUAL_UINT64(time8, CP56Time2a_toMsTimestamp(MeasuredValueShortWithCP56Time2a_getTimestamp(mvs8_dec)));
MeasuredValueShortWithCP56Time2a_destroy(mvs1_dec);
MeasuredValueShortWithCP56Time2a_destroy(mvs2_dec);
MeasuredValueShortWithCP56Time2a_destroy(mvs3_dec);
MeasuredValueShortWithCP56Time2a_destroy(mvs4_dec);
MeasuredValueShortWithCP56Time2a_destroy(mvs5_dec);
MeasuredValueShortWithCP56Time2a_destroy(mvs6_dec);
MeasuredValueShortWithCP56Time2a_destroy(mvs7_dec);
MeasuredValueShortWithCP56Time2a_destroy(mvs8_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_IntegratedTotals(void)
{
IntegratedTotals it1;
IntegratedTotals it2;
BinaryCounterReading bcr1;
BinaryCounterReading bcr2;
bcr1 = BinaryCounterReading_create(NULL, INT32_MAX, 0, true, true, true);
bcr2 = BinaryCounterReading_create(NULL, INT32_MIN, 15, false, false, false);
it1 = IntegratedTotals_create(NULL, 101, bcr1);
it2 = IntegratedTotals_create(NULL, 102, bcr2);
BinaryCounterReading_destroy(bcr1);
BinaryCounterReading_destroy(bcr2);
TEST_ASSERT_EQUAL_INT32(INT32_MAX, BinaryCounterReading_getValue(IntegratedTotals_getBCR(it1)));
TEST_ASSERT_EQUAL_UINT8(0, BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR(it1)));
TEST_ASSERT_TRUE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR(it1)));
TEST_ASSERT_TRUE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR(it1)));
TEST_ASSERT_TRUE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR(it1)));
TEST_ASSERT_EQUAL_INT32(INT32_MIN, BinaryCounterReading_getValue(IntegratedTotals_getBCR(it2)));
TEST_ASSERT_EQUAL_UINT8(15, BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR(it2)));
TEST_ASSERT_FALSE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR(it2)));
TEST_ASSERT_FALSE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR(it2)));
TEST_ASSERT_FALSE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR(it2)));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)it1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)it2);
IntegratedTotals_destroy(it1);
IntegratedTotals_destroy(it2);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(22, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(2, CS101_ASDU_getNumberOfElements(asdu2));
IntegratedTotals it1_dec = (IntegratedTotals)CS101_ASDU_getElement(asdu2, 0);
IntegratedTotals it2_dec = (IntegratedTotals)CS101_ASDU_getElement(asdu2, 1);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)it1_dec));
TEST_ASSERT_EQUAL_INT32(INT32_MAX, BinaryCounterReading_getValue(IntegratedTotals_getBCR(it1_dec)));
TEST_ASSERT_EQUAL_UINT8(0, BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR(it1_dec)));
TEST_ASSERT_TRUE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR(it1_dec)));
TEST_ASSERT_TRUE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR(it1_dec)));
TEST_ASSERT_TRUE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR(it1_dec)));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)it2_dec));
TEST_ASSERT_EQUAL_INT32(INT32_MIN, BinaryCounterReading_getValue(IntegratedTotals_getBCR(it2_dec)));
TEST_ASSERT_EQUAL_UINT8(15, BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR(it2_dec)));
TEST_ASSERT_FALSE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR(it2_dec)));
TEST_ASSERT_FALSE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR(it2_dec)));
TEST_ASSERT_FALSE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR(it2_dec)));
IntegratedTotals_destroy(it1_dec);
IntegratedTotals_destroy(it2_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_IntegratedTotalsWithCP24Time2a(void)
{
IntegratedTotalsWithCP24Time2a it1;
IntegratedTotalsWithCP24Time2a it2;
BinaryCounterReading bcr1;
BinaryCounterReading bcr2;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
struct sCP24Time2a cpTime1;
struct sCP24Time2a cpTime2;
bzero(&cpTime1, sizeof(struct sCP24Time2a));
bzero(&cpTime2, sizeof(struct sCP24Time2a));
CP24Time2a_setMinute(&cpTime1, 12);
CP24Time2a_setMillisecond(&cpTime1, 24123);
CP24Time2a_setMinute(&cpTime2, 54);
CP24Time2a_setMillisecond(&cpTime2, 12345);
bcr1 = BinaryCounterReading_create(NULL, INT32_MAX, 0, true, true, true);
bcr2 = BinaryCounterReading_create(NULL, INT32_MIN, 15, false, false, false);
it1 = IntegratedTotalsWithCP24Time2a_create(NULL, 101, bcr1, &cpTime1);
it2 = IntegratedTotalsWithCP24Time2a_create(NULL, 102, bcr2, &cpTime2);
BinaryCounterReading_destroy(bcr1);
BinaryCounterReading_destroy(bcr2);
TEST_ASSERT_EQUAL_INT32(INT32_MAX, BinaryCounterReading_getValue(IntegratedTotals_getBCR((IntegratedTotals)it1)));
TEST_ASSERT_EQUAL_UINT8(0, BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR((IntegratedTotals)it1)));
TEST_ASSERT_TRUE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR((IntegratedTotals)it1)));
TEST_ASSERT_TRUE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR((IntegratedTotals)it1)));
TEST_ASSERT_TRUE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR((IntegratedTotals)it1)));
TEST_ASSERT_EQUAL_INT32(INT32_MIN, BinaryCounterReading_getValue(IntegratedTotals_getBCR((IntegratedTotals)it2)));
TEST_ASSERT_EQUAL_UINT8(15, BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR((IntegratedTotals)it2)));
TEST_ASSERT_FALSE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR((IntegratedTotals)it2)));
TEST_ASSERT_FALSE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR((IntegratedTotals)it2)));
TEST_ASSERT_FALSE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR((IntegratedTotals)it2)));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)it1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)it2);
IntegratedTotalsWithCP24Time2a_destroy(it1);
IntegratedTotalsWithCP24Time2a_destroy(it2);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(28, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(2, CS101_ASDU_getNumberOfElements(asdu2));
IntegratedTotalsWithCP24Time2a it1_dec = (IntegratedTotalsWithCP24Time2a)CS101_ASDU_getElement(asdu2, 0);
IntegratedTotalsWithCP24Time2a it2_dec = (IntegratedTotalsWithCP24Time2a)CS101_ASDU_getElement(asdu2, 1);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)it1_dec));
TEST_ASSERT_EQUAL_INT32(INT32_MAX,
BinaryCounterReading_getValue(IntegratedTotals_getBCR((IntegratedTotals)it1_dec)));
TEST_ASSERT_EQUAL_UINT8(0,
BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR((IntegratedTotals)it1_dec)));
TEST_ASSERT_TRUE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR((IntegratedTotals)it1_dec)));
TEST_ASSERT_TRUE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR((IntegratedTotals)it1_dec)));
TEST_ASSERT_TRUE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR((IntegratedTotals)it1_dec)));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)it2_dec));
TEST_ASSERT_EQUAL_INT32(INT32_MIN,
BinaryCounterReading_getValue(IntegratedTotals_getBCR((IntegratedTotals)it2_dec)));
TEST_ASSERT_EQUAL_UINT8(15,
BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR((IntegratedTotals)it2_dec)));
TEST_ASSERT_FALSE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR((IntegratedTotals)it2_dec)));
TEST_ASSERT_FALSE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR((IntegratedTotals)it2_dec)));
TEST_ASSERT_FALSE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR((IntegratedTotals)it2_dec)));
CP24Time2a time1_dec = IntegratedTotalsWithCP24Time2a_getTimestamp(it1_dec);
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getMinute(time1_dec));
TEST_ASSERT_EQUAL_INT(24, CP24Time2a_getSecond(time1_dec));
TEST_ASSERT_EQUAL_INT(123, CP24Time2a_getMillisecond(time1_dec));
CP24Time2a time2_dec = IntegratedTotalsWithCP24Time2a_getTimestamp(it2_dec);
TEST_ASSERT_EQUAL_INT(54, CP24Time2a_getMinute(time2_dec));
TEST_ASSERT_EQUAL_INT(12, CP24Time2a_getSecond(time2_dec));
TEST_ASSERT_EQUAL_INT(345, CP24Time2a_getMillisecond(time2_dec));
IntegratedTotalsWithCP24Time2a_destroy(it1_dec);
IntegratedTotalsWithCP24Time2a_destroy(it2_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_IntegratedTotalsWithCP56Time2a(void)
{
IntegratedTotalsWithCP56Time2a it1;
IntegratedTotalsWithCP56Time2a it2;
BinaryCounterReading bcr1;
BinaryCounterReading bcr2;
uint64_t time1 = Hal_getTimeInMs();
uint64_t time2 = time1 + 1000;
struct sCP56Time2a cpTime1;
struct sCP56Time2a cpTime2;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
CP56Time2a_createFromMsTimestamp(&cpTime2, time2);
bcr1 = BinaryCounterReading_create(NULL, INT32_MAX, 0, true, true, true);
bcr2 = BinaryCounterReading_create(NULL, INT32_MIN, 15, false, false, false);
it1 = IntegratedTotalsWithCP56Time2a_create(NULL, 101, bcr1, &cpTime1);
it2 = IntegratedTotalsWithCP56Time2a_create(NULL, 102, bcr2, &cpTime2);
BinaryCounterReading_destroy(bcr1);
BinaryCounterReading_destroy(bcr2);
TEST_ASSERT_EQUAL_INT32(INT32_MAX, BinaryCounterReading_getValue(IntegratedTotals_getBCR((IntegratedTotals)it1)));
TEST_ASSERT_EQUAL_UINT8(0, BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR((IntegratedTotals)it1)));
TEST_ASSERT_TRUE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR((IntegratedTotals)it1)));
TEST_ASSERT_TRUE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR((IntegratedTotals)it1)));
TEST_ASSERT_TRUE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR((IntegratedTotals)it1)));
TEST_ASSERT_EQUAL_INT32(INT32_MIN, BinaryCounterReading_getValue(IntegratedTotals_getBCR((IntegratedTotals)it2)));
TEST_ASSERT_EQUAL_UINT8(15, BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR((IntegratedTotals)it2)));
TEST_ASSERT_FALSE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR((IntegratedTotals)it2)));
TEST_ASSERT_FALSE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR((IntegratedTotals)it2)));
TEST_ASSERT_FALSE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR((IntegratedTotals)it2)));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)it1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)it2);
IntegratedTotalsWithCP56Time2a_destroy(it1);
IntegratedTotalsWithCP56Time2a_destroy(it2);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(36, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(2, CS101_ASDU_getNumberOfElements(asdu2));
IntegratedTotalsWithCP56Time2a it1_dec = (IntegratedTotalsWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
IntegratedTotalsWithCP56Time2a it2_dec = (IntegratedTotalsWithCP56Time2a)CS101_ASDU_getElement(asdu2, 1);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)it1_dec));
TEST_ASSERT_EQUAL_INT32(INT32_MAX,
BinaryCounterReading_getValue(IntegratedTotals_getBCR((IntegratedTotals)it1_dec)));
TEST_ASSERT_EQUAL_UINT8(0,
BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR((IntegratedTotals)it1_dec)));
TEST_ASSERT_TRUE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR((IntegratedTotals)it1_dec)));
TEST_ASSERT_TRUE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR((IntegratedTotals)it1_dec)));
TEST_ASSERT_TRUE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR((IntegratedTotals)it1_dec)));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)it2_dec));
TEST_ASSERT_EQUAL_INT32(INT32_MIN,
BinaryCounterReading_getValue(IntegratedTotals_getBCR((IntegratedTotals)it2_dec)));
TEST_ASSERT_EQUAL_UINT8(15,
BinaryCounterReading_getSequenceNumber(IntegratedTotals_getBCR((IntegratedTotals)it2_dec)));
TEST_ASSERT_FALSE(BinaryCounterReading_hasCarry(IntegratedTotals_getBCR((IntegratedTotals)it2_dec)));
TEST_ASSERT_FALSE(BinaryCounterReading_isAdjusted(IntegratedTotals_getBCR((IntegratedTotals)it2_dec)));
TEST_ASSERT_FALSE(BinaryCounterReading_isInvalid(IntegratedTotals_getBCR((IntegratedTotals)it2_dec)));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(IntegratedTotalsWithCP56Time2a_getTimestamp(it1_dec)));
TEST_ASSERT_EQUAL_UINT64(time2, CP56Time2a_toMsTimestamp(IntegratedTotalsWithCP56Time2a_getTimestamp(it2_dec)));
IntegratedTotalsWithCP56Time2a_destroy(it1_dec);
IntegratedTotalsWithCP56Time2a_destroy(it2_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SingleCommand(void)
{
SingleCommand sc;
sc = SingleCommand_create(NULL, 101, true, true, 0);
TEST_ASSERT_TRUE(SingleCommand_getState(sc));
TEST_ASSERT_TRUE(SingleCommand_isSelect(sc));
TEST_ASSERT_EQUAL_INT(0, SingleCommand_getQU(sc));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)sc);
SingleCommand_destroy(sc);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(10, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
SingleCommand sc_dec = (SingleCommand)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)sc_dec));
TEST_ASSERT_TRUE(SingleCommand_getState(sc_dec));
TEST_ASSERT_TRUE(SingleCommand_isSelect(sc_dec));
TEST_ASSERT_EQUAL_INT(0, SingleCommand_getQU(sc_dec));
SingleCommand_destroy(sc_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SingleCommandWithCP56Time2a(void)
{
SingleCommandWithCP56Time2a sc;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
sc = SingleCommandWithCP56Time2a_create(NULL, 101, true, true, 0, &cpTime1);
TEST_ASSERT_TRUE(SingleCommand_getState((SingleCommand)sc));
TEST_ASSERT_TRUE(SingleCommand_isSelect((SingleCommand)sc));
TEST_ASSERT_EQUAL_INT(0, SingleCommand_getQU((SingleCommand)sc));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)sc);
SingleCommandWithCP56Time2a_destroy(sc);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(17, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
SingleCommandWithCP56Time2a sc_dec = (SingleCommandWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)sc_dec));
TEST_ASSERT_TRUE(SingleCommand_getState((SingleCommand)sc_dec));
TEST_ASSERT_TRUE(SingleCommand_isSelect((SingleCommand)sc_dec));
TEST_ASSERT_EQUAL_INT(0, SingleCommand_getQU((SingleCommand)sc_dec));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(SingleCommandWithCP56Time2a_getTimestamp(sc_dec)));
SingleCommandWithCP56Time2a_destroy(sc_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_DoubleCommand(void)
{
DoubleCommand dc;
dc = DoubleCommand_create(NULL, 101, 1, true, 0);
TEST_ASSERT_TRUE(DoubleCommand_isSelect(dc));
TEST_ASSERT_EQUAL_INT(1, DoubleCommand_getState(dc));
TEST_ASSERT_EQUAL_INT(0, DoubleCommand_getQU(dc));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dc);
DoubleCommand_destroy(dc);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(10, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
DoubleCommand dc_dec = (DoubleCommand)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)dc_dec));
TEST_ASSERT_TRUE(DoubleCommand_isSelect(dc_dec));
TEST_ASSERT_EQUAL_INT(1, DoubleCommand_getState(dc_dec));
TEST_ASSERT_EQUAL_INT(0, DoubleCommand_getQU(dc_dec));
DoubleCommand_destroy(dc_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_DoubleCommandWithCP56Time2a(void)
{
DoubleCommandWithCP56Time2a dc;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
dc = DoubleCommandWithCP56Time2a_create(NULL, 101, 1, true, 0, &cpTime1);
TEST_ASSERT_TRUE(DoubleCommandWithCP56Time2a_isSelect(dc));
TEST_ASSERT_EQUAL_INT(1, DoubleCommandWithCP56Time2a_getState(dc));
TEST_ASSERT_EQUAL_INT(0, DoubleCommandWithCP56Time2a_getQU(dc));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dc);
DoubleCommandWithCP56Time2a_destroy(dc);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(17, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
DoubleCommandWithCP56Time2a dc_dec = (DoubleCommandWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)dc_dec));
TEST_ASSERT_TRUE(DoubleCommandWithCP56Time2a_isSelect(dc_dec));
TEST_ASSERT_EQUAL_INT(1, DoubleCommandWithCP56Time2a_getState(dc_dec));
TEST_ASSERT_EQUAL_INT(0, DoubleCommandWithCP56Time2a_getQU(dc_dec));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(DoubleCommandWithCP56Time2a_getTimestamp(dc_dec)));
DoubleCommandWithCP56Time2a_destroy(dc_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_StepCommandValue(void)
{
StepCommand scv;
scv = StepCommand_create(NULL, 101, IEC60870_STEP_INVALID_0, true, 0);
TEST_ASSERT_TRUE(StepCommand_isSelect(scv));
TEST_ASSERT_EQUAL_INT(IEC60870_STEP_INVALID_0, StepCommand_getState(scv));
TEST_ASSERT_EQUAL_INT(0, StepCommand_getQU(scv));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)scv);
StepCommand_destroy(scv);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(10, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
StepCommand scv_dec = (StepCommand)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)scv_dec));
TEST_ASSERT_TRUE(StepCommand_isSelect(scv_dec));
TEST_ASSERT_EQUAL_INT(IEC60870_STEP_INVALID_0, StepCommand_getState(scv_dec));
TEST_ASSERT_EQUAL_INT(0, StepCommand_getQU(scv_dec));
StepCommand_destroy(scv_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_StepCommandWithCP56Time2a(void)
{
StepCommandWithCP56Time2a scv;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
scv = StepCommandWithCP56Time2a_create(NULL, 101, IEC60870_STEP_INVALID_0, true, 0, &cpTime1);
TEST_ASSERT_TRUE(StepCommandWithCP56Time2a_isSelect(scv));
TEST_ASSERT_EQUAL_INT(IEC60870_STEP_INVALID_0, StepCommandWithCP56Time2a_getState(scv));
TEST_ASSERT_EQUAL_INT(0, StepCommandWithCP56Time2a_getQU(scv));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)scv);
StepCommandWithCP56Time2a_destroy((StepCommandWithCP56Time2a)scv);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(17, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
StepCommandWithCP56Time2a scv_dec = (StepCommandWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)scv_dec));
TEST_ASSERT_TRUE(StepCommandWithCP56Time2a_isSelect(scv_dec));
TEST_ASSERT_EQUAL_INT(IEC60870_STEP_INVALID_0, StepCommandWithCP56Time2a_getState(scv_dec));
TEST_ASSERT_EQUAL_INT(0, StepCommandWithCP56Time2a_getQU(scv_dec));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(StepCommandWithCP56Time2a_getTimestamp(scv_dec)));
StepCommandWithCP56Time2a_destroy((StepCommandWithCP56Time2a)scv_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SetpointCommandNormalized(void)
{
SetpointCommandNormalized spcn;
spcn = SetpointCommandNormalized_create(NULL, 101, -1, true, 0);
TEST_ASSERT_EQUAL_INT(-1, SetpointCommandNormalized_getValue(spcn));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandNormalized_getQL(spcn));
TEST_ASSERT_TRUE(SetpointCommandNormalized_isSelect(spcn));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spcn);
SetpointCommandNormalized_destroy(spcn);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(12, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
SetpointCommandNormalized spcn_dec = (SetpointCommandNormalized)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spcn_dec));
TEST_ASSERT_EQUAL_INT(-1, SetpointCommandNormalized_getValue(spcn_dec));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandNormalized_getQL(spcn_dec));
TEST_ASSERT_TRUE(SetpointCommandNormalized_isSelect(spcn_dec));
SetpointCommandNormalized_destroy(spcn_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SetpointCommandNormalizedWithCP56Time2a(void)
{
SetpointCommandNormalizedWithCP56Time2a spcn;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
spcn = SetpointCommandNormalizedWithCP56Time2a_create(NULL, 101, 0, true, 0, &cpTime1);
TEST_ASSERT_EQUAL_INT(0, SetpointCommandNormalizedWithCP56Time2a_getValue(spcn));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandNormalizedWithCP56Time2a_getQL(spcn));
TEST_ASSERT_TRUE(SetpointCommandNormalizedWithCP56Time2a_isSelect(spcn));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spcn);
SetpointCommandNormalizedWithCP56Time2a_destroy(spcn);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(19, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
SetpointCommandNormalizedWithCP56Time2a spcn_dec =
(SetpointCommandNormalizedWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spcn_dec));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandNormalizedWithCP56Time2a_getValue(spcn_dec));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandNormalizedWithCP56Time2a_getQL(spcn_dec));
TEST_ASSERT_TRUE(SetpointCommandNormalizedWithCP56Time2a_isSelect(spcn_dec));
TEST_ASSERT_EQUAL_UINT64(time1,
CP56Time2a_toMsTimestamp(SetpointCommandNormalizedWithCP56Time2a_getTimestamp(spcn_dec)));
SetpointCommandNormalizedWithCP56Time2a_destroy(spcn_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SetpointCommandScaled(void)
{
SetpointCommandScaled spcs;
spcs = SetpointCommandScaled_create(NULL, 101, -32768, true, 0);
TEST_ASSERT_EQUAL_INT(-32768, SetpointCommandScaled_getValue(spcs));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandScaled_getQL(spcs));
TEST_ASSERT_TRUE(SetpointCommandScaled_isSelect(spcs));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spcs);
SetpointCommandScaled_destroy(spcs);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(12, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
SetpointCommandScaled spcs_dec = (SetpointCommandScaled)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spcs_dec));
TEST_ASSERT_EQUAL_INT(-32768, SetpointCommandScaled_getValue(spcs_dec));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandScaled_getQL(spcs_dec));
TEST_ASSERT_TRUE(SetpointCommandScaled_isSelect(spcs_dec));
SetpointCommandScaled_destroy(spcs_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SetpointCommandScaledWithCP56Time2a(void)
{
SetpointCommandScaledWithCP56Time2a spcs;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
spcs = SetpointCommandScaledWithCP56Time2a_create(NULL, 101, -32768, true, 0, &cpTime1);
TEST_ASSERT_EQUAL_INT(-32768, SetpointCommandScaledWithCP56Time2a_getValue(spcs));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandScaledWithCP56Time2a_getQL(spcs));
TEST_ASSERT_TRUE(SetpointCommandScaledWithCP56Time2a_isSelect(spcs));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spcs);
SetpointCommandScaledWithCP56Time2a_destroy(spcs);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(19, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
SetpointCommandScaledWithCP56Time2a spcs_dec = (SetpointCommandScaledWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spcs_dec));
TEST_ASSERT_EQUAL_INT(-32768, SetpointCommandScaledWithCP56Time2a_getValue(spcs_dec));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandScaledWithCP56Time2a_getQL(spcs_dec));
TEST_ASSERT_TRUE(SetpointCommandScaledWithCP56Time2a_isSelect(spcs_dec));
TEST_ASSERT_EQUAL_UINT64(time1,
CP56Time2a_toMsTimestamp(SetpointCommandScaledWithCP56Time2a_getTimestamp(spcs_dec)));
SetpointCommandScaledWithCP56Time2a_destroy(spcs_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SetpointCommandShort(void)
{
SetpointCommandShort spcs;
spcs = SetpointCommandShort_create(NULL, 101, 10.5f, true, 0);
TEST_ASSERT_EQUAL_FLOAT(10.5f, SetpointCommandShort_getValue(spcs));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandShort_getQL(spcs));
TEST_ASSERT_TRUE(SetpointCommandShort_isSelect(spcs));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spcs);
SetpointCommandShort_destroy(spcs);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(14, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
SetpointCommandShort spcs_dec = (SetpointCommandShort)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spcs_dec));
TEST_ASSERT_EQUAL_FLOAT(10.5f, SetpointCommandShort_getValue(spcs_dec));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandShort_getQL(spcs_dec));
TEST_ASSERT_TRUE(SetpointCommandShort_isSelect(spcs_dec));
SetpointCommandShort_destroy(spcs_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_SetpointCommandShortWithCP56Time2a(void)
{
SetpointCommandShortWithCP56Time2a spcs;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
spcs = SetpointCommandShortWithCP56Time2a_create(NULL, 101, 10.5f, true, 0, &cpTime1);
TEST_ASSERT_EQUAL_FLOAT(10.5f, SetpointCommandShortWithCP56Time2a_getValue(spcs));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandShortWithCP56Time2a_getQL(spcs));
TEST_ASSERT_TRUE(SetpointCommandShortWithCP56Time2a_isSelect(spcs));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)spcs);
SetpointCommandShortWithCP56Time2a_destroy(spcs);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(21, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
SetpointCommandShortWithCP56Time2a spcs_dec = (SetpointCommandShortWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)spcs_dec));
TEST_ASSERT_EQUAL_FLOAT(10.5f, SetpointCommandShortWithCP56Time2a_getValue(spcs_dec));
TEST_ASSERT_EQUAL_INT(0, SetpointCommandShortWithCP56Time2a_getQL(spcs_dec));
TEST_ASSERT_TRUE(SetpointCommandShortWithCP56Time2a_isSelect(spcs_dec));
TEST_ASSERT_EQUAL_UINT64(time1,
CP56Time2a_toMsTimestamp(SetpointCommandShortWithCP56Time2a_getTimestamp(spcs_dec)));
SetpointCommandShortWithCP56Time2a_destroy(spcs_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_InterrogationCommand(void)
{
InterrogationCommand ic;
uint8_t qoi = 21;
ic = InterrogationCommand_create(NULL, 101, qoi);
TEST_ASSERT_EQUAL_INT(21, InterrogationCommand_getQOI(ic));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)ic);
InterrogationCommand_destroy(ic);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(10, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
InterrogationCommand ic_dec = (InterrogationCommand)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)ic_dec));
TEST_ASSERT_EQUAL_INT(21, InterrogationCommand_getQOI(ic_dec));
InterrogationCommand_destroy(ic_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_CounterInterrogationCommand(void)
{
CounterInterrogationCommand cic;
uint8_t qcc = 1;
cic = CounterInterrogationCommand_create(NULL, 101, qcc);
TEST_ASSERT_EQUAL_INT(1, CounterInterrogationCommand_getQCC(cic));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)cic);
CounterInterrogationCommand_destroy(cic);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(10, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
CounterInterrogationCommand cic_dec = (CounterInterrogationCommand)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)cic_dec));
TEST_ASSERT_EQUAL_INT(1, CounterInterrogationCommand_getQCC(cic_dec));
CounterInterrogationCommand_destroy(cic_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_ReadCommand(void)
{
ReadCommand rc;
rc = ReadCommand_create(NULL, 101);
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)rc);
ReadCommand_destroy(rc);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(9, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
ReadCommand rc_dec = (ReadCommand)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)rc_dec));
ReadCommand_destroy(rc_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_ClockSynchronizationCommand(void)
{
ClockSynchronizationCommand csc;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
csc = ClockSynchronizationCommand_create(NULL, 101, &cpTime1);
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)csc);
ClockSynchronizationCommand_destroy(csc);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(16, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
ClockSynchronizationCommand csc_dec = (ClockSynchronizationCommand)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)csc_dec));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(ClockSynchronizationCommand_getTime(csc_dec)));
ClockSynchronizationCommand_destroy(csc_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_ResetProcessCommand(void)
{
ResetProcessCommand rpc;
uint8_t qrp = 0;
rpc = ResetProcessCommand_create(NULL, 101, qrp);
TEST_ASSERT_EQUAL_INT(0, ResetProcessCommand_getQRP(rpc));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)rpc);
ResetProcessCommand_destroy(rpc);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(10, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
ResetProcessCommand rpc_dec = (ResetProcessCommand)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)rpc_dec));
TEST_ASSERT_EQUAL_INT(0, ResetProcessCommand_getQRP(rpc_dec));
ResetProcessCommand_destroy(rpc_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_DelayAcquisitionCommand(void)
{
DelayAcquisitionCommand dac;
uint64_t time1 = Hal_getTimeInMs();
struct sCP16Time2a delay;
bzero(&delay, sizeof(struct sCP16Time2a));
CP16Time2a_setEplapsedTimeInMs(&delay, 24123);
dac = DelayAcquisitionCommand_create(NULL, 101, &delay);
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dac);
DelayAcquisitionCommand_destroy(dac);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(11, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
DelayAcquisitionCommand dac_dec = (DelayAcquisitionCommand)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)dac_dec));
CP16Time2a time1_dec = DelayAcquisitionCommand_getDelay(dac_dec);
TEST_ASSERT_EQUAL_INT(24123, CP16Time2a_getEplapsedTimeInMs(time1_dec));
DelayAcquisitionCommand_destroy(dac_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_TestCommand(void)
{
TestCommand tc;
tc = TestCommand_create(NULL);
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)tc);
TestCommand_destroy(tc);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(11, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
TestCommand tc_dec = (TestCommand)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(0, InformationObject_getObjectAddress((InformationObject)tc_dec));
TEST_ASSERT_EQUAL_INT(0xaa, buffer[9]);
TEST_ASSERT_EQUAL_INT(0x55, buffer[10]);
TEST_ASSERT_TRUE(TestCommand_isValid(tc_dec));
TestCommand_destroy(tc_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_TestCommandWithTime(void)
{
TestCommandWithCP56Time2a tc;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
tc = TestCommandWithCP56Time2a_create(NULL, 0xaa55, &cpTime1);
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)tc);
TestCommandWithCP56Time2a_destroy(tc);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(18, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
TestCommandWithCP56Time2a tc_dec = (TestCommandWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(0, InformationObject_getObjectAddress((InformationObject)tc_dec));
TEST_ASSERT_EQUAL_INT(0xaa55, TestCommandWithCP56Time2a_getCounter(tc_dec));
TestCommandWithCP56Time2a_destroy(tc_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_BitString32(void)
{
BitString32 bs32;
bs32 = BitString32_createEx(NULL, 101, 0xaaaa, IEC60870_QUALITY_INVALID);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, BitString32_getQuality(bs32));
BitString32_destroy(bs32);
bs32 = BitString32_create(NULL, 101, 0xaaaa);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, BitString32_getQuality(bs32));
BitString32_destroy(bs32);
bs32 = BitString32_createEx(NULL, 101, 0xaaaa, IEC60870_QUALITY_INVALID | IEC60870_QUALITY_NON_TOPICAL);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID + IEC60870_QUALITY_NON_TOPICAL, BitString32_getQuality(bs32));
TEST_ASSERT_EQUAL_UINT32(0xaaaa, BitString32_getValue(bs32));
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)bs32));
BitString32_destroy(bs32);
Bitstring32WithCP24Time2a bs32cp24;
struct sCP24Time2a cp24;
bs32cp24 = Bitstring32WithCP24Time2a_createEx(NULL, 100002, 0xbbbb, IEC60870_QUALITY_INVALID, &cp24);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID, BitString32_getQuality((BitString32)bs32cp24));
TEST_ASSERT_EQUAL_UINT32(0xbbbb, BitString32_getValue((BitString32)bs32cp24));
TEST_ASSERT_EQUAL_INT(100002, InformationObject_getObjectAddress((InformationObject)bs32cp24));
Bitstring32WithCP24Time2a_destroy(bs32cp24);
bs32cp24 = Bitstring32WithCP24Time2a_create(NULL, 100002, 0xbbbb, &cp24);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, BitString32_getQuality((BitString32)bs32cp24));
TEST_ASSERT_EQUAL_UINT32(0xbbbb, BitString32_getValue((BitString32)bs32cp24));
TEST_ASSERT_EQUAL_INT(100002, InformationObject_getObjectAddress((InformationObject)bs32cp24));
Bitstring32WithCP24Time2a_destroy(bs32cp24);
Bitstring32WithCP56Time2a bs32cp56;
struct sCP56Time2a cp56;
bs32cp56 = Bitstring32WithCP56Time2a_createEx(NULL, 1000002, 0xcccc,
IEC60870_QUALITY_INVALID | IEC60870_QUALITY_NON_TOPICAL, &cp56);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_INVALID + IEC60870_QUALITY_NON_TOPICAL,
BitString32_getQuality((BitString32)bs32cp56));
TEST_ASSERT_EQUAL_UINT32(0xcccc, BitString32_getValue((BitString32)bs32cp56));
TEST_ASSERT_EQUAL_INT(1000002, InformationObject_getObjectAddress((InformationObject)bs32cp56));
Bitstring32WithCP56Time2a_destroy(bs32cp56);
bs32cp56 = Bitstring32WithCP56Time2a_create(NULL, 1000002, 0xcccc, &cp56);
TEST_ASSERT_EQUAL_UINT8(IEC60870_QUALITY_GOOD, BitString32_getQuality((BitString32)bs32cp56));
TEST_ASSERT_EQUAL_UINT32(0xcccc, BitString32_getValue((BitString32)bs32cp56));
TEST_ASSERT_EQUAL_INT(1000002, InformationObject_getObjectAddress((InformationObject)bs32cp56));
Bitstring32WithCP56Time2a_destroy(bs32cp56);
}
void
test_Bitstring32CommandWithCP56Time2a(void)
{
Bitstring32CommandWithCP56Time2a bsc;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
bsc = Bitstring32CommandWithCP56Time2a_create(NULL, 101, (uint32_t)0x0000000000, &cpTime1);
TEST_ASSERT_EQUAL_UINT32(0x0000000000, Bitstring32CommandWithCP56Time2a_getValue(bsc));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)bsc);
Bitstring32CommandWithCP56Time2a_destroy(bsc);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(20, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
Bitstring32CommandWithCP56Time2a bsc_dec = (Bitstring32CommandWithCP56Time2a)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)bsc_dec));
TEST_ASSERT_EQUAL_UINT64(time1, CP56Time2a_toMsTimestamp(Bitstring32CommandWithCP56Time2a_getTimestamp(bsc_dec)));
TEST_ASSERT_EQUAL_UINT32(0x0000000000, Bitstring32CommandWithCP56Time2a_getValue(bsc_dec));
Bitstring32CommandWithCP56Time2a_destroy(bsc_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_QueryLog(void)
{
QueryLog queryLog;
uint64_t stopTime = Hal_getTimeInMs();
uint64_t startTime = stopTime - 2000;
struct sCP56Time2a rangeStartTime;
struct sCP56Time2a rangeStopTime;
CP56Time2a_createFromMsTimestamp(&rangeStartTime, startTime);
CP56Time2a_createFromMsTimestamp(&rangeStopTime, stopTime);
queryLog = QueryLog_create(NULL, 101, 256, &rangeStartTime, &rangeStopTime);
TEST_ASSERT_EQUAL_UINT16(256, QueryLog_getNOF(queryLog));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)queryLog);
QueryLog_destroy(queryLog);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(25, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
QueryLog queryLog_dec = (QueryLog)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_NOT_NULL(queryLog_dec);
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)queryLog_dec));
TEST_ASSERT_EQUAL_UINT16(256, QueryLog_getNOF(queryLog_dec));
TEST_ASSERT_EQUAL_UINT64(startTime, CP56Time2a_toMsTimestamp(QueryLog_getRangeStartTime(queryLog_dec)));
TEST_ASSERT_EQUAL_UINT64(stopTime, CP56Time2a_toMsTimestamp(QueryLog_getRangeStopTime(queryLog_dec)));
QueryLog_destroy(queryLog_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_FileDirectory(void)
{
FileDirectory fd1;
FileDirectory fd2;
FileDirectory fd3;
struct sCP56Time2a fileCreationTime;
uint64_t timeval = Hal_getTimeInMs();
CP56Time2a_createFromMsTimestamp(&fileCreationTime, timeval);
fd1 = FileDirectory_create(NULL, 100, 1, 1024, 0, &fileCreationTime);
fd2 = FileDirectory_create(NULL, 101, 2, 2048, 1, &fileCreationTime);
fd3 = FileDirectory_create(NULL, 102, 60001, 4444, 2, &fileCreationTime);
TEST_ASSERT_NOT_NULL(fd1);
TEST_ASSERT_NOT_NULL(fd2);
TEST_ASSERT_NOT_NULL(fd3);
TEST_ASSERT_EQUAL_UINT32(1024, FileDirectory_getLengthOfFile(fd1));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
/* NOTE: file directory is always a "sequence" */
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, true, CS101_COT_SPONTANEOUS, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)fd1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)fd2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)fd3);
FileDirectory_destroy(fd1);
FileDirectory_destroy(fd2);
FileDirectory_destroy(fd3);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(48, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(3, CS101_ASDU_getNumberOfElements(asdu2));
FileDirectory fd1_dec = (FileDirectory)CS101_ASDU_getElement(asdu2, 0);
FileDirectory fd2_dec = (FileDirectory)CS101_ASDU_getElement(asdu2, 1);
FileDirectory fd3_dec = (FileDirectory)CS101_ASDU_getElement(asdu2, 2);
TEST_ASSERT_NOT_NULL(fd1_dec);
TEST_ASSERT_NOT_NULL(fd2_dec);
TEST_ASSERT_NOT_NULL(fd3_dec);
TEST_ASSERT_EQUAL_UINT32(1024, FileDirectory_getLengthOfFile(fd1_dec));
TEST_ASSERT_EQUAL_UINT32(2048, FileDirectory_getLengthOfFile(fd2_dec));
TEST_ASSERT_EQUAL_UINT32(4444, FileDirectory_getLengthOfFile(fd3_dec));
TEST_ASSERT_EQUAL_INT(100, InformationObject_getObjectAddress((InformationObject)fd1_dec));
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)fd2_dec));
TEST_ASSERT_EQUAL_INT(102, InformationObject_getObjectAddress((InformationObject)fd3_dec));
TEST_ASSERT_EQUAL_UINT8(0, FileDirectory_getSOF(fd1_dec));
TEST_ASSERT_EQUAL_UINT8(1, FileDirectory_getSOF(fd2_dec));
TEST_ASSERT_EQUAL_UINT8(2, FileDirectory_getSOF(fd3_dec));
TEST_ASSERT_EQUAL_UINT16(1, FileDirectory_getNOF(fd1_dec));
TEST_ASSERT_EQUAL_UINT16(2, FileDirectory_getNOF(fd2_dec));
TEST_ASSERT_EQUAL_UINT16(60001, FileDirectory_getNOF(fd3_dec));
FileDirectory_destroy(fd1_dec);
FileDirectory_destroy(fd2_dec);
FileDirectory_destroy(fd3_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_FileDirectorySingleEntry(void)
{
FileDirectory fd1;
struct sCP56Time2a fileCreationTime;
uint64_t timeval = Hal_getTimeInMs();
CP56Time2a_createFromMsTimestamp(&fileCreationTime, timeval);
fd1 = FileDirectory_create(NULL, 101, 1, 1024, 0, &fileCreationTime);
TEST_ASSERT_NOT_NULL(fd1);
TEST_ASSERT_EQUAL_UINT32(1024, FileDirectory_getLengthOfFile(fd1));
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
/* NOTE: file directory is always a "sequence" */
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, true, CS101_COT_SPONTANEOUS, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)fd1);
FileDirectory_destroy(fd1);
CS101_ASDU_encode(asdu, f);
TEST_ASSERT_EQUAL_INT(22, Frame_getMsgSize(f));
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
TEST_ASSERT_EQUAL_INT(1, CS101_ASDU_getNumberOfElements(asdu2));
FileDirectory fd1_dec = (FileDirectory)CS101_ASDU_getElement(asdu2, 0);
TEST_ASSERT_NOT_NULL(fd1_dec);
TEST_ASSERT_EQUAL_UINT32(1024, FileDirectory_getLengthOfFile(fd1_dec));
TEST_ASSERT_EQUAL_INT(101, InformationObject_getObjectAddress((InformationObject)fd1_dec));
TEST_ASSERT_EQUAL_UINT8(0, FileDirectory_getSOF(fd1_dec));
TEST_ASSERT_EQUAL_UINT16(1, FileDirectory_getNOF(fd1_dec));
FileDirectory_destroy(fd1_dec);
CS101_ASDU_destroy(asdu2);
}
void
test_BitString32xx_encodeDecode(void)
{
#ifndef _WIN32
uint8_t buffer[256];
struct sBufferFrame bf;
Frame f = BufferFrame_initialize(&bf, buffer, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
BitString32 bs32_1 = BitString32_createEx(NULL, 101, (uint32_t)0xaaaaaaaaaa, IEC60870_QUALITY_INVALID);
BitString32 bs32_2 = BitString32_create(NULL, 102, (uint32_t)0x0000000000);
BitString32 bs32_3 = BitString32_create(NULL, 103, (uint32_t)0xffffffffffUL);
CS101_ASDU_addInformationObject(asdu, (InformationObject)bs32_1);
CS101_ASDU_addInformationObject(asdu, (InformationObject)bs32_2);
CS101_ASDU_addInformationObject(asdu, (InformationObject)bs32_3);
CS101_ASDU_encode(asdu, f);
InformationObject_destroy((InformationObject)bs32_1);
InformationObject_destroy((InformationObject)bs32_2);
InformationObject_destroy((InformationObject)bs32_3);
CS101_ASDU_destroy(asdu);
CS101_ASDU asdu2 = CS101_ASDU_createFromBuffer(&defaultAppLayerParameters, buffer, Frame_getMsgSize(f));
BitString32 bs32_1_dec = (BitString32)CS101_ASDU_getElement(asdu2, 0);
BitString32 bs32_2_dec = (BitString32)CS101_ASDU_getElement(asdu2, 1);
BitString32 bs32_3_dec = (BitString32)CS101_ASDU_getElement(asdu2, 2);
TEST_ASSERT_EQUAL_UINT32(0xaaaaaaaaaaUL, BitString32_getValue(bs32_1_dec));
TEST_ASSERT_EQUAL_INT(IEC60870_QUALITY_INVALID, BitString32_getQuality(bs32_1_dec));
TEST_ASSERT_EQUAL_UINT32(0x0000000000UL, BitString32_getValue(bs32_2_dec));
TEST_ASSERT_EQUAL_INT(IEC60870_QUALITY_GOOD, BitString32_getQuality(bs32_2_dec));
TEST_ASSERT_EQUAL_UINT32(0xffffffffUL, BitString32_getValue(bs32_3_dec));
TEST_ASSERT_EQUAL_INT(IEC60870_QUALITY_GOOD, BitString32_getQuality(bs32_3_dec));
InformationObject_destroy((InformationObject)bs32_1_dec);
InformationObject_destroy((InformationObject)bs32_2_dec);
InformationObject_destroy((InformationObject)bs32_3_dec);
CS101_ASDU_destroy(asdu2);
#endif
}
void
test_version_number(void)
{
Lib60870VersionInfo version = Lib60870_getLibraryVersionInfo();
TEST_ASSERT_EQUAL_INT(2, version.major);
TEST_ASSERT_EQUAL_INT(4, version.minor);
TEST_ASSERT_EQUAL_INT(0, version.patch);
}
void
test_CS104_Slave_CreateDestroy(void)
{
CS104_Slave slave = CS104_Slave_create(100, 100);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_destroy(slave);
}
void
test_CS104_Connection_CreateDestroy(void)
{
CS104_Connection con = CS104_Connection_create("127.0.0.1", 2404);
TEST_ASSERT_NOT_NULL(con);
CS104_Connection_destroy(con);
}
void
test_CS104_MasterSlave_CreateDestroy(void)
{
CS104_Slave slave = CS104_Slave_create(100, 100);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
TEST_ASSERT_NOT_NULL(con);
CS104_Connection_connect(con);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
}
void
test_CS104_MasterSlave_CreateDestroyLoop(void)
{
CS104_Slave slave = NULL;
CS104_Connection con = NULL;
for (int i = 0; i < 1000; i++)
{
slave = CS104_Slave_create(100, 100);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
con = CS104_Connection_create("127.0.0.1", 20004);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
}
}
void
test_CS104_Connection_ConnectTimeout(void)
{
CS104_Connection con = CS104_Connection_create("192.168.3.120", 2404);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Connection_destroy(con);
}
void
test_CS104_Connection_UseAfterClose(void)
{
CS104_Slave slave = NULL;
CS104_Connection con = NULL;
slave = CS104_Slave_create(100, 100);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
con = CS104_Connection_create("127.0.0.1", 20004);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_close(con);
result = CS104_Connection_sendInterrogationCommand(con, CS101_COT_ACTIVATION, 1, IEC60870_QOI_STATION);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
}
void
test_CS104_Connection_UseAfterServerClosedConnection(void)
{
CS104_Slave slave = NULL;
CS104_Connection con = NULL;
slave = CS104_Slave_create(100, 100);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
con = CS104_Connection_create("127.0.0.1", 20004);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Slave_destroy(slave);
/* wait to allow client side to detect connection loss */
Thread_sleep(500);
result = CS104_Connection_sendInterrogationCommand(con, CS101_COT_ACTIVATION, 1, IEC60870_QOI_STATION);
TEST_ASSERT_FALSE(result);
CS104_Connection_destroy(con);
}
static CS104_ConnectionEvent test_CS104_Connection_async_timeout_event;
static void
test_CS104_Connection_async_timeout_connectionHandler(void* parameter, CS104_Connection connection,
CS104_ConnectionEvent event)
{
test_CS104_Connection_async_timeout_event = event;
}
void
test_CS104_Connection_async_success(void)
{
test_CS104_Connection_async_timeout_event = CS104_CONNECTION_CLOSED;
CS104_Slave slave = NULL;
CS104_Connection con = NULL;
slave = CS104_Slave_create(100, 100);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
con = CS104_Connection_create("127.0.0.1", 20004);
TEST_ASSERT_NOT_NULL(con);
CS104_APCIParameters apciParameters = CS104_Connection_getAPCIParameters(con);
apciParameters->t0 = 1;
CS104_Connection_setConnectionHandler(con, test_CS104_Connection_async_timeout_connectionHandler, NULL);
CS104_Connection_connectAsync(con);
Thread_sleep(500);
TEST_ASSERT_EQUAL_INT(CS104_CONNECTION_OPENED, test_CS104_Connection_async_timeout_event);
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
void
test_CS104_Connection_async_timeout(void)
{
test_CS104_Connection_async_timeout_event = CS104_CONNECTION_CLOSED;
CS104_Connection con = CS104_Connection_create("192.168.3.120", 2404);
TEST_ASSERT_NOT_NULL(con);
CS104_APCIParameters apciParameters = CS104_Connection_getAPCIParameters(con);
apciParameters->t0 = 1;
CS104_Connection_setConnectionHandler(con, test_CS104_Connection_async_timeout_connectionHandler, NULL);
CS104_Connection_connectAsync(con);
Thread_sleep(2000);
TEST_ASSERT_EQUAL_INT(CS104_CONNECTION_FAILED, test_CS104_Connection_async_timeout_event);
CS104_Connection_destroy(con);
}
void
test_CS101_ASDU_addObjectOfWrongType(void)
{
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
InformationObject io1 = (InformationObject)SinglePointInformation_create(NULL, 101, true, IEC60870_QUALITY_GOOD);
bool added = CS101_ASDU_addInformationObject(asdu, io1);
TEST_ASSERT_TRUE(added);
InformationObject_destroy(io1);
InformationObject io2 =
(InformationObject)DoublePointInformation_create(NULL, 102, IEC60870_DOUBLE_POINT_OFF, IEC60870_QUALITY_GOOD);
added = CS101_ASDU_addInformationObject(asdu, io2);
TEST_ASSERT_FALSE(added);
InformationObject_destroy(io2);
CS101_ASDU_destroy(asdu);
}
void
test_CS101_ASDU_addUntilOverflow(void)
{
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
int i = 0;
for (i = 0; i < 60; i++)
{
InformationObject io =
(InformationObject)SinglePointInformation_create(NULL, 100 + i, true, IEC60870_QUALITY_GOOD);
bool added = CS101_ASDU_addInformationObject(asdu, io);
TEST_ASSERT_TRUE(added);
InformationObject_destroy(io);
TEST_ASSERT_EQUAL_INT(i + 1, CS101_ASDU_getNumberOfElements(asdu));
}
InformationObject io = (InformationObject)SinglePointInformation_create(NULL, 100 + i, true, IEC60870_QUALITY_GOOD);
bool added = CS101_ASDU_addInformationObject(asdu, io);
TEST_ASSERT_FALSE(added);
InformationObject_destroy(io);
CS101_ASDU_destroy(asdu);
}
void
test_CS101_ASDU_clone(void)
{
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_PERIODIC, 0, 1, false, false);
int i = 0;
for (i = 0; i < 60; i++)
{
InformationObject io =
(InformationObject)SinglePointInformation_create(NULL, 100 + i, true, IEC60870_QUALITY_GOOD);
bool added = CS101_ASDU_addInformationObject(asdu, io);
TEST_ASSERT_TRUE(added);
InformationObject_destroy(io);
TEST_ASSERT_EQUAL_INT(i + 1, CS101_ASDU_getNumberOfElements(asdu));
}
CS101_ASDU clonedAsdu = CS101_ASDU_clone(asdu, NULL);
TEST_ASSERT_NOT_NULL(clonedAsdu);
TEST_ASSERT_EQUAL_INT(CS101_ASDU_getCA(asdu), CS101_ASDU_getCA(clonedAsdu));
TEST_ASSERT_EQUAL_INT(CS101_ASDU_getOA(asdu), CS101_ASDU_getOA(clonedAsdu));
TEST_ASSERT_EQUAL_INT(CS101_ASDU_getCOT(asdu), CS101_ASDU_getCOT(clonedAsdu));
TEST_ASSERT_EQUAL_INT(CS101_ASDU_getTypeID(asdu), CS101_ASDU_getTypeID(clonedAsdu));
TEST_ASSERT_EQUAL_INT(CS101_ASDU_getNumberOfElements(asdu), CS101_ASDU_getNumberOfElements(clonedAsdu));
TEST_ASSERT_EQUAL_INT(CS101_ASDU_getPayloadSize(asdu), CS101_ASDU_getPayloadSize(clonedAsdu));
TEST_ASSERT_EQUAL_INT(0, memcmp(CS101_ASDU_getPayload(asdu), CS101_ASDU_getPayload(clonedAsdu),
CS101_ASDU_getPayloadSize(clonedAsdu)));
CS101_ASDU_destroy(asdu);
CS101_ASDU_destroy(clonedAsdu);
}
#if (CONFIG_CS104_SUPPORT_TLS == 1)
struct secEventInfo
{
int eventHandlerCalled;
int eventCodes[100];
};
static void
securityEventHandler(void* parameter, TLSEventLevel eventLevel, int eventCode, const char* msg, TLSConnection con)
{
struct secEventInfo* eventInfo = (struct secEventInfo*)parameter;
char peerAddrBuf[60];
char* peerAddr = NULL;
const char* tlsVersion = "unknown";
if (con)
{
peerAddr = TLSConnection_getPeerAddress(con, peerAddrBuf);
tlsVersion = TLSConfigVersion_toString(TLSConnection_getTLSVersion(con));
}
printf("[SECURITY EVENT] %s (t: %i, c: %i, version: %s remote-ip: %s)\n", msg, eventLevel, eventCode, tlsVersion,
peerAddr);
if (eventInfo)
{
/* Bounds check to prevent buffer overflow */
if (eventInfo->eventHandlerCalled < 100)
{
eventInfo->eventCodes[eventInfo->eventHandlerCalled] = eventCode;
eventInfo->eventHandlerCalled++;
}
}
}
void
test_CS104_MasterSlave_TLSConnectSuccess(void)
{
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, NULL);
TLSConfiguration_setChainValidation(tlsConfig1, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig2, true);
/* use valid certificate */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addAllowedCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
}
void
test_CS104_MasterSlave_TLSConnectSuccessWithoutSeparateCACert(void)
{
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, NULL);
TLSConfiguration_setChainValidation(tlsConfig1, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1_chain.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "server_CA1_1_chain.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig2, true);
/* use expired certificate */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addAllowedCertificateFromFile(tlsConfig2, "server_CA1_1_chain.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
}
void
test_CS104_MasterSlave_TLSConnectFails(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig2, true);
/* use valid certificate */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addAllowedCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
TEST_ASSERT_EQUAL_INT(1, eventInfo.eventHandlerCalled);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_ALGO_NOT_SUPPORTED, eventInfo.eventCodes[0]);
}
#ifndef WITH_MBEDTLS3
void
test_CS104_MasterSlave_TLSVersionMismatch(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setMinTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
TLSConfiguration_setChainValidation(tlsConfig1, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig2, true);
TLSConfiguration_setMinTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_1);
TLSConfiguration_setMaxTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_1);
/* use valid certificate */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addAllowedCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
TEST_ASSERT_EQUAL_INT(1, eventInfo.eventHandlerCalled);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_UNSECURE_COMMUNICATION, eventInfo.eventCodes[0]);
}
#endif
#ifdef WITH_MBEDTLS3
void
test_CS104_MasterSlave_TLSVersionMismatch_mbedtls3(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setMinTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_3);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
TLSConfiguration_setChainValidation(tlsConfig1, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig2, true);
TLSConfiguration_setMinTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_2);
TLSConfiguration_setMaxTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_2);
/* use valid certificate */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addAllowedCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
TEST_ASSERT_EQUAL_INT(1, eventInfo.eventHandlerCalled);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_UNSECURE_COMMUNICATION, eventInfo.eventCodes[0]);
}
#endif
void
test_CS104_MasterSlave_TLSCipherSuiteMismatch(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration - restrict to specific cipher suites */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
TLSConfiguration_setChainValidation(tlsConfig1, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
/* Restrict server to only TLS_RSA_WITH_AES_128_GCM_SHA256 */
TLSConfiguration_clearCipherSuiteList(tlsConfig1);
TLSConfiguration_addCipherSuite(tlsConfig1, TLS_RSA_WITH_AES_128_GCM_SHA256);
/* Client configuration - restrict to different cipher suite */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setMaxTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_2);
TLSConfiguration_setChainValidation(tlsConfig2, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig2, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addAllowedCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
/* Restrict client to only TLS_RSA_WITH_AES_256_GCM_SHA384 - no overlap with server */
TLSConfiguration_clearCipherSuiteList(tlsConfig2);
TLSConfiguration_addCipherSuite(tlsConfig2, TLS_RSA_WITH_AES_256_GCM_SHA384);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
Thread_sleep(200); /* Give time for security event to be generated */
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
TEST_ASSERT_EQUAL_INT(1, eventInfo.eventHandlerCalled);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_NO_CIPHER, eventInfo.eventCodes[0]);
}
void
test_CS104_MasterSlave_TLSCipherSuiteMismatch_TLS_PSK_WITH_AES_256_GCM_SHA384(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration - restrict to specific cipher suites */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
TLSConfiguration_setChainValidation(tlsConfig1, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
/* Restrict server to only TLS_RSA_WITH_AES_128_GCM_SHA256 */
TLSConfiguration_clearCipherSuiteList(tlsConfig1);
TLSConfiguration_addCipherSuite(tlsConfig1, TLS_RSA_WITH_AES_128_GCM_SHA256);
/* Client configuration - restrict to different cipher suite */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig2, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addAllowedCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
/* Restrict client to only TLS_RSA_WITH_AES_256_GCM_SHA384 - no overlap with server */
TLSConfiguration_clearCipherSuiteList(tlsConfig2);
TLSConfiguration_addCipherSuite(tlsConfig2, TLS_PSK_WITH_AES_256_GCM_SHA384);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
Thread_sleep(200); /* Give time for security event to be generated */
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
TEST_ASSERT_EQUAL_INT(1, eventInfo.eventHandlerCalled);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_NO_CIPHER, eventInfo.eventCodes[0]);
}
void
test_CS104_MasterSlave_TLSClientCertificateNotProvided(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration - requires client certificate */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
TLSConfiguration_setChainValidation(tlsConfig1, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
/* Client configuration - NO certificate provided */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig2, true);
/* Do NOT set client certificate - client will connect without certificate */
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addAllowedCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
Thread_sleep(200); /* Give time for security event to be generated */
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify that certificate unavailable alarm was raised */
bool certUnavailableDetected = false;
for (int i = 0; i < eventInfo.eventHandlerCalled; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CERT_UNAVAILABLE) {
certUnavailableDetected = true;
break;
}
}
TEST_ASSERT_TRUE(certUnavailableDetected);
}
void
test_CS104_MasterSlave_TLSVersionChangeDetected(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration - supports both TLS 1.1 and TLS 1.2 */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
/* Allow both TLS 1.1 and 1.2 on server */
TLSConfiguration_setMinTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_1);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
/* Client configuration with session resumption enabled */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
//TLSConfiguration_setEventHandler(tlsConfig2, securityEventHandler, &eventInfo);
TLSConfiguration_enableSessionResumption(tlsConfig2, true);
TLSConfiguration_setSessionResumptionInterval(tlsConfig2, 60); /* 60 seconds */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
/* First connection with TLS 1.2 */
TLSConfiguration_setMinTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_2);
TLSConfiguration_setMaxTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_2);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* First connection should succeed with TLS 1.2 */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
Thread_sleep(200); /* Allow events to be processed */
CS104_Connection_close(con);
Thread_sleep(200); /* Allow cleanup */
/* Now change client to use TLS 1.1 and reconnect - session resumption should detect version change */
TLSConfiguration_setMinTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_1);
TLSConfiguration_setMaxTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_1);
printf("Reconnect with TLS 1.1....\n");
/* Second connection attempt with TLS 1.1 - should detect version change */
result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result); /* Connection fails and version change is detected */
Thread_sleep(200); /* Give time for security event to be generated */
CS104_Connection_close(con);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify that TLS version change alarm was raised */
bool versionChangeDetected = false;
for (int i = 0; i < eventInfo.eventHandlerCalled; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_TLS_VERSION_CHANGE) {
versionChangeDetected = true;
break;
}
}
TEST_ASSERT_TRUE(versionChangeDetected);
}
void
test_CS104_MasterSlave_TLSCertificateSizeExceeded(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* This test verifies that the TLS_EVENT_CODE_ALM_CERT_SIZE_EXCEEDED event is raised
* when a certificate exceeds the maximum TLS record size (16384 bytes).
*
* Note: In the TLS protocol and mbedTLS implementation, certificate size validation
* occurs on the SENDING side before transmission. When an endpoint attempts to send
* a certificate that exceeds MBEDTLS_SSL_OUT_CONTENT_LEN (16384 bytes), it detects
* the error and fails the handshake with MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE.
*
* This test configures the SERVER with an oversized certificate. When a client connects,
* the server attempts to send its certificate during the TLS handshake. The server-side
* mbedTLS code detects that the certificate is too large and raises the
* TLS_EVENT_CODE_ALM_CERT_SIZE_EXCEEDED security event.
*
* This is the correct and expected behavior - a TLS endpoint can only detect and report
* issues with its OWN certificate before sending, not validate the size of incoming
* certificates from the peer (which are already constrained by TLS record size limits).
*/
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
/* Configure server with oversized certificate (> 16384 bytes) */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "client_oversized.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
/* Client configuration with normal-sized certificate */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Connection should fail - server cannot send its oversized certificate */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
Thread_sleep(200); /* Give time for security event to be generated */
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify that certificate size exceeded alarm was raised by the server */
bool certSizeExceededDetected = false;
for (int i = 0; i < eventInfo.eventHandlerCalled; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CERT_SIZE_EXCEEDED) {
certSizeExceededDetected = true;
break;
}
}
TEST_ASSERT_TRUE(certSizeExceededDetected);
}
void
test_CS104_MasterSlave_TLSCRLExpired(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration with expired CRL
* This test verifies that when the server has an expired CRL loaded,
* it generates a TLS_EVENT_CODE_WRN_CRL_EXPIRED warning event when
* validating a client certificate. The client certificate itself is
* valid and not revoked, but the CRL used to check revocation status
* has expired (Next Update date in the past).
*/
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setTimeValidation(tlsConfig1, false); /* Disable time validation so CRL expired flag is not cleared */
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
/* Load expired CRL - test.crl has Next Update: Jun 25, 2022 (expired) */
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
TEST_ASSERT_TRUE(res);
/* Client configuration with valid, non-revoked certificate
* client_CA1_4 is valid (expires 2030) and not in the CRL */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_4.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_4.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Connection should succeed, but with CRL expired warning */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
Thread_sleep(200); /* Give time for security event to be generated */
/* Verify that CRL expired warning was raised by the server */
bool crlExpiredDetected = false;
for (int i = 0; i < eventInfo.eventHandlerCalled; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_WRN_CRL_EXPIRED) {
crlExpiredDetected = true;
break;
}
}
TEST_ASSERT_TRUE(crlExpiredDetected);
CS104_Connection_sendStartDT(con);
printf("finished\n");
CS104_Connection_close(con);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
}
void
test_CS104_MasterSlave_TLSCertificateExpired(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TLSConfiguration_setMinTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* use expired certificate */
TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_1.key", NULL);
TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_1.pem");
TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TLSConfiguration_setMinTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_2);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
TEST_ASSERT_EQUAL_INT(3, eventInfo.eventHandlerCalled);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_WRN_CRL_NOT_ACCESSIBLE, eventInfo.eventCodes[0]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_CERT_EXPIRED, eventInfo.eventCodes[1]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED, eventInfo.eventCodes[2]);
}
void
test_CS104_MasterSlave_TLSCertificateRevoked(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
TEST_ASSERT_TRUE(res);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
;
/* use revoked certificate */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
TEST_ASSERT_EQUAL_INT(2, eventInfo.eventHandlerCalled);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_CERT_REVOKED, eventInfo.eventCodes[0]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED, eventInfo.eventCodes[1]);
}
/**
* Test that TLS handshake fails when the client presents a certificate with a
* public key length smaller than the configured minimum. The server should
* detect this and raise TLS_EVENT_CODE_ALM_INSUFFICIENT_KEY_LENGTH (23) alarm.
*
* Test scenario:
* - Server configured with minimum key length of 2048 bits
* - Client uses a certificate with only 1024-bit RSA key (client_CA1_weak.pem)
* - Connection should fail
* - Security event "Alarm: Insufficient key length" should be raised
*/
void
test_CS104_MasterSlave_TLSInsufficientKeyLength(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration with minimum key length of 2048 bits */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
/* Set minimum key length to 2048 bits (default, but explicit for test clarity) */
TLSConfiguration_setMinimumKeyLength(tlsConfig1, 2048);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
/* Client configuration with weak 1024-bit key certificate */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* Use certificate with 1024-bit RSA key (below minimum) */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_weak.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_weak.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Connection should fail due to insufficient key length */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
Thread_sleep(200); /* Give time for security event to be generated */
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify security event for insufficient key length was raised */
TEST_ASSERT_TRUE(eventInfo.eventHandlerCalled >= 1);
/* Find the insufficient key length event in the event list */
bool foundInsufficientKeyLengthEvent = false;
bool foundCertValidationFailedEvent = false;
bool foundMinKeyLengthEvent = false;
for (int i = 0; i < eventInfo.eventHandlerCalled && i < 200; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_INSUFFICIENT_KEY_LENGTH) {
foundInsufficientKeyLengthEvent = true;
}
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED) {
foundCertValidationFailedEvent = true;
}
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_WRN_MIN_KEY_LENGTH) {
foundMinKeyLengthEvent = true;
}
}
TEST_ASSERT_TRUE(foundInsufficientKeyLengthEvent);
TEST_ASSERT_TRUE(foundCertValidationFailedEvent);
TEST_ASSERT_FALSE(foundMinKeyLengthEvent);
}
void
test_CS104_MasterSlave_TLSInsufficientServerKeyLength(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration with minimum key length of 2048 bits */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "client_CA1_weak.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "client_CA1_weak.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
/* Client configuration with weak 1024-bit key certificate */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* Set minimum key length to 2048 bits (default, but explicit for test clarity) */
TLSConfiguration_setMinimumKeyLength(tlsConfig2, 2048);
/* Use certificate with 1024-bit RSA key (below minimum) */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setEventHandler(tlsConfig2, securityEventHandler, &eventInfo);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Connection should fail due to insufficient key length */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
Thread_sleep(200); /* Give time for security event to be generated */
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify security event for insufficient key length was raised */
TEST_ASSERT_TRUE(eventInfo.eventHandlerCalled >= 1);
/* Find the insufficient key length event in the event list */
bool foundInsufficientKeyLengthEvent = false;
bool foundCertValidationFailedEvent = false;
bool foundMinKeyLengthEvent = false;
for (int i = 0; i < eventInfo.eventHandlerCalled && i < 200; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_INSUFFICIENT_KEY_LENGTH) {
foundInsufficientKeyLengthEvent = true;
}
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED) {
foundCertValidationFailedEvent = true;
}
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_WRN_MIN_KEY_LENGTH) {
foundMinKeyLengthEvent = true;
}
}
TEST_ASSERT_TRUE(foundInsufficientKeyLengthEvent);
TEST_ASSERT_TRUE(foundCertValidationFailedEvent);
TEST_ASSERT_FALSE(foundMinKeyLengthEvent);
}
void
test_CS104_MasterSlave_TLSWarningMinimumKeyLength(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration with minimum key length of 1024 bits */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
/* Set minimum key length to 2048 bits (default, but explicit for test clarity) */
TLSConfiguration_setMinimumKeyLength(tlsConfig1, 1024);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setMinimumKeyLength(tlsConfig1, 1024);
/* Client configuration with weak 1024-bit key certificate */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* Use certificate with 1024-bit RSA key (below minimum) */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_weak.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_weak.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Connection should fail due to insufficient key length */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify security event for insufficient key length was raised */
TEST_ASSERT_TRUE(eventInfo.eventHandlerCalled >= 1);
/* Find the insufficient key length event in the event list */
bool foundInsufficientKeyLengthEvent = false;
bool foundCertValidationFailedEvent = false;
bool foundMinKeyLengthEvent = false;
for (int i = 0; i < eventInfo.eventHandlerCalled && i < 200; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_INSUFFICIENT_KEY_LENGTH) {
foundInsufficientKeyLengthEvent = true;
}
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED) {
foundCertValidationFailedEvent = true;
}
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_WRN_MIN_KEY_LENGTH) {
foundMinKeyLengthEvent = true;
}
}
TEST_ASSERT_FALSE(foundInsufficientKeyLengthEvent);
TEST_ASSERT_FALSE(foundCertValidationFailedEvent);
TEST_ASSERT_TRUE(foundMinKeyLengthEvent);
}
void
test_CS104_MasterSlave_TLSWarningMinimumServerKeyLength(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration with minimum key length of 2048 bits */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
/* Set minimum key length to 2048 bits (default, but explicit for test clarity) */
TLSConfiguration_setMinimumKeyLength(tlsConfig1, 2048);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "client_CA1_weak.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "client_CA1_weak.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
/* Client configuration with weak 1024-bit key certificate */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* Use certificate with 1024-bit RSA key (below minimum) */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setEventHandler(tlsConfig2, securityEventHandler, &eventInfo);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Connection should fail due to insufficient key length */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
Thread_sleep(200); /* Give time for security event to be generated */
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify security event for insufficient key length was raised */
TEST_ASSERT_TRUE(eventInfo.eventHandlerCalled >= 1);
/* Find the insufficient key length event in the event list */
bool foundInsufficientKeyLengthEvent = false;
bool foundCertValidationFailedEvent = false;
bool foundMinKeyLengthEvent = false;
for (int i = 0; i < eventInfo.eventHandlerCalled && i < 200; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_INSUFFICIENT_KEY_LENGTH) {
foundInsufficientKeyLengthEvent = true;
}
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED) {
foundCertValidationFailedEvent = true;
}
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_WRN_MIN_KEY_LENGTH) {
foundMinKeyLengthEvent = true;
}
}
TEST_ASSERT_FALSE(foundInsufficientKeyLengthEvent);
TEST_ASSERT_FALSE(foundCertValidationFailedEvent);
TEST_ASSERT_TRUE(foundMinKeyLengthEvent);
}
/**
* Test that TLS handshake fails when the client presents a certificate with an
* invalid signature. The server should detect this and raise
* TLS_EVENT_CODE_ALM_CERT_NOT_TRUSTED (14) alarm with message
* "Alarm: certificate validation: certificate signature could not be validated"
*
* Test scenario:
* - Server configured with chain validation enabled
* - Client uses a certificate with corrupted/invalid signature (client_CA1_badsig.pem)
* - Connection should fail
* - Security event for invalid signature should be raised
*/
void
test_CS104_MasterSlave_TLSInvalidSignature(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration with chain validation */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
/* Client configuration with certificate that has invalid/corrupted signature */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* Use certificate with corrupted signature */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_badsig.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_badsig.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Connection should fail due to invalid signature */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify security event for invalid signature was raised */
TEST_ASSERT_TRUE(eventInfo.eventHandlerCalled >= 1);
/* Find the certificate not trusted event (code 14) - this indicates signature validation failure */
bool foundCertNotTrustedEvent = false;
for (int i = 0; i < eventInfo.eventHandlerCalled && i < 200; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CERT_NOT_TRUSTED) {
foundCertNotTrustedEvent = true;
break;
}
}
TEST_ASSERT_TRUE(foundCertNotTrustedEvent);
}
void
test_CS104_MasterSlave_TLSUnknownCA(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration with chain validation */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
// res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
// TEST_ASSERT_TRUE(res);
TLSConfiguration_setChainValidation(tlsConfig1, true);
/* Client configuration with certificate that has invalid/corrupted signature */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* Use certificate with corrupted signature */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Connection should fail due to invalid signature */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify security event for invalid signature was raised */
TEST_ASSERT_TRUE(eventInfo.eventHandlerCalled >= 1);
/* Find the certificate not trusted event (code 14) - this indicates signature validation failure */
bool foundCertNotTrustedEvent = false;
for (int i = 0; i < eventInfo.eventHandlerCalled && i < 200; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CA_CERT_NOT_AVAILABLE) {
foundCertNotTrustedEvent = true;
break;
}
}
TEST_ASSERT_TRUE(foundCertNotTrustedEvent);
}
/**
* Test that TLS session renegotiation works correctly and raises appropriate
* security events. This test verifies the renegotiation mechanism is functional
* and that security events are properly generated.
*
* Test scenario:
* 1. Client and server configured with valid certificates
* 2. Connection establishes successfully
* 3. Server has short renegotiation time (1 second)
* 4. After renegotiation timer expires, next I/O triggers renegotiation
* 5. Renegotiation should succeed with valid certificates
* 6. Security event TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (10) is raised
*
* Note: Testing certificate change during renegotiation is not practical because
* mbedTLS caches certificates in the SSL context at initialization time, and
* changing TLSConfiguration after socket creation doesn't affect existing contexts.
*/
void
test_CS104_MasterSlave_TLSSuccessfulRenegotiation(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration with short renegotiation time */
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
/* Set short renegotiation time (1 second) so renegotiation happens quickly */
TLSConfiguration_setRenegotiationTime(tlsConfig1, 1000);
/* Server event handler to detect renegotiation */
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
/* Client configuration */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_4.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_4.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Initial connection should succeed with valid certificates */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
/* Send some data to confirm connection is working */
CS101_ASDU asdu1 =
CS101_ASDU_create(CS104_Slave_getAppLayerParameters(slave), false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io1 = (InformationObject)MeasuredValueScaled_create(NULL, 100, 42, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(asdu1, io1);
InformationObject_destroy(io1);
CS104_Slave_enqueueASDU(slave, asdu1);
CS101_ASDU_destroy(asdu1);
Thread_sleep(200);
/* Wait for renegotiation timer (1s) plus margin */
Thread_sleep(1500);
/* Send more data to trigger renegotiation check */
CS101_ASDU asdu2 =
CS101_ASDU_create(CS104_Slave_getAppLayerParameters(slave), false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io2 = (InformationObject)MeasuredValueScaled_create(NULL, 101, 43, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(asdu2, io2);
InformationObject_destroy(io2);
CS104_Slave_enqueueASDU(slave, asdu2);
CS101_ASDU_destroy(asdu2);
/* Wait for renegotiation to complete */
Thread_sleep(500);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify security events on server side:
* - TLS_EVENT_CODE_INF_SESSION_ESTABLISHED (initial connection succeeds)
* - TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation started)
*/
TEST_ASSERT_TRUE(eventInfo.eventHandlerCalled >= 2);
/* Find the session established event */
bool foundSessionEstablished = false;
for (int i = 0; i < eventInfo.eventHandlerCalled && i < 200; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_INF_SESSION_ESTABLISHED) {
foundSessionEstablished = true;
break;
}
}
TEST_ASSERT_TRUE(foundSessionEstablished);
/* Find the renegotiation event */
bool foundRenegotiationEvent = false;
for (int i = 0; i < eventInfo.eventHandlerCalled && i < 200; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION) {
foundRenegotiationEvent = true;
break;
}
}
TEST_ASSERT_TRUE(foundRenegotiationEvent);
}
void
test_CS104_MasterSlave_TLSRenegotiateAfterCRLUpdate(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
// res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
// TEST_ASSERT_TRUE(res);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* use revoked certificate */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setRenegotiationTime(tlsConfig1, 10000);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
TEST_ASSERT_TRUE(res);
CS101_ASDU newAsdu =
CS101_ASDU_create(CS104_Slave_getAppLayerParameters(slave), false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io = (InformationObject)MeasuredValueScaled_create(NULL, 110, 1, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
Thread_sleep(1000);
TEST_ASSERT_EQUAL_INT(5, eventInfo.eventHandlerCalled);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_WRN_CRL_NOT_ACCESSIBLE, eventInfo.eventCodes[0]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_INF_SESSION_ESTABLISHED, eventInfo.eventCodes[1]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION, eventInfo.eventCodes[2]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_CERT_REVOKED, eventInfo.eventCodes[3]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED, eventInfo.eventCodes[4]);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
}
void
test_CS104_MasterSlave_TLSRenegotiationCRLExpired(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
/* Server configuration with expired CRL
* This test verifies that when the server has an expired CRL loaded,
* it generates a TLS_EVENT_CODE_WRN_CRL_EXPIRED warning event when
* validating a client certificate. The client certificate itself is
* valid and not revoked, but the CRL used to check revocation status
* has expired (Next Update date in the past).
*/
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setTimeValidation(tlsConfig1, false); /* Disable time validation so CRL expired flag is not cleared */
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
/* Load expired CRL - test.crl has Next Update: Jun 25, 2022 (expired) */
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setRenegotiationTime(tlsConfig1, 1000);
/* Client configuration with valid, non-revoked certificate
* client_CA1_4 is valid (expires 2030) and not in the CRL */
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_4.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_4.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Connection should succeed, but with CRL expired warning */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
Thread_sleep(200); /* Give time for security event to be generated */
/* Verify that CRL expired warning was raised by the server */
int crlExpiredDetected = 0;
for (int i = 0; i < eventInfo.eventHandlerCalled; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_WRN_CRL_EXPIRED) {
crlExpiredDetected++;
}
}
TEST_ASSERT_EQUAL_INT(1, crlExpiredDetected);
Thread_sleep(1000);
CS104_Connection_sendStartDT(con);
Thread_sleep(2000);
crlExpiredDetected = 0;
for (int i = 0; i < eventInfo.eventHandlerCalled; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_WRN_CRL_EXPIRED) {
crlExpiredDetected++;
}
}
TEST_ASSERT_EQUAL_INT(2, crlExpiredDetected);
CS104_Connection_sendStopDT(con);
Thread_sleep(2000);
crlExpiredDetected = 0;
for (int i = 0; i < eventInfo.eventHandlerCalled; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_WRN_CRL_EXPIRED) {
crlExpiredDetected++;
}
}
CS104_Connection_close(con);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
//TEST_ASSERT_EQUAL_INT(2, crlExpiredDetected);
}
void
test_CS104_MasterSlave_TLSCertificateRevokedBeforeRenegotiation(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
/* Set short renegotiation time (1 second) so renegotiation happens quickly */
TLSConfiguration_setRenegotiationTime(tlsConfig1, 1000);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* Client uses certificate that IS revoked in test.crl (client_CA1_3, serial ...C9) */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Initial connection succeeds because server has no CRL loaded yet */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
/* Now load CRL on server side - this will be used during next renegotiation */
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
TEST_ASSERT_TRUE(res);
/* Wait for renegotiation timer (1s) plus margin */
Thread_sleep(1500);
/* Send data to trigger renegotiation check */
CS101_ASDU newAsdu =
CS101_ASDU_create(CS104_Slave_getAppLayerParameters(slave), false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io = (InformationObject)MeasuredValueScaled_create(NULL, 110, 1, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
/* Wait for renegotiation to complete and connection to close */
Thread_sleep(1500);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify security events:
* Expected sequence:
* - Event 0: TLS_EVENT_CODE_INF_SESSION_ESTABLISHED (initial connection succeeds, no CRL loaded yet)
* - Event 1: TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation started after CRL loaded)
* - Event 2: TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation completed)
* - Event 3: TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED (certificate validation fails after renegotiation handshake)
* - Many: TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON (repeated handshake failures)
* - Eventually: TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation started again)
* - Finally: TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation failed)
*
* Note: The specific "revoked certificate" event (TLS_EVENT_CODE_ALM_CERT_REVOKED) is not raised
* during renegotiation in mbedTLS 2.x because certificate verification happens after the handshake
* completes, and the verification callback may not distinguish revoked from other validation failures
* in the renegotiation context. This test verifies that the connection DOES fail due to certificate
* validation after CRL is loaded, which is the important security property.
*/
TEST_ASSERT_TRUE(eventInfo.eventHandlerCalled >= 4);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_WRN_CRL_NOT_ACCESSIBLE, eventInfo.eventCodes[0]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_INF_SESSION_ESTABLISHED, eventInfo.eventCodes[1]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION, eventInfo.eventCodes[2]);
/* Verify that certificate validation failed during or after renegotiation */
bool foundCertValidationFailed = false;
for (int i = 2; i < eventInfo.eventHandlerCalled && i < 100; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED) {
foundCertValidationFailed = true;
break;
}
}
TEST_ASSERT_TRUE(foundCertValidationFailed);
}
void
test_CS104_MasterSlave_TLSCRLUpdateDuringConnection(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
/* Initially do NOT load any CRL - this means no certificates are revoked */
/* (Alternative would be to load an empty CRL, but not loading is equivalent) */
/* Set short renegotiation time (1 second) so renegotiation happens quickly */
TLSConfiguration_setRenegotiationTime(tlsConfig1, 1000);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* Client uses certificate that will be revoked when test.crl is loaded (client_CA1_3, serial ...C9) */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Initial connection succeeds because no CRL is loaded (no revocations to check) */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
/* Send some data to confirm connection is working */
CS101_ASDU asdu1 =
CS101_ASDU_create(CS104_Slave_getAppLayerParameters(slave), false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io1 = (InformationObject)MeasuredValueScaled_create(NULL, 100, 42, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(asdu1, io1);
InformationObject_destroy(io1);
CS104_Slave_enqueueASDU(slave, asdu1);
CS101_ASDU_destroy(asdu1);
Thread_sleep(200);
/* Now load CRL with client certificate revoked - this will trigger renegotiation */
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
TEST_ASSERT_TRUE(res);
/* Wait for renegotiation timer (1s) plus margin */
Thread_sleep(1500);
/* Send more data to trigger renegotiation check */
CS101_ASDU asdu2 =
CS101_ASDU_create(CS104_Slave_getAppLayerParameters(slave), false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io2 = (InformationObject)MeasuredValueScaled_create(NULL, 101, 43, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(asdu2, io2);
InformationObject_destroy(io2);
CS104_Slave_enqueueASDU(slave, asdu2);
CS101_ASDU_destroy(asdu2);
/* Wait for renegotiation to complete and connection to close */
Thread_sleep(1500);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify security events:
* Expected sequence:
* - Event 0: TLS_EVENT_CODE_INF_SESSION_ESTABLISHED (initial connection succeeds, no CRL loaded)
* - Event 1: TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation started after CRL loaded and updated)
* - Event 2: TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation completed)
* - Event 3: TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED (certificate validation fails - client cert now revoked)
* - Many: TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON (repeated handshake failures)
* - Eventually: TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation started again)
* - Finally: TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation failed)
*
* This test validates IEC 62351-3 Section 6.2.6 requirement: "If the CRL is updated, a TLS
* renegotiation shall be performed to ensure that the peer's certificate is validated against
* the updated CRL." The test confirms that after a CRL update that revokes a client certificate,
* the automatic renegotiation detects the revocation and terminates the connection.
*/
TEST_ASSERT_TRUE(eventInfo.eventHandlerCalled >= 4);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_WRN_CRL_NOT_ACCESSIBLE, eventInfo.eventCodes[0]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_INF_SESSION_ESTABLISHED, eventInfo.eventCodes[1]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION, eventInfo.eventCodes[2]);
/* Verify that certificate validation failed during or after renegotiation */
bool foundCertValidationFailed = false;
for (int i = 2; i < eventInfo.eventHandlerCalled && i < 100; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED) {
foundCertValidationFailed = true;
break;
}
}
TEST_ASSERT_TRUE(foundCertValidationFailed);
}
void
test_CS104_MasterSlave_TLSCRLUpdateWithNewRevocation(void)
{
struct secEventInfo eventInfo;
memset(&eventInfo, 0, sizeof(struct secEventInfo));
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, &eventInfo);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
/* Initially load CRL that only revokes client_CA1_2 (serial ...C6) */
/* This CRL does NOT revoke client_CA1_3 (serial ...C9) yet */
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test_initial.crl");
TEST_ASSERT_TRUE(res);
/* Set short renegotiation time (1 second) so renegotiation happens quickly */
TLSConfiguration_setRenegotiationTime(tlsConfig1, 1000);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* Client uses client_CA1_3 (serial ...C9) which is NOT revoked in test_initial.crl */
/* but WILL BE revoked when we update to test.crl */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
/* Initial connection succeeds because client_CA1_3 is NOT revoked in test_initial.crl */
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
/* Send some data to confirm connection is working */
CS101_ASDU asdu1 =
CS101_ASDU_create(CS104_Slave_getAppLayerParameters(slave), false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io1 = (InformationObject)MeasuredValueScaled_create(NULL, 100, 42, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(asdu1, io1);
InformationObject_destroy(io1);
CS104_Slave_enqueueASDU(slave, asdu1);
CS101_ASDU_destroy(asdu1);
Thread_sleep(200);
/* Now update CRL to test.crl which also revokes client_CA1_3 (adds ...C9 to revocations) */
/* This simulates a real-world scenario where a new certificate gets revoked */
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
TEST_ASSERT_TRUE(res);
/* Wait for renegotiation timer (1s) plus margin */
Thread_sleep(1500);
/* Send more data to trigger renegotiation check */
CS101_ASDU asdu2 =
CS101_ASDU_create(CS104_Slave_getAppLayerParameters(slave), false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io2 = (InformationObject)MeasuredValueScaled_create(NULL, 101, 43, IEC60870_QUALITY_GOOD);
CS101_ASDU_addInformationObject(asdu2, io2);
InformationObject_destroy(io2);
CS104_Slave_enqueueASDU(slave, asdu2);
CS101_ASDU_destroy(asdu2);
/* Wait for renegotiation to complete and connection to close */
Thread_sleep(1500);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
/* Verify security events:
* Expected sequence:
* - Event 0: TLS_EVENT_CODE_INF_SESSION_ESTABLISHED (initial connection succeeds, client cert not revoked)
* - Event 1: TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation started after CRL updated)
* - Event 2: TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION (renegotiation completed)
* - Event 3: TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED (certificate validation fails - client cert now revoked)
* - Many: TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON (repeated handshake failures)
*
* This test validates IEC 62351-3 Section 6.2.6 requirement: "If the CRL is updated, a TLS
* renegotiation shall be performed to ensure that the peer's certificate is validated against
* the updated CRL." The test confirms that when a CRL is updated to add a NEW revocation for
* a client certificate that was previously valid, the automatic renegotiation detects the
* new revocation and terminates the connection.
*
* Test scenario:
* 1. Server loads test_initial.crl (only revokes client_CA1_2, serial ...C6)
* 2. Client connects with client_CA1_3 (serial ...C9) - NOT revoked yet - connection succeeds
* 3. Server updates to test.crl (revokes both ...C6 AND ...C9)
* 4. Automatic renegotiation triggered
* 5. Client certificate now detected as revoked
* 6. Connection terminated
*
* Note: The specific "revoked certificate" event (TLS_EVENT_CODE_ALM_CERT_REVOKED) is not raised
* during renegotiation in mbedTLS 2.x because certificate verification happens after the handshake
* completes, and the verification callback may not distinguish revoked from other validation failures
* in the renegotiation context. This test verifies that the connection DOES fail due to certificate
* validation after CRL is loaded, which is the important security property.
*/
TEST_ASSERT_TRUE(eventInfo.eventHandlerCalled >= 4);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_INF_SESSION_ESTABLISHED, eventInfo.eventCodes[0]);
TEST_ASSERT_EQUAL_INT(TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION, eventInfo.eventCodes[1]);
/* Verify that certificate validation failed during or after renegotiation */
bool foundCertValidationFailed = false;
for (int i = 2; i < eventInfo.eventHandlerCalled && i < 100; i++) {
if (eventInfo.eventCodes[i] == TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED) {
foundCertValidationFailed = true;
break;
}
}
TEST_ASSERT_TRUE(foundCertValidationFailed);
}
void
test_CS104_MasterSlave_TLSCertificateRevokedBeforeReconnect(void)
{
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_enableSessionResumption(tlsConfig1, false);
TLSConfiguration_setChainValidation(tlsConfig1, true);
// TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, NULL);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
TLSConfiguration_setRenegotiationTime(tlsConfig1, 1000);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* use revoked certificate */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setEventHandler(tlsConfig2, securityEventHandler, NULL);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_close(con);
/* update CRL -> expect renegotiation to fail! */
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
TEST_ASSERT_TRUE(res);
result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
}
void
test_CS104_MasterSlave_TLSUnknownCertificate(void)
{
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, NULL);
TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TLSConfiguration_addAllowedCertificateFromFile(tlsConfig1, "client_CA1_3.pem");
TLSConfiguration_setMinTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig2, true);
;
/* use expired certificate */
TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_4.key", NULL);
TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_4.pem");
TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TLSConfiguration_setMinTlsVersion(tlsConfig2, TLS_VERSION_TLS_1_2);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
}
void
test_CS104_MasterSlave_TLSUseSessionResumption(void)
{
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_enableSessionResumption(tlsConfig1, true);
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_enableSessionResumption(tlsConfig2, true);
TLSConfiguration_setChainValidation(tlsConfig2, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig2, true);
/* use valid certificate */
TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TLSConfiguration_addAllowedCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_destroy(con);
printf("New connection should use the old TLS session\n");
con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
}
void
test_CS104_MasterSlave_TLSCertificateSessionResumptionExpiredAtClient(void)
{
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, NULL);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setRenegotiationTime(tlsConfig1, 1000);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_enableSessionResumption(tlsConfig2, true);
TLSConfiguration_setSessionResumptionInterval(tlsConfig2, 1);
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* use revoked certificate */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_close(con);
Thread_sleep(1500);
/* update CRL -> expect renegotiation to fail! */
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
TEST_ASSERT_TRUE(res);
result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
}
void
test_CS104_MasterSlave_TLSCertificateSessionResumptionExpiredAtServer(void)
{
bool res = false;
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_enableSessionResumption(tlsConfig1, true);
TLSConfiguration_setSessionResumptionInterval(tlsConfig1, 1);
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setEventHandler(tlsConfig1, securityEventHandler, NULL);
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
TLSConfiguration_setRenegotiationTime(tlsConfig1, 1000);
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_enableSessionResumption(tlsConfig2, true);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
TLSConfiguration_setChainValidation(tlsConfig2, true);
/* use revoked certificate */
res = TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TEST_ASSERT_TRUE(res);
res = TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TEST_ASSERT_TRUE(res);
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_close(con);
Thread_sleep(2000);
/* update CRL -> expect renegotiation to fail! */
res = TLSConfiguration_addCRLFromFile(tlsConfig1, "test.crl");
TEST_ASSERT_TRUE(res);
result = CS104_Connection_connect(con);
TEST_ASSERT_FALSE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
}
void
test_CS104_MasterSlave_TLSReuseConfigurationWithSessionResumption(void)
{
TLSConfiguration tlsConfig1 = TLSConfiguration_create();
TLSConfiguration_enableSessionResumption(tlsConfig1, true);
TLSConfiguration_setChainValidation(tlsConfig1, true);
TLSConfiguration_setOwnKeyFromFile(tlsConfig1, "server_CA1_1.key", NULL);
TLSConfiguration_setOwnCertificateFromFile(tlsConfig1, "server_CA1_1.pem");
TLSConfiguration_addCACertificateFromFile(tlsConfig1, "root_CA1.pem");
TLSConfiguration tlsConfig2 = TLSConfiguration_create();
TLSConfiguration_enableSessionResumption(tlsConfig2, true);
TLSConfiguration_setChainValidation(tlsConfig2, true);
TLSConfiguration_setAllowOnlyKnownCertificates(tlsConfig2, true);
/* use valid certificate */
TLSConfiguration_setOwnKeyFromFile(tlsConfig2, "client_CA1_3.key", NULL);
TLSConfiguration_setOwnCertificateFromFile(tlsConfig2, "client_CA1_3.pem");
TLSConfiguration_addCACertificateFromFile(tlsConfig2, "root_CA1.pem");
TLSConfiguration_addAllowedCertificateFromFile(tlsConfig2, "server_CA1_1.pem");
CS104_Slave slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TLSConfiguration_setMaxTlsVersion(tlsConfig1, TLS_VERSION_TLS_1_2);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_destroy(con);
con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
slave = CS104_Slave_createSecure(100, 100, tlsConfig1);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
con = CS104_Connection_createSecure("127.0.0.1", 20004, tlsConfig2);
TEST_ASSERT_NOT_NULL(con);
result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
Thread_sleep(500);
CS104_Slave_destroy(slave);
CS104_Connection_destroy(con);
TLSConfiguration_destroy(tlsConfig1);
TLSConfiguration_destroy(tlsConfig2);
}
#endif /* #if (CONFIG_CS104_SUPPORT_TLS == 1) */
void
test_ASDUsetGetNumberOfElements(void)
{
struct sCS101_AppLayerParameters salParameters;
salParameters.maxSizeOfASDU = 100;
salParameters.originatorAddress = 0;
salParameters.sizeOfCA = 2;
salParameters.sizeOfCOT = 2;
salParameters.sizeOfIOA = 3;
salParameters.sizeOfTypeId = 1;
salParameters.sizeOfVSQ = 1;
CS101_ASDU asdu = CS101_ASDU_create(&salParameters, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
TEST_ASSERT_FALSE(CS101_ASDU_isSequence(asdu));
CS101_ASDU_setNumberOfElements(asdu, 127);
TEST_ASSERT_EQUAL_INT(127, CS101_ASDU_getNumberOfElements(asdu));
CS101_ASDU_setNumberOfElements(asdu, 5);
TEST_ASSERT_EQUAL_INT(5, CS101_ASDU_getNumberOfElements(asdu));
TEST_ASSERT_FALSE(CS101_ASDU_isSequence(asdu));
CS101_ASDU_setSequence(asdu, true);
CS101_ASDU_setNumberOfElements(asdu, 127);
TEST_ASSERT_EQUAL_INT(127, CS101_ASDU_getNumberOfElements(asdu));
CS101_ASDU_setNumberOfElements(asdu, 5);
TEST_ASSERT_EQUAL_INT(5, CS101_ASDU_getNumberOfElements(asdu));
TEST_ASSERT_TRUE(CS101_ASDU_isSequence(asdu));
CS101_ASDU_destroy(asdu);
}
static uint8_t STARTDT_ACT_MSG[] = {0x68, 0x04, 0x07, 0x00, 0x00, 0x00};
static uint8_t STOPDT_ACT_MSG[] = {0x68, 0x04, 0x13, 0x00, 0x00, 0x00};
void
test_CS104SlaveUnconfirmedStoppedMode()
{
CS104_Slave slave = CS104_Slave_create(10, 10);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
struct stest_CS104SlaveEventQueue1 info;
info.asduHandlerCalled = 0;
info.spontCount = 0;
info.lastScaledValue = 0;
int16_t scaledValue = 0;
for (int i = 0; i < 15; i++)
{
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io =
(InformationObject)MeasuredValueScaled_create(NULL, 110, scaledValue, IEC60870_QUALITY_GOOD);
scaledValue++;
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
}
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
CS104_Connection_setASDUReceivedHandler(con, test_CS104SlaveEventQueue1_asduReceivedHandler, &info);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
Thread_sleep(500);
CS104_Connection_sendStopDT(con);
CS104_Connection_close(con);
TEST_ASSERT_EQUAL_INT(14, info.lastScaledValue);
info.asduHandlerCalled = 0;
info.spontCount = 0;
result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
for (int i = 0; i < 6; i++)
{
Thread_sleep(10);
CS101_ASDU newAsdu = CS101_ASDU_create(alParams, false, CS101_COT_SPONTANEOUS, 0, 1, false, false);
InformationObject io =
(InformationObject)MeasuredValueScaled_create(NULL, 110, scaledValue, IEC60870_QUALITY_GOOD);
scaledValue++;
CS101_ASDU_addInformationObject(newAsdu, io);
InformationObject_destroy(io);
CS104_Slave_enqueueASDU(slave, newAsdu);
CS101_ASDU_destroy(newAsdu);
}
Thread_sleep(500);
TEST_ASSERT_EQUAL_INT(6, CS104_Connection_sendMessage(con, STOPDT_ACT_MSG, sizeof(STOPDT_ACT_MSG)));
Thread_sleep(5000);
CS104_Connection_close(con);
TEST_ASSERT_EQUAL_INT(6, info.asduHandlerCalled);
TEST_ASSERT_EQUAL_INT(6, info.spontCount);
TEST_ASSERT_EQUAL_INT(20, info.lastScaledValue);
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
#define SCALED_VALUE_MAX 32767
#define SCALED_VALUE_MIN -32768
#define NORMALIZED_VALUE_MAX (32767.f / 32768.f)
void
test_ScaledNormalizedConversion()
{
TEST_ASSERT_EQUAL_INT(32767, NormalizedValue_toScaled(NORMALIZED_VALUE_MAX));
TEST_ASSERT_EQUAL_INT(32767, NormalizedValue_toScaled(1.0f));
TEST_ASSERT_EQUAL_INT(32767, NormalizedValue_toScaled(2.0f));
TEST_ASSERT_EQUAL_INT(-32768, NormalizedValue_toScaled(-1.0f));
TEST_ASSERT_EQUAL_INT(-32768, NormalizedValue_toScaled(-2.0f));
TEST_ASSERT_EQUAL_INT(0, NormalizedValue_toScaled(0.0f));
TEST_ASSERT_EQUAL_INT(0, NormalizedValue_toScaled(-0.0f));
float normalizedUnit = (1.f - NORMALIZED_VALUE_MAX);
TEST_ASSERT_EQUAL_FLOAT(NORMALIZED_VALUE_MAX - normalizedUnit, NormalizedValue_fromScaled(32766));
TEST_ASSERT_EQUAL_FLOAT(NORMALIZED_VALUE_MAX, NormalizedValue_fromScaled(32767));
TEST_ASSERT_EQUAL_FLOAT(NORMALIZED_VALUE_MAX, NormalizedValue_fromScaled(32768));
TEST_ASSERT_EQUAL_FLOAT(NORMALIZED_VALUE_MAX, NormalizedValue_fromScaled(99999));
TEST_ASSERT_EQUAL_FLOAT(-1.0f + (normalizedUnit * 2.f), NormalizedValue_fromScaled(-32766));
TEST_ASSERT_EQUAL_FLOAT(-1.0f + normalizedUnit, NormalizedValue_fromScaled(-32767));
TEST_ASSERT_EQUAL_FLOAT(-1.0f, NormalizedValue_fromScaled(-32768));
TEST_ASSERT_EQUAL_FLOAT(-1.0f, NormalizedValue_fromScaled(-32769));
TEST_ASSERT_EQUAL_FLOAT(0.0f, NormalizedValue_fromScaled(0));
}
void
test_CS104Connection_cannotWriteToSocketWhenNotConnected()
{
/* test that the client does not crash when it tries to send a message after the connection is closed */
CS104_Slave slave = CS104_Slave_create(10, 10);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_sendStartDT(con);
CS104_Slave_stop(slave);
Thread_sleep(500);
CS104_Connection_sendStopDT(con);
CS104_Connection_close(con);
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
static bool
test_CS104Slave_handleTestCommand_asduReceivedHandler(void* parameter, int address, CS101_ASDU asdu)
{
CS101_ASDU* receivedASDU = (CS101_ASDU*)parameter;
if (*receivedASDU != NULL)
{
CS101_ASDU_destroy(*receivedASDU);
}
*receivedASDU = CS101_ASDU_clone(asdu, NULL);
return true;
}
void
test_CS104Slave_handleTestCommandWithTimestamp()
{
CS101_ASDU receivedASDU = NULL;
CS104_Slave slave = CS104_Slave_create(10, 10);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_setASDUReceivedHandler(con, test_CS104Slave_handleTestCommand_asduReceivedHandler, &receivedASDU);
CS104_Connection_sendStartDT(con);
TestCommandWithCP56Time2a tc;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
/* send correct test command */
tc = TestCommandWithCP56Time2a_create(NULL, 0xaa55, &cpTime1);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)tc);
TestCommandWithCP56Time2a_destroy(tc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_TS_TA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_ACTIVATION_CON, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_FALSE(CS101_ASDU_isNegative(receivedASDU));
/* send test command with wrong COT */
tc = TestCommandWithCP56Time2a_create(NULL, 0xaa55, &cpTime1);
asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION_CON, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)tc);
TestCommandWithCP56Time2a_destroy(tc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_TS_TA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_COT, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
/* send test command with correct COT but IOA != 0 */
tc = TestCommandWithCP56Time2a_create(NULL, 0xaa55, &cpTime1);
InformationObject_setObjectAddress((InformationObject)tc, 2);
asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)tc);
TestCommandWithCP56Time2a_destroy(tc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_TS_TA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_IOA, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
/* send test command with wrong COT AND IOA != 0 */
tc = TestCommandWithCP56Time2a_create(NULL, 0xaa55, &cpTime1);
InformationObject_setObjectAddress((InformationObject)tc, 2);
asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION_TERMINATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)tc);
TestCommandWithCP56Time2a_destroy(tc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_TS_TA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_COT, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
CS104_Connection_close(con);
CS104_Connection_destroy(con);
if (receivedASDU)
CS101_ASDU_destroy(receivedASDU);
CS104_Slave_destroy(slave);
}
void
test_CS104Slave_rejectCommandsWithBroadcastCA()
{
CS101_ASDU receivedASDU = NULL;
CS104_Slave slave = CS104_Slave_create(10, 10);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_setASDUReceivedHandler(con, test_CS104Slave_handleTestCommand_asduReceivedHandler, &receivedASDU);
CS104_Connection_sendStartDT(con);
TestCommandWithCP56Time2a tc;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
tc = TestCommandWithCP56Time2a_create(NULL, 0xaa55, &cpTime1);
/* send test command with CASDU = 65535 (broadcast)*/
CS101_ASDU asdu =
CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 65535, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)tc);
TestCommandWithCP56Time2a_destroy(tc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_TS_TA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_CA, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
ReadCommand rc = ReadCommand_create(NULL, 100);
/* send read command with CASDU = 65535 (broadcast)*/
asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 65535, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)rc);
ReadCommand_destroy(rc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_RD_NA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_CA, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
struct sCP16Time2a cp16Time2a;
CP16Time2a_setEplapsedTimeInMs(&cp16Time2a, 1);
DelayAcquisitionCommand dac = DelayAcquisitionCommand_create(NULL, 0, &cp16Time2a);
/* send delay acquisition command with CASDU = 65535 (broadcast)*/
asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 65535, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)dac);
DelayAcquisitionCommand_destroy(dac);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_CD_NA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_CA, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
CS104_Connection_close(con);
CS104_Connection_destroy(con);
if (receivedASDU)
CS101_ASDU_destroy(receivedASDU);
CS104_Slave_destroy(slave);
}
static bool
test_IsCAAllowedHandler(void* parameter, int ca)
{
int expectedCa = *((int*)parameter);
return (expectedCa == ca);
}
void
test_CS104Slave_rejectCommandWithUnknownCA()
{
int expectedCa = 100;
CS101_ASDU receivedASDU = NULL;
CS104_Slave slave = CS104_Slave_create(10, 10);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_setAllowedCAHandler(slave, test_IsCAAllowedHandler, &expectedCa);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_setASDUReceivedHandler(con, test_CS104Slave_handleTestCommand_asduReceivedHandler, &receivedASDU);
CS104_Connection_sendStartDT(con);
TestCommandWithCP56Time2a tc;
uint64_t time1 = Hal_getTimeInMs();
struct sCP56Time2a cpTime1;
CP56Time2a_createFromMsTimestamp(&cpTime1, time1);
/* send test command with unknown CA */
tc = TestCommandWithCP56Time2a_create(NULL, 0xaa55, &cpTime1);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)tc);
TestCommandWithCP56Time2a_destroy(tc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_TS_TA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_CA, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
/* send test command with known CA */
tc = TestCommandWithCP56Time2a_create(NULL, 0xaa55, &cpTime1);
asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, expectedCa, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)tc);
TestCommandWithCP56Time2a_destroy(tc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_TS_TA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_ACTIVATION_CON, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_FALSE(CS101_ASDU_isNegative(receivedASDU));
CS104_Connection_close(con);
CS104_Connection_destroy(con);
if (receivedASDU)
CS101_ASDU_destroy(receivedASDU);
CS104_Slave_destroy(slave);
}
bool
test_ResetProcessHandler(void* parameter, IMasterConnection connection, CS101_ASDU asdu, uint8_t qrp)
{
int* resetProcessHandlerCalled = (int*)parameter;
if (resetProcessHandlerCalled)
{
*resetProcessHandlerCalled = *resetProcessHandlerCalled + 1;
}
IMasterConnection_sendACT_CON(connection, asdu, false);
return true;
}
void
test_CS104Slave_handleResetProcessCommand()
{
CS101_ASDU receivedASDU = NULL;
int resetProcessHandlerCalled = 0;
CS104_Slave slave = CS104_Slave_create(10, 10);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS101_AppLayerParameters alParams = CS104_Slave_getAppLayerParameters(slave);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
CS104_Connection_setASDUReceivedHandler(con, test_CS104Slave_handleTestCommand_asduReceivedHandler, &receivedASDU);
CS104_Connection_sendStartDT(con);
ResetProcessCommand rpc = ResetProcessCommand_create(NULL, 0, 0);
CS101_ASDU asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)rpc);
ResetProcessCommand_destroy(rpc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_RP_NA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_TYPE_ID, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
if (receivedASDU)
{
CS101_ASDU_destroy(receivedASDU);
receivedASDU = NULL;
}
CS104_Slave_setResetProcessHandler(slave, test_ResetProcessHandler, &resetProcessHandlerCalled);
rpc = ResetProcessCommand_create(NULL, 0, 0);
asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)rpc);
ResetProcessCommand_destroy(rpc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_RP_NA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_ACTIVATION_CON, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_FALSE(CS101_ASDU_isNegative(receivedASDU));
TEST_ASSERT_EQUAL_INT(1, resetProcessHandlerCalled);
/* send reset process command with invalid IOA (!= 0) */
rpc = ResetProcessCommand_create(NULL, 1, 0);
asdu = CS101_ASDU_create(&defaultAppLayerParameters, false, CS101_COT_ACTIVATION, 0, 1, false, false);
CS101_ASDU_addInformationObject(asdu, (InformationObject)rpc);
ResetProcessCommand_destroy(rpc);
TEST_ASSERT_TRUE(CS104_Connection_sendASDU(con, asdu));
CS101_ASDU_destroy(asdu);
Thread_sleep(500);
TEST_ASSERT_NOT_NULL(receivedASDU);
TEST_ASSERT_EQUAL_INT(C_RP_NA_1, CS101_ASDU_getTypeID(receivedASDU));
TEST_ASSERT_EQUAL_INT(CS101_COT_UNKNOWN_IOA, CS101_ASDU_getCOT(receivedASDU));
TEST_ASSERT_TRUE(CS101_ASDU_isNegative(receivedASDU));
TEST_ASSERT_EQUAL_INT(1, resetProcessHandlerCalled);
CS104_Connection_close(con);
CS104_Connection_destroy(con);
if (receivedASDU)
CS101_ASDU_destroy(receivedASDU);
CS104_Slave_destroy(slave);
}
/*
* Test: Client sends TESTFR_ACT after T3 timeout when connection remains INACTIVE (no STARTDT)
* We start a server and a client in threadless mode, set a short T3 (2s), leave connection inactive,
* and poll both sides until we observe the TESTFR_ACT frame (0x68 0x04 0x43 00 00 00) received by the server.
*/
static uint8_t _testfr_frame[6];
static bool _testfr_found = false;
static void
_testfr_rawHandler(void* parameter, IMasterConnection connection, uint8_t* msg, int msgSize, bool sent)
{
(void)parameter;
(void)connection;
/* print raw frames for debugging */
{
char peerAddrBuf[128];
peerAddrBuf[0] = '\0';
if (connection)
{
/* fill peer address string if available */
IMasterConnection_getPeerAddress(connection, peerAddrBuf, sizeof(peerAddrBuf));
}
// printf("[RAW %s] size=%d peer=%s sent=%s\n", (sent ? "SENT" : "RECV"), msgSize,
// (peerAddrBuf[0] != '\0' ? peerAddrBuf : "unknown"), (sent ? "true" : "false"));
// if (msg && msgSize > 0)
// {
// printf(" data:");
// for (int i = 0; i < msgSize; i++)
// {
// printf(" %02x", msg[i]);
// }
// printf("\n");
// fflush(stdout);
// }
}
if (!sent && msgSize == 6 && msg[0] == 0x68 && msg[1] == 0x04 && msg[2] == 0x43)
{
memcpy(_testfr_frame, msg, 6);
_testfr_found = true;
}
}
void
test_CS104_Connection_sendsTestFrAfterT3TimeoutInactive()
{
_testfr_found = false;
memset(_testfr_frame, 0, sizeof(_testfr_frame));
/* Start slave in threadless mode */
CS104_Slave slave = CS104_Slave_create(5, 5);
TEST_ASSERT_NOT_NULL(slave);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20014);
CS104_Slave_startThreadless(slave);
CS104_Slave_setRawMessageHandler(slave, _testfr_rawHandler, NULL);
/* Create client connection threadless with small T3 */
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20014);
TEST_ASSERT_NOT_NULL(con);
CS104_APCIParameters p = CS104_Connection_getAPCIParameters(con);
p->t3 = 2; /* seconds */
p->t2 = 1; /* keep small just in case */
p->t1 = 3; /* arbitrary */
/* Establish socket in threadless mode */
TEST_ASSERT_TRUE_MESSAGE(CS104_Connection_startThreadless(con), "Failed to start threadless connection");
/* Loop until TESTFR_ACT observed or timeout (~5s) */
uint64_t start = Hal_getTimeInMs();
while (!_testfr_found && (Hal_getTimeInMs() - start) < 5500)
{
CS104_Slave_tick(slave);
CS104_Connection_run(con, 50); /* wait up to 50ms for client socket events */
Thread_sleep(20);
}
TEST_ASSERT_TRUE_MESSAGE(_testfr_found, "Did not capture TESTFR_ACT after T3 timeout in inactive state");
TEST_ASSERT_EQUAL_UINT8(0x68, _testfr_frame[0]);
TEST_ASSERT_EQUAL_UINT8(0x04, _testfr_frame[1]);
TEST_ASSERT_EQUAL_UINT8(0x43, _testfr_frame[2]);
/* Cleanup */
CS104_Connection_stopThreadless(con);
CS104_Connection_destroy(con);
CS104_Slave_stopThreadless(slave);
CS104_Slave_destroy(slave);
}
static void*
silent_server_thread(void* parameter)
{
int port = 20005;
ServerSocket serverSocket = TcpServerSocket_create(NULL, port);
if (serverSocket)
{
ServerSocket_listen(serverSocket);
Socket clientSocket = NULL;
int retry = 0;
while (clientSocket == NULL && retry < 100)
{
clientSocket = ServerSocket_accept(serverSocket);
if (clientSocket == NULL)
{
Thread_sleep(10);
retry++;
}
}
if (clientSocket)
{
uint8_t buffer[100];
/* Read START_DT ACT */
Socket_read(clientSocket, buffer, 100);
/* Do NOT send START_DT CON */
/* Wait longer than T1 (1s) */
Thread_sleep(2000);
Socket_destroy(clientSocket);
}
ServerSocket_destroy(serverSocket);
}
return NULL;
}
static CS104_ConnectionEvent test_CS104_Connection_StartDTTimeout_event = CS104_CONNECTION_OPENED;
static void
test_CS104_Connection_StartDTTimeout_connectionHandler(void* parameter, CS104_Connection connection,
CS104_ConnectionEvent event)
{
test_CS104_Connection_StartDTTimeout_event = event;
}
void
test_CS104_Connection_StartDTTimeout(void)
{
test_CS104_Connection_StartDTTimeout_event = CS104_CONNECTION_OPENED;
Thread serverThread = Thread_create(silent_server_thread, NULL, false);
Thread_start(serverThread);
Thread_sleep(100);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20005);
TEST_ASSERT_NOT_NULL(con);
CS104_APCIParameters apciParameters = CS104_Connection_getAPCIParameters(con);
apciParameters->t1 = 1;
CS104_Connection_setConnectionHandler(con, test_CS104_Connection_StartDTTimeout_connectionHandler, NULL);
bool connected = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(connected);
CS104_Connection_sendStartDT(con);
/* Wait for timeout (T1 = 1s) + some margin */
Thread_sleep(2000);
TEST_ASSERT_EQUAL_INT(CS104_CONNECTION_CLOSED, test_CS104_Connection_StartDTTimeout_event);
CS104_Connection_destroy(con);
Thread_destroy(serverThread);
}
static void*
silent_server_thread_stop_dt(void* parameter)
{
int port = 20006;
ServerSocket serverSocket = TcpServerSocket_create(NULL, port);
if (serverSocket)
{
ServerSocket_listen(serverSocket);
Socket clientSocket = NULL;
int retry = 0;
while (clientSocket == NULL && retry < 100)
{
clientSocket = ServerSocket_accept(serverSocket);
if (clientSocket == NULL)
{
Thread_sleep(10);
retry++;
}
}
if (clientSocket)
{
uint8_t buffer[100];
/* Read START_DT ACT */
int readBytes = Socket_read(clientSocket, buffer, 100);
if (readBytes > 0)
{
/* Send START_DT CON */
uint8_t startDtCon[] = {0x68, 0x04, 0x0B, 0x00, 0x00, 0x00};
Socket_write(clientSocket, startDtCon, 6);
/* Read STOP_DT ACT */
Socket_read(clientSocket, buffer, 100);
/* Do NOT send STOP_DT CON */
/* Wait longer than T1 (1s) */
Thread_sleep(2000);
}
Socket_destroy(clientSocket);
}
ServerSocket_destroy(serverSocket);
}
return NULL;
}
static CS104_ConnectionEvent test_CS104_Connection_StopDTTimeout_event = CS104_CONNECTION_OPENED;
static void
test_CS104_Connection_StopDTTimeout_connectionHandler(void* parameter, CS104_Connection connection,
CS104_ConnectionEvent event)
{
test_CS104_Connection_StopDTTimeout_event = event;
}
void
test_CS104_Connection_StopDTTimeout(void)
{
test_CS104_Connection_StopDTTimeout_event = CS104_CONNECTION_OPENED;
Thread serverThread = Thread_create(silent_server_thread_stop_dt, NULL, false);
Thread_start(serverThread);
Thread_sleep(100);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20006);
TEST_ASSERT_NOT_NULL(con);
CS104_APCIParameters apciParameters = CS104_Connection_getAPCIParameters(con);
apciParameters->t1 = 1;
CS104_Connection_setConnectionHandler(con, test_CS104_Connection_StopDTTimeout_connectionHandler, NULL);
bool connected = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(connected);
CS104_Connection_sendStartDT(con);
/* Wait a bit to ensure START_DT is processed */
Thread_sleep(100);
CS104_Connection_sendStopDT(con);
/* Wait for timeout (T1 = 1s) + some margin */
Thread_sleep(2000);
TEST_ASSERT_EQUAL_INT(CS104_CONNECTION_CLOSED, test_CS104_Connection_StopDTTimeout_event);
CS104_Connection_destroy(con);
Thread_destroy(serverThread);
}
void
test_CS104_Connection_isRunning(void)
{
CS104_Slave slave = CS104_Slave_create(10, 10);
CS104_Slave_setServerMode(slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
CS104_Slave_setLocalPort(slave, 20004);
CS104_Slave_start(slave);
CS104_Connection con = CS104_Connection_create("127.0.0.1", 20004);
TEST_ASSERT_FALSE(CS104_Connection_isConnected(con));
bool result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
TEST_ASSERT_TRUE(CS104_Connection_isConnected(con));
CS104_Connection_sendStartDT(con);
Thread_sleep(500);
TEST_ASSERT_TRUE(CS104_Connection_isConnected(con));
CS104_Connection_sendStopDT(con);
Thread_sleep(500);
TEST_ASSERT_TRUE(CS104_Connection_isConnected(con));
CS104_Connection_close(con);
TEST_ASSERT_FALSE(CS104_Connection_isConnected(con));
result = CS104_Connection_connect(con);
TEST_ASSERT_TRUE(result);
TEST_ASSERT_TRUE(CS104_Connection_isConnected(con));
CS104_Connection_sendStartDT(con);
Thread_sleep(500);
TEST_ASSERT_TRUE(CS104_Connection_isConnected(con));
CS104_Connection_close(con);
TEST_ASSERT_FALSE(CS104_Connection_isConnected(con));
CS104_Connection_destroy(con);
CS104_Slave_destroy(slave);
}
int
main(int argc, char** argv)
{
UNITY_BEGIN();
RUN_TEST(test_version_number);
RUN_TEST(test_CS104_Slave_CreateDestroy);
RUN_TEST(test_CS104_MasterSlave_CreateDestroyLoop);
RUN_TEST(test_CS104_Connection_CreateDestroy);
RUN_TEST(test_CS104_MasterSlave_CreateDestroy);
RUN_TEST(test_CP56Time2a);
RUN_TEST(test_CP56Time2aToMsTimestamp);
RUN_TEST(test_CP56Time2aConversionFunctions);
RUN_TEST(test_StepPositionInformation);
RUN_TEST(test_addMaxNumberOfIOsToASDU);
RUN_TEST(test_SingleEventType);
RUN_TEST(test_SinglePointInformation);
RUN_TEST(test_SinglePointInformationSequence);
RUN_TEST(test_SinglePointWithCP24Time2a);
RUN_TEST(test_SinglePointWithCP56Time2a);
RUN_TEST(test_DoublePointInformation);
RUN_TEST(test_DoublePointWithCP24Time2a);
RUN_TEST(test_DoublePointWithCP56Time2a);
RUN_TEST(test_NormalizeMeasureValueWithoutQuality);
RUN_TEST(test_NormalizeMeasureValue);
RUN_TEST(test_MeasuredValueNormalizedWithCP24Time2a);
RUN_TEST(test_MeasuredValueNormalizedWithCP56Time2a);
RUN_TEST(test_MeasuredValueScaled);
RUN_TEST(test_MeasuredValueScaledWithCP24Time2a);
RUN_TEST(test_MeasuredValueScaledWithCP56Time2a);
RUN_TEST(test_MeasuredValueShort);
RUN_TEST(test_MeasuredValueShortWithCP24Time2a);
RUN_TEST(test_MeasuredValueShortWithCP56Time2a);
RUN_TEST(test_StepPositionInformation);
RUN_TEST(test_StepPositionWithCP24Time2a);
RUN_TEST(test_StepPositionWithCP56Time2a);
RUN_TEST(test_IntegratedTotals);
RUN_TEST(test_IntegratedTotalsWithCP24Time2a);
RUN_TEST(test_IntegratedTotalsWithCP56Time2a);
RUN_TEST(test_SingleCommand);
RUN_TEST(test_SingleCommandWithCP56Time2a);
RUN_TEST(test_DoubleCommand);
RUN_TEST(test_DoubleCommandWithCP56Time2a);
RUN_TEST(test_StepCommandValue);
RUN_TEST(test_StepCommandWithCP56Time2a);
RUN_TEST(test_SetpointCommandNormalized);
RUN_TEST(test_SetpointCommandNormalizedWithCP56Time2a);
RUN_TEST(test_SetpointCommandScaled);
RUN_TEST(test_SetpointCommandScaledWithCP56Time2a);
RUN_TEST(test_SetpointCommandShort);
RUN_TEST(test_SetpointCommandShortWithCP56Time2a);
RUN_TEST(test_InterrogationCommand);
RUN_TEST(test_CounterInterrogationCommand);
RUN_TEST(test_ReadCommand);
RUN_TEST(test_ClockSynchronizationCommand);
RUN_TEST(test_ResetProcessCommand);
RUN_TEST(test_DelayAcquisitionCommand);
RUN_TEST(test_TestCommand);
RUN_TEST(test_TestCommandWithTime);
RUN_TEST(test_BitString32);
RUN_TEST(test_Bitstring32CommandWithCP56Time2a);
RUN_TEST(test_QueryLog);
RUN_TEST(test_FileDirectory);
RUN_TEST(test_FileDirectorySingleEntry);
RUN_TEST(test_BitString32xx_encodeDecode);
RUN_TEST(test_EventOfProtectionEquipmentWithTime);
RUN_TEST(test_IpAddressHandling);
RUN_TEST(test_CS104SlaveConnectionIsRedundancyGroup);
RUN_TEST(test_CS104SlaveSingleRedundancyGroup);
RUN_TEST(test_CS104SlaveSingleRedundancyGroupMultipleConnections);
RUN_TEST(test_CS104SlaveEventQueue1);
RUN_TEST(test_CS104SlaveEventQueueOverflow);
RUN_TEST(test_CS104SlaveEventQueueOverflow2);
RUN_TEST(test_CS104SlaveEventQueueCheckCapacity);
RUN_TEST(test_CS104SlaveEventQueueOverflow3);
RUN_TEST(test_CS104_Connection_ConnectTimeout);
RUN_TEST(test_CS104_Connection_UseAfterClose);
RUN_TEST(test_CS104_Connection_UseAfterServerClosedConnection);
RUN_TEST(test_CS104_Connection_async_success);
RUN_TEST(test_CS104_Connection_async_timeout);
RUN_TEST(test_CS101_ASDU_addObjectOfWrongType);
RUN_TEST(test_CS101_ASDU_addUntilOverflow);
#if (CONFIG_CS104_SUPPORT_TLS == 1)
RUN_TEST(test_CS104_MasterSlave_TLSConnectSuccess);
RUN_TEST(test_CS104_MasterSlave_TLSConnectSuccessWithoutSeparateCACert);
RUN_TEST(test_CS104_MasterSlave_TLSConnectFails);
#ifndef WITH_MBEDTLS3
RUN_TEST(test_CS104_MasterSlave_TLSVersionMismatch);
#endif
#ifdef WITH_MBEDTLS3
RUN_TEST(test_CS104_MasterSlave_TLSVersionMismatch_mbedtls3);
#endif
RUN_TEST(test_CS104_MasterSlave_TLSCipherSuiteMismatch);
RUN_TEST(test_CS104_MasterSlave_TLSCipherSuiteMismatch_TLS_PSK_WITH_AES_256_GCM_SHA384);
RUN_TEST(test_CS104_MasterSlave_TLSClientCertificateNotProvided);
RUN_TEST(test_CS104_MasterSlave_TLSVersionChangeDetected);
///// !!! RUN_TEST(test_CS104_MasterSlave_TLSCertificateSizeExceeded);
RUN_TEST(test_CS104_MasterSlave_TLSCRLExpired);
RUN_TEST(test_CS104_MasterSlave_TLSCertificateExpired);
RUN_TEST(test_CS104_MasterSlave_TLSCertificateRevoked);
RUN_TEST(test_CS104_MasterSlave_TLSInsufficientKeyLength);
RUN_TEST(test_CS104_MasterSlave_TLSInsufficientServerKeyLength);
RUN_TEST(test_CS104_MasterSlave_TLSWarningMinimumKeyLength);
RUN_TEST(test_CS104_MasterSlave_TLSWarningMinimumServerKeyLength);
RUN_TEST(test_CS104_MasterSlave_TLSInvalidSignature);
RUN_TEST(test_CS104_MasterSlave_TLSUnknownCA);
RUN_TEST(test_CS104_MasterSlave_TLSSuccessfulRenegotiation);
RUN_TEST(test_CS104_MasterSlave_TLSRenegotiateAfterCRLUpdate);
RUN_TEST(test_CS104_MasterSlave_TLSRenegotiationCRLExpired);
RUN_TEST(test_CS104_MasterSlave_TLSCertificateRevokedBeforeRenegotiation);
RUN_TEST(test_CS104_MasterSlave_TLSCRLUpdateDuringConnection);
RUN_TEST(test_CS104_MasterSlave_TLSCRLUpdateWithNewRevocation);
RUN_TEST(test_CS104_MasterSlave_TLSCertificateRevokedBeforeReconnect);
RUN_TEST(test_CS104_MasterSlave_TLSUnknownCertificate);
RUN_TEST(test_CS104_MasterSlave_TLSUseSessionResumption);
RUN_TEST(test_CS104_MasterSlave_TLSCertificateSessionResumptionExpiredAtClient);
RUN_TEST(test_CS104_MasterSlave_TLSCertificateSessionResumptionExpiredAtServer);
RUN_TEST(test_CS104_MasterSlave_TLSReuseConfigurationWithSessionResumption);
#endif /* #if (CONFIG_CS104_SUPPORT_TLS == 1) */
RUN_TEST(test_ASDUsetGetNumberOfElements);
RUN_TEST(test_CS101_ASDU_clone);
RUN_TEST(test_CS104SlaveUnconfirmedStoppedMode);
RUN_TEST(test_ScaledNormalizedConversion);
RUN_TEST(test_CS104Connection_cannotWriteToSocketWhenNotConnected);
RUN_TEST(test_CS104Slave_handleTestCommandWithTimestamp);
RUN_TEST(test_CS104Slave_rejectCommandsWithBroadcastCA);
RUN_TEST(test_CS104Slave_rejectCommandWithUnknownCA);
RUN_TEST(test_CS104Slave_handleResetProcessCommand);
RUN_TEST(test_CS104_Connection_sendsTestFrAfterT3TimeoutInactive);
RUN_TEST(test_CS104_Connection_StartDTTimeout);
RUN_TEST(test_CS104_Connection_StopDTTimeout);
RUN_TEST(test_CS104_Connection_isRunning);
return UNITY_END();
}