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

Loading…
Cancel
Save