int parseUserInformation(byte[] buffer, int bufPos, int maxBufPos, ref bool userInfoValid) { iecs.logger.LogDebug(String.Format("ACSE: parseUserInformation {0} {1}", bufPos, maxBufPos)); bool hasindirectReference = false; bool isDataValid = false; while (bufPos < maxBufPos) { byte tag = buffer[bufPos++]; int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); switch (tag) { case 0x02: /* indirect-reference */ nextReference = IsoUtil.BerDecoder_decodeUint32(buffer, len, bufPos); bufPos += len; hasindirectReference = true; break; case 0xa0: /* encoding */ isDataValid = true; userDataBufferSize = len; userDataBufferIndex = bufPos; bufPos += len; break; default: /* ignore unknown tag */ bufPos += len; break; } } if (!hasindirectReference) { iecs.logger.LogDebug("ACSE: User data has no indirect reference!"); } if (!isDataValid) { iecs.logger.LogDebug("ACSE: No valid user data"); } if (hasindirectReference && isDataValid) { userInfoValid = true; } else { userInfoValid = false; } return(bufPos); }
AcseIndication parseAarePdu(byte[] buffer, int bufPos, int maxBufPos) { iecs.logger.LogDebug("ACSE: parse AARE PDU"); bool userInfoValid = false; uint result = 99; while (bufPos < maxBufPos) { byte tag = buffer[bufPos++]; int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); switch (tag) { case 0xa1: /* application context name */ bufPos += len; break; case 0xa2: /* result */ bufPos++; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); result = IsoUtil.BerDecoder_decodeUint32(buffer, len, bufPos); bufPos += len; break; case 0xa3: /* result source diagnostic */ bufPos += len; break; case 0xbe: /* user information */ if (buffer[bufPos] != 0x28) { iecs.logger.LogDebug("ACSE: invalid user info"); bufPos += len; } else { bufPos++; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); bufPos = parseUserInformation(buffer, bufPos, bufPos + len, ref userInfoValid); } break; default: /* ignore unknown tag */ iecs.logger.LogDebug(String.Format("ACSE: parseAarePdu: unknown tag 0x{0:X2}", tag)); bufPos += len; break; } } if (!userInfoValid) { return(AcseIndication.ACSE_ERROR); } if (result != 0) { return(AcseIndication.ACSE_ASSOCIATE_FAILED); } return(AcseIndication.ACSE_ASSOCIATE); }
int parsePCDLEntry(byte[] buffer, int totalLength, int bufPos) { int endPos = bufPos + totalLength; int contextId = -1; bool isAcse = false; bool isMms = false; while (bufPos < endPos) { byte tag = buffer[bufPos++]; int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, endPos); switch (tag) { case 0x02: /* presentation-context-identifier */ contextId = (int)IsoUtil.BerDecoder_decodeUint32(buffer, len, bufPos); bufPos += len; break; case 0x06: /* abstract-syntax-name */ iecs.logger.LogDebug(String.Format("PRES: abstract-syntax-name with len {0}", len)); if (len == 5) { isMms = true; for (int i = 0; i < 5; i++) { if (buffer[bufPos + i] != asn_id_mms[i]) { isMms = false; } } //if (memcmp(buffer + bufPos, asn_id_mms, 5) == 0) // isMms = true; } else if (len == 4) { isAcse = true; for (int i = 0; i < 4; i++) { if (buffer[bufPos + i] != asn_id_as_acse[i]) { isAcse = false; } } //if (memcmp(buffer + bufPos, asn_id_as_acse, 4) == 0) // isAcse = true; } bufPos += len; break; case 0x30: /* transfer-syntax-name */ iecs.logger.LogDebug("PRES: ignore transfer-syntax-name"); bufPos += len; break; default: iecs.logger.LogDebug("PRES: unknown tag in presentation-context-definition-list-entry"); bufPos += len; break; } } if (contextId < 0) { iecs.logger.LogDebug("PRES: ContextId not defined!"); return(-1); } if ((isAcse == false) && (isMms == false)) { iecs.logger.LogDebug("PRES: not an ACSE nor MMS context definition"); return(-1); } if (isMms) { mmsContextId = (byte)contextId; iecs.logger.LogDebug(String.Format("PRES: MMS context id is {0}", contextId)); } else { acseContextId = (byte)contextId; iecs.logger.LogDebug(String.Format("PRES: ACSE context id is {0}", contextId)); } return(bufPos); }
/// <summary> /// Parses Iso presentation connect message /// </summary> /// <param name="buffer">Data buffer</param> /// <param name="offset">Index of the first message byte</param> /// <param name="length">Length of the buffer from offset to end</param> /// <returns>Index to the user data (payload) in the absolute numbering (from the buffer index 0)</returns> public int parseConnect(byte[] buffer, int offset, int length) { int maxBufPos = offset + length; int bufPos = offset; byte cpTag = buffer[bufPos++]; if (cpTag != 0x31) { iecs.logger.LogDebug("PRES: not a CP type"); return(0); } int len = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); iecs.logger.LogDebug(String.Format("PRES: CPType with len {0}", len)); while (bufPos < maxBufPos) { byte tag = buffer[bufPos++]; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); if (bufPos < 0) { iecs.logger.LogDebug("PRES: wrong parameter length\n"); return(0); } switch (tag) { case 0xa0: /* mode-selection */ { if (buffer[bufPos++] != 0x80) { iecs.logger.LogDebug("PRES: mode-value of wrong type!"); return(0); } bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, maxBufPos); uint modeSelector = IsoUtil.BerDecoder_decodeUint32(buffer, len, bufPos); iecs.logger.LogDebug(String.Format("PRES: modesel {0}", modeSelector)); bufPos += len; } break; case 0xa2: /* normal-mode-parameters */ bufPos = parseNormalModeParameters(buffer, len, bufPos); if (bufPos < 0) { iecs.logger.LogDebug("PRES: error parsing normal-mode-parameters"); return(0); } break; default: /* unsupported element */ iecs.logger.LogDebug(String.Format("PRES: tag 0x{0:X2} not recognized\n", tag)); bufPos += len; break; } } return(bufPos); }
int parseFullyEncodedData(byte[] buffer, int len, int bufPos) { int presentationSelector = -1; bool userDataPresent = false; int endPos = bufPos + len; if (buffer[bufPos++] != 0x30) { iecs.logger.LogDebug("PRES: user-data parse error"); return(-1); } bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref len, bufPos, endPos); endPos = bufPos + len; if (bufPos < 0) { iecs.logger.LogDebug("PRES: wrong parameter length"); return(-1); } while (bufPos < endPos) { byte tag = buffer[bufPos++]; int length = 0; bufPos = IsoUtil.BerDecoder_decodeLength(buffer, ref length, bufPos, endPos); if (bufPos < 0) { iecs.logger.LogDebug("PRES: wrong parameter length"); return(-1); } switch (tag) { case 0x02: /* presentation-context-identifier */ iecs.logger.LogDebug("PRES: presentation-context-identifier"); { presentationSelector = (int)IsoUtil.BerDecoder_decodeUint32(buffer, length, bufPos); nextContextId = (byte)presentationSelector; bufPos += length; } break; case 0xa0: iecs.logger.LogDebug("PRES: fully-encoded-data"); userDataPresent = true; nextPayload_bufferIndex = bufPos; nextPayload_size = length; bufPos += length; break; default: iecs.logger.LogDebug(String.Format("PRES: fed: unknown tag 0x{0:X2}", tag)); bufPos += length; break; } } if (!userDataPresent) { iecs.logger.LogDebug("PRES: user-data not present\n"); return(-1); } return(bufPos); }