9634 lines
378 KiB
C
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(¤tTime, currentTimestamp);
|
|
|
|
uint64_t convertedTimestamp = CP56Time2a_toMsTimestamp(¤tTime);
|
|
|
|
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, ×tamp);
|
|
|
|
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();
|
|
}
|