- handle presentation layer data messages with transfer-syntax-name

pull/374/head
Michael Zillgith 4 years ago
parent d5ec52ef78
commit f98c1a956d

@ -1,7 +1,7 @@
/*
* iso_presentation.c
*
* Copyright 2013-2019 Michael Zillgith
* Copyright 2013-2022 Michael Zillgith
*
* This file is part of libIEC61850.
*
@ -234,6 +234,10 @@ parseFullyEncodedData(IsoPresentation* self, uint8_t* buffer, int len, int bufPo
}
break;
case 0x06: /* transfer-syntax-name */
bufPos += length;
break;
case 0xa0:
if (DEBUG_PRES)
printf("PRES: fully-encoded-data\n");
@ -451,12 +455,27 @@ parseNormalModeParameters(IsoPresentation* self, uint8_t* buffer, int totalLengt
bufPos += len;
break;
case 0x83: /* responding-presentation-selector */
if (len > 16) {
if (DEBUG_PRES)
printf("PRES: responding-presentation-sel too large\n");
}
bufPos += len;
break;
case 0xa4: /* presentation-context-definition list */
if (DEBUG_PRES)
printf("PRES: pcd list\n");
bufPos = parsePresentationContextDefinitionList(self, buffer, len, bufPos);
break;
case 0xa5: /* context-definition-result-list */
bufPos += len;
break;
case 0x61: /* user data */
if (DEBUG_PRES)
printf("PRES: user-data\n");
@ -625,12 +644,13 @@ IsoPresentation_createUserDataACSE(IsoPresentation* self, BufferChain writeBuffe
int
IsoPresentation_parseUserData(IsoPresentation* self, ByteBuffer* readBuffer)
{
int length = readBuffer->size;
uint8_t* buffer = readBuffer->buffer;
int maxBufPos = readBuffer->size;
bool hasAbstractSyntaxName = false;
int bufPos = 0;
if (length < 9)
if (maxBufPos < 9)
return 0;
if (buffer[bufPos++] != 0x61)
@ -638,7 +658,7 @@ IsoPresentation_parseUserData(IsoPresentation* self, ByteBuffer* readBuffer)
int len;
bufPos = BerDecoder_decodeLength(buffer, &len, bufPos, length);
bufPos = BerDecoder_decodeLength(buffer, &len, bufPos, maxBufPos);
if (bufPos < 0) {
if (DEBUG_PRES)
@ -649,7 +669,7 @@ IsoPresentation_parseUserData(IsoPresentation* self, ByteBuffer* readBuffer)
if (buffer[bufPos++] != 0x30)
return 0;
bufPos = BerDecoder_decodeLength(buffer, &len, bufPos, length);
bufPos = BerDecoder_decodeLength(buffer, &len, bufPos, maxBufPos);
if (bufPos < 0) {
if (DEBUG_PRES)
@ -657,37 +677,64 @@ IsoPresentation_parseUserData(IsoPresentation* self, ByteBuffer* readBuffer)
return 0;
}
if (buffer[bufPos++] != 0x02)
return 0;
while (bufPos < maxBufPos) {
uint8_t tag = buffer[bufPos++];
uint8_t lenField = buffer[bufPos];
if (buffer[bufPos++] != 0x01)
return 0;
bufPos = BerDecoder_decodeLength(buffer, &len, bufPos, maxBufPos);
self->nextContextId = buffer[bufPos++];
if (bufPos < 0) {
if (DEBUG_PRES)
printf("PRES: wrong parameter length\n");
return 0;
}
if (buffer[bufPos++] != 0xa0)
return 0;
switch (tag) {
case 0x02: /* abstract-syntax-name */
self->nextContextId = buffer[bufPos];
hasAbstractSyntaxName = true;
bufPos += len;
break;
int userDataLength;
case 0x06: /* transfer-syntax-name */
{
/* check if basic-encoding (2.1.1 - 51 01) */
if ((buffer[bufPos] != 0x51) || (buffer[bufPos + 1] != 0x01)) {
if (DEBUG_PRES) {
printf("PRES: unknown transfer-syntax-name\n");
}
uint8_t lengthByte = buffer[bufPos];
return 0;
}
bufPos = BerDecoder_decodeLength(buffer, &userDataLength, bufPos, length);
bufPos += len;
}
break;
if (bufPos < 0) {
if (DEBUG_PRES)
printf("PRES: invalid message!\n");
return 0;
}
if (lengthByte == 0x80) {
/* remove end element from user data length when indefinite length encoded */
userDataLength = userDataLength - 2;
}
case 0xa0: /* presentation data */
{
if (hasAbstractSyntaxName == false) {
if (DEBUG_PRES)
printf("PRES: abstract-syntax-name missing!\n");
ByteBuffer_wrap(&(self->nextPayload), buffer + bufPos, userDataLength, userDataLength);
return 0;
}
return 1;
int userDataLength = len;
if (lenField == 0x80)
userDataLength = userDataLength - 2;
ByteBuffer_wrap(&(self->nextPayload), buffer + bufPos, userDataLength, userDataLength);
return 1;
}
break;
}
}
return 0;
}
int

Loading…
Cancel
Save