diff --git a/examples/iec61850_client_example5/client_example5.c b/examples/iec61850_client_example5/client_example5.c index 5acf11b8..2791428f 100644 --- a/examples/iec61850_client_example5/client_example5.c +++ b/examples/iec61850_client_example5/client_example5.c @@ -50,12 +50,15 @@ main(int argc, char** argv) TSelector localTSelector = { 3, { 0x00, 0x01, 0x02 } }; TSelector remoteTSelector = { 2, { 0x00, 0x01 } }; - SSelector sSelector1 = { 2, { 0, 1 } }; - SSelector sSelector2 = { 5, { 0, 1, 2, 3, 4 } }; + SSelector remoteSSelector = { 2, { 0, 1 } }; + SSelector localSSelector = { 5, { 0, 1, 2, 3, 4 } }; + + PSelector localPSelector = {4, { 0x12, 0x34, 0x56, 0x78 } }; + PSelector remotePSelector = {4, { 0x87, 0x65, 0x43, 0x21 } }; /* change parameters for presentation, session and transport layers */ - IsoConnectionParameters_setRemoteAddresses(parameters, 0x12345678, sSelector1, localTSelector); - IsoConnectionParameters_setLocalAddresses(parameters, 0x87654321, sSelector2, remoteTSelector); + IsoConnectionParameters_setRemoteAddresses(parameters, remotePSelector, remoteSSelector, localTSelector); + IsoConnectionParameters_setLocalAddresses(parameters, localPSelector, localSSelector, remoteTSelector); char* password = "top secret"; diff --git a/src/mms/inc/iso_connection_parameters.h b/src/mms/inc/iso_connection_parameters.h index 9e95c238..cdd04bcb 100644 --- a/src/mms/inc/iso_connection_parameters.h +++ b/src/mms/inc/iso_connection_parameters.h @@ -114,11 +114,26 @@ typedef struct { uint8_t value[4]; /** T-selector value */ } TSelector; +/** + * \brief OSI session selector + * + * To not use S SEL set size to 0 + */ typedef struct { uint8_t size; /** 0 .. 16 - 0 means S-selector is not present */ - uint8_t value[16]; /** P-selector value */ + uint8_t value[16]; /** S-selector value */ } SSelector; +/** + * \brief OSI presentation (P) selector + * + * To not use P SEL set size to 0 + */ +typedef struct { + uint8_t size; /** 0 .. 16 - 0 means P-selector is not present */ + uint8_t value[16]; /** P-selector value */ +} PSelector; + struct sIsoConnectionParameters { AcseAuthenticationParameter acseAuthParameter; @@ -133,14 +148,15 @@ struct sIsoConnectionParameters uint8_t remoteApTitle[10]; int remoteApTitleLen; int remoteAEQualifier; - uint32_t remotePSelector; + PSelector remotePSelector; SSelector remoteSSelector; TSelector remoteTSelector; + uint8_t localApTitle[10]; int localApTitleLen; int localAEQualifier; - uint32_t localPSelector; + PSelector localPSelector; SSelector localSSelector; TSelector localTSelector; @@ -227,7 +243,7 @@ IsoConnectionParameters_setRemoteApTitle(IsoConnectionParameters self, const cha * \param tSelector the T-Selector (ISO transport layer address) */ LIB61850_API void -IsoConnectionParameters_setRemoteAddresses(IsoConnectionParameters self, uint32_t pSelector, SSelector sSelector, TSelector tSelector); +IsoConnectionParameters_setRemoteAddresses(IsoConnectionParameters self, PSelector pSelector, SSelector sSelector, TSelector tSelector); /** * \brief set the local AP-Title and AE-Qualifier @@ -257,7 +273,7 @@ IsoConnectionParameters_setLocalApTitle(IsoConnectionParameters self, const char * \param tSelector the T-Selector (ISO transport layer address) */ LIB61850_API void -IsoConnectionParameters_setLocalAddresses(IsoConnectionParameters self, uint32_t pSelector, SSelector sSelector, TSelector tSelector); +IsoConnectionParameters_setLocalAddresses(IsoConnectionParameters self, PSelector pSelector, SSelector sSelector, TSelector tSelector); /**@}*/ diff --git a/src/mms/inc_private/iso_presentation.h b/src/mms/inc_private/iso_presentation.h index df45185f..367e2995 100644 --- a/src/mms/inc_private/iso_presentation.h +++ b/src/mms/inc_private/iso_presentation.h @@ -1,7 +1,7 @@ /* * iso_presentation.h * - * Copyright 2013 Michael Zillgith + * Copyright 2013-2019 Michael Zillgith * * This file is part of libIEC61850. * @@ -29,8 +29,8 @@ #include "iso_connection_parameters.h" typedef struct { - uint32_t callingPresentationSelector; - uint32_t calledPresentationSelector; + PSelector callingPresentationSelector; + PSelector calledPresentationSelector; uint8_t nextContextId; uint8_t acseContextId; uint8_t mmsContextId; diff --git a/src/mms/iso_common/iso_connection_parameters.c b/src/mms/iso_common/iso_connection_parameters.c index 912b10fd..bb48001f 100644 --- a/src/mms/iso_common/iso_connection_parameters.c +++ b/src/mms/iso_common/iso_connection_parameters.c @@ -113,7 +113,7 @@ IsoConnectionParameters_setRemoteApTitle(IsoConnectionParameters self, const cha } void -IsoConnectionParameters_setRemoteAddresses(IsoConnectionParameters self, uint32_t pSelector, SSelector sSelector, TSelector tSelector) +IsoConnectionParameters_setRemoteAddresses(IsoConnectionParameters self, PSelector pSelector, SSelector sSelector, TSelector tSelector) { self->remotePSelector = pSelector; self->remoteSSelector = sSelector; @@ -133,7 +133,7 @@ IsoConnectionParameters_setLocalApTitle(IsoConnectionParameters self, const char } void -IsoConnectionParameters_setLocalAddresses(IsoConnectionParameters self, uint32_t pSelector, SSelector sSelector, TSelector tSelector) +IsoConnectionParameters_setLocalAddresses(IsoConnectionParameters self, PSelector pSelector, SSelector sSelector, TSelector tSelector) { self->localPSelector = pSelector; self->localSSelector = sSelector; diff --git a/src/mms/iso_mms/client/mms_client_connection.c b/src/mms/iso_mms/client/mms_client_connection.c index 6ae1f383..b943f026 100644 --- a/src/mms/iso_mms/client/mms_client_connection.c +++ b/src/mms/iso_mms/client/mms_client_connection.c @@ -1408,10 +1408,11 @@ MmsConnection_createInternal(TLSConfiguration tlsConfig, bool createThread) /* Load default values for connection parameters */ TSelector tSelector = { 2, { 0, 1 } }; SSelector sSelector = { 2, { 0, 1 } }; + PSelector pSelector = { 4, { 0, 0, 0, 1 } }; - IsoConnectionParameters_setLocalAddresses(self->isoParameters, 1, sSelector, tSelector); + IsoConnectionParameters_setLocalAddresses(self->isoParameters, pSelector, sSelector, tSelector); IsoConnectionParameters_setLocalApTitle(self->isoParameters, "1.1.1.999", 12); - IsoConnectionParameters_setRemoteAddresses(self->isoParameters, 1, sSelector, tSelector); + IsoConnectionParameters_setRemoteAddresses(self->isoParameters, pSelector, sSelector, tSelector); IsoConnectionParameters_setRemoteApTitle(self->isoParameters, "1.1.1.999.1", 12); self->connectTimeout = CONFIG_MMS_CONNECTION_DEFAULT_CONNECT_TIMEOUT; diff --git a/src/mms/iso_presentation/iso_presentation.c b/src/mms/iso_presentation/iso_presentation.c index b956248e..c29f1baf 100644 --- a/src/mms/iso_presentation/iso_presentation.c +++ b/src/mms/iso_presentation/iso_presentation.c @@ -1,7 +1,7 @@ /* * iso_presentation.c * - * Copyright 2013-2018 Michael Zillgith + * Copyright 2013-2019 Michael Zillgith * * This file is part of libIEC61850. * @@ -99,6 +99,7 @@ static void createConnectPdu(IsoPresentation* self, BufferChain writeBuffer, BufferChain payload) { int contentLength = 0; + int i; /* mode-selector */ contentLength += 5; @@ -108,7 +109,9 @@ createConnectPdu(IsoPresentation* self, BufferChain writeBuffer, BufferChain pay /* called- and calling-presentation-selector */ normalModeLength += 12; - int pclLength = 35; + int pclLength = 27; /* 35; */ + pclLength += self->callingPresentationSelector.size; + pclLength += self->calledPresentationSelector.size; normalModeLength += pclLength; @@ -134,18 +137,14 @@ createConnectPdu(IsoPresentation* self, BufferChain writeBuffer, BufferChain pay bufPos = BerEncoder_encodeTL(0xa2, normalModeLength, buffer, bufPos); /* calling-presentation-selector */ - bufPos = BerEncoder_encodeTL(0x81, 4, buffer, bufPos); - buffer[bufPos++] = (uint8_t) ((self->callingPresentationSelector >> 24) & 0xff); - buffer[bufPos++] = (uint8_t) ((self->callingPresentationSelector >> 16) & 0xff); - buffer[bufPos++] = (uint8_t) ((self->callingPresentationSelector >> 8) & 0xff); - buffer[bufPos++] = (uint8_t) (self->callingPresentationSelector & 0xff); + bufPos = BerEncoder_encodeTL(0x81, self->callingPresentationSelector.size, buffer, bufPos); + for (i = 0; i < self->callingPresentationSelector.size; i++) + buffer[bufPos++] = self->callingPresentationSelector.value[i]; /* called-presentation-selector */ - bufPos = BerEncoder_encodeTL(0x82, 4, buffer, bufPos); - buffer[bufPos++] = (uint8_t) ((self->calledPresentationSelector >> 24) & 0xff); - buffer[bufPos++] = (uint8_t) ((self->calledPresentationSelector >> 16) & 0xff); - buffer[bufPos++] = (uint8_t) ((self->calledPresentationSelector >> 8) & 0xff); - buffer[bufPos++] = (uint8_t) (self->calledPresentationSelector & 0xff); + bufPos = BerEncoder_encodeTL(0x82, self->calledPresentationSelector.size, buffer, bufPos); + for (i = 0; i < self->calledPresentationSelector.size; i++) + buffer[bufPos++] = self->calledPresentationSelector.value[i]; /* presentation-context-id list */ bufPos = BerEncoder_encodeTL(0xa4, 35, buffer, bufPos); @@ -384,6 +383,9 @@ parseNormalModeParameters(IsoPresentation* self, uint8_t* buffer, int totalLengt { int endPos = bufPos + totalLength; + self->calledPresentationSelector.size = 0; + self->callingPresentationSelector.size = 0; + while (bufPos < endPos) { uint8_t tag = buffer[bufPos++]; int len; @@ -398,15 +400,37 @@ parseNormalModeParameters(IsoPresentation* self, uint8_t* buffer, int totalLengt switch (tag) { case 0x81: /* calling-presentation-selector */ - if (DEBUG_PRES) - printf("PRES: calling-pres-sel\n"); + + if (len > 16) { + if (DEBUG_PRES) + printf("PRES: calling-presentation-sel too large\n"); + } + else { + self->callingPresentationSelector.size = len; + int i; + for (i = 0; i < len; i++) + self->callingPresentationSelector.value[i] = buffer[bufPos + i]; + } + bufPos += len; break; - case 0x82: /* calling-presentation-selector */ - if (DEBUG_PRES) - printf("PRES: calling-pres-sel\n"); + + case 0x82: /* called-presentation-selector */ + + if (len > 16) { + if (DEBUG_PRES) + printf("PRES: called-presentation-sel too large\n"); + } + else { + self->calledPresentationSelector.size = len; + int i; + for (i = 0; i < len; i++) + self->calledPresentationSelector.value[i] = buffer[bufPos + i]; + } + bufPos += len; break; + case 0xa4: /* presentation-context-definition list */ if (DEBUG_PRES) printf("PRES: pcd list\n");