/// <summary> /// Class constructor /// </summary> /// <param name="messageSubType">ORU Message Sub Type.</param> public OruMessage(System.String messageSubType) : base("ORU", messageSubType) { Hl7Segment segment = new Hl7Segment(1, Hl7SegmentEnum.PID); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(2, Hl7SegmentEnum.PD1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(3, Hl7SegmentEnum.NK1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(4, Hl7SegmentEnum.PV1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(5, Hl7SegmentEnum.PV2); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(6, Hl7SegmentEnum.ORC); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(7, Hl7SegmentEnum.OBR); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(8, Hl7SegmentEnum.NTE); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(9, Hl7SegmentEnum.OBX); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(10, Hl7SegmentEnum.CTI); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(11, Hl7SegmentEnum.DSC); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(12, Hl7SegmentEnum.ZDS); Segments.Add(segment.SegmentId.Id, segment); }
/// <summary> /// Class constructor. /// </summary> /// <param name="messageType">Message Type</param> /// <param name="messageSubType">Message Sub Type</param> public Hl7Message(System.String messageType, System.String messageSubType) { // constructor activities _messageType = messageType; _messageSubType = messageSubType; _segments = new Hashtable(); Hl7Segment segment = new Hl7Segment(0, Hl7SegmentEnum.MSH); _segments.Add(segment.SegmentId.Id, segment); // Set up MSH segment // - use default message delimiters for now Hl7MessageDelimiters messageDelimiters = new Hl7MessageDelimiters(); FieldDelimiter = messageDelimiters.FieldDelimiter; EncodingCharacters = messageDelimiters.ComponentDelimiter + messageDelimiters.RepetitionSeparator + messageDelimiters.EscapeCharacter + messageDelimiters.SubComponentDelimiter; SendingApplication = "DVTK-IHE"; SendingFacility = "DVTK"; ReceivingApplication = "DVTK-IHE"; ReceivingFacility = "DVTK"; ProcessingId = "P"; VersionId = "2.3.1"; if (messageSubType == System.String.Empty) { this.MSH[9] = messageType; } else { this.MSH[9] = messageType + messageDelimiters.ComponentDelimiter + messageSubType; } }
/// <summary> /// Class constructor - ACK /// </summary> /// <param name="messageSubType">ACK Message Sub Type.</param> public AckMessage(System.String messageSubType) : base("ACK", messageSubType) { Hl7Segment segment = new Hl7Segment(1, Hl7SegmentEnum.MSA); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(2, Hl7SegmentEnum.ERR); Segments.Add(segment.SegmentId.Id, segment); }
/// <summary> /// Set the value at the indexed segment. /// </summary> /// <param name="name">Segment Name.</param> /// <param name="fieldIndex">Field Index.</param> /// <param name="val">Field Value.</param> public void AddValue(Hl7SegmentEnum name, int fieldIndex, System.String val) { Hl7SegmentId segmentId = new Hl7SegmentId(name); Hl7Segment hl7Segment = (Hl7Segment)_segments[segmentId.Id]; if (hl7Segment != null) { hl7Segment[fieldIndex] = val; } }
/// <summary> /// Class constructor - ADR /// </summary> /// <param name="messageSubType">ADR Message Sub Type.</param> public AdrMessage(System.String messageSubType) : base("ADR", messageSubType) { Hl7Segment segment = new Hl7Segment(1, Hl7SegmentEnum.MSA); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(2, Hl7SegmentEnum.QRD); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(3, Hl7SegmentEnum.EVN); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(4, Hl7SegmentEnum.PID); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(5, Hl7SegmentEnum.PV1); Segments.Add(segment.SegmentId.Id, segment); }
/// <summary> /// Get the value at the segment/field identified by the tag. /// </summary> /// <param name="tag">Hl7 Tag.</param> /// <returns>String - value at the segment/field identified by the tag.</returns> public System.String Value(Hl7Tag tag) { System.String val = System.String.Empty; Hl7Segment hl7Segment = (Hl7Segment)_segments[tag.SegmentId.Id]; if (hl7Segment != null) { if (tag.FieldIndex < hl7Segment.Count) { val = (System.String)hl7Segment[tag.FieldIndex]; } } return(val); }
/// <summary> /// Class constructor - ADT /// </summary> /// <param name="messageSubType">ADT Message Sub Type.</param> public AdtMessage(System.String messageSubType) : base("ADT", messageSubType) { Hl7Segment segment = new Hl7Segment(1, Hl7SegmentEnum.EVN); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(2, Hl7SegmentEnum.PID); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(3, Hl7SegmentEnum.PD1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(4, Hl7SegmentEnum.NK1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(5, Hl7SegmentEnum.PV1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(6, Hl7SegmentEnum.PV2); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(7, Hl7SegmentEnum.DB1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(8, Hl7SegmentEnum.OBX); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(9, Hl7SegmentEnum.AL1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(10, Hl7SegmentEnum.DG1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(11, Hl7SegmentEnum.DRG); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(12, Hl7SegmentEnum.PR1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(13, Hl7SegmentEnum.ROL); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(14, Hl7SegmentEnum.GT1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(15, Hl7SegmentEnum.IN1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(16, Hl7SegmentEnum.IN2); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(17, Hl7SegmentEnum.IN3); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(18, Hl7SegmentEnum.ACC); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(19, Hl7SegmentEnum.UB1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(20, Hl7SegmentEnum.UB2); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(21, Hl7SegmentEnum.MRG); Segments.Add(segment.SegmentId.Id, segment); }
/// <summary> /// Set the OBX value given at the segment/field index. /// </summary> /// <param name="segmentIndex">OBX Segment Index.</param> /// <param name="fieldIndex">OBX Field Index (within Segment).</param> /// <param name="stringValue">Value to set.</param> public void obxSeg(int segmentIndex, int fieldIndex, System.String stringValue) { Hl7Segment segment = null; if (segmentIndex > 0) { Hl7SegmentId segmentId = new Hl7SegmentId(Hl7SegmentEnum.OBX, segmentIndex); segment = (Hl7Segment)Segments[segmentId.Id]; if (segment == null) { segment = new Hl7Segment(0, Hl7SegmentEnum.OBX); segment.SegmentId.SegmentIndex = segmentIndex; AddSegment(segment); } } segment[fieldIndex] = stringValue; }
/// <summary> /// Class constructor /// </summary> /// <param name="messageSubType">ORM Message Sub Type.</param> public OrmMessage(System.String messageSubType) : base("ORM", messageSubType) { Hl7Segment segment = new Hl7Segment(1, Hl7SegmentEnum.PID); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(2, Hl7SegmentEnum.PD1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(3, Hl7SegmentEnum.PV1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(4, Hl7SegmentEnum.PV2); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(5, Hl7SegmentEnum.IN1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(6, Hl7SegmentEnum.IN2); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(7, Hl7SegmentEnum.IN3); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(8, Hl7SegmentEnum.GT1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(9, Hl7SegmentEnum.AL1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(10, Hl7SegmentEnum.ORC); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(11, Hl7SegmentEnum.OBR); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(12, Hl7SegmentEnum.NTE); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(13, Hl7SegmentEnum.DG1); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(14, Hl7SegmentEnum.OBX); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(15, Hl7SegmentEnum.CTI); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(16, Hl7SegmentEnum.BLG); Segments.Add(segment.SegmentId.Id, segment); segment = new Hl7Segment(17, Hl7SegmentEnum.ZDS); Segments.Add(segment.SegmentId.Id, segment); }
/// <summary> /// Add segment to HL7 message /// </summary> /// <param name="segment"></param> public void AddSegment(Hl7Segment segment) { ICollection segments = _segments.Values; int nextSequenceNumber = segments.Count; // check if the segment is already present if (_segments.Contains(segment.SegmentId.Id) == true) { // remove the segment Hl7Segment tempSegment = (Hl7Segment)_segments[segment.SegmentId.Id]; _segments.Remove(segment.SegmentId.Id); // use the current sequence number segment.SequenceNumber = tempSegment.SequenceNumber; } else { // check to see if a segment already exists of the same type int existingSequenceNumber = 0; int nextSegmentIndex = 0; if (GetNextSegmentIndex(segment.SegmentId.SegmentName, out existingSequenceNumber, out nextSegmentIndex) == true) { // segment exists - this new one must get the existing sequence number and next segment index segment.SequenceNumber = existingSequenceNumber; segment.SegmentId.SegmentIndex = nextSegmentIndex; } else { // segment does not exist - simply give it the next sequence number and start the segment index at 1. segment.SequenceNumber = nextSequenceNumber; segment.SegmentId.SegmentIndex = 1; } } // add the new segment _segments.Add(segment.SegmentId.Id, segment); }
/// <summary> /// Class constructor - QRY /// </summary> /// <param name="messageSubType">QRY Message Sub Type.</param> public QryMessage(System.String messageSubType) : base("QRY", messageSubType) { Hl7Segment segment = new Hl7Segment(1, Hl7SegmentEnum.QRD); Segments.Add(segment.SegmentId.Id, segment); }
// // - Methods - // /// <summary> /// Decode a Hl7Message object from a given stream. /// </summary> /// <param name="stream">The stream.</param> /// <returns>The decoded Hl7Message.</returns> internal Hl7Message Decode(System.IO.Stream stream) { Hl7Message hl7Message = new Hl7Message(); // initialize the message delimiters to the default values _messageDelimiters = new Hl7MessageDelimiters(); // initialise the segment content System.String rxSegment = System.String.Empty; // read the first character from the stream to determine if the MLLP is used int rxCode = stream.ReadByte(); if (rxCode < 0) { throw new System.Exception("Incomplete HL7 stream."); } stream.Seek(0, System.IO.SeekOrigin.Begin); // initialise the MLLP state MllpStateEnum mllpState = MllpStateEnum.MllpNotUsed; if ((char)rxCode == _StartOfMessageChar) { // SOM read - use the MLLP protocol mllpState = MllpStateEnum.WaitingForStartOfMessageChar; } // loop waiting for the end of message character while (_continueReading) { // get the next character from the stream rxCode = stream.ReadByte(); if (rxCode < 0) { // end of stream reached when not using the MLLP // - check if there is any data left in the rxSegment if ((rxSegment != System.String.Empty) && (mllpState == MllpStateEnum.MllpNotUsed)) { // segment is complete Hl7Segment segment = new Hl7Segment(); segment.Decode(rxSegment, _messageDelimiters); // add the segment to the HL7 message hl7Message.AddSegment(segment); } // message is complete _continueReading = false; break; } char rxChar = (char) rxCode; // switch on MLLP state switch(mllpState) { case MllpStateEnum.MllpNotUsed: // check if we have got the end of segment if (rxChar == _EndOfSegmentChar) { // check if we have the MSH segment // - we need to get the message delimiters if (rxSegment.StartsWith("MSH") == true) { // set the message delimiters to the values received // - we assume that the MSH segment is formatted properly at least in the first few bytes _messageDelimiters = new Hl7MessageDelimiters(rxSegment.Substring(3,5)); } // segment is complete Hl7Segment segment = new Hl7Segment(); segment.Decode(rxSegment, _messageDelimiters); // add the segment to the HL7 message hl7Message.AddSegment(segment); // reset the segment rxSegment = System.String.Empty; } else if (rxChar == _NewLineChar) { // ignore the line feed character } else { // save the received character in the current segment rxSegment += rxChar; } break; case MllpStateEnum.WaitingForStartOfMessageChar: // check if we have got the SOM if (rxChar == _StartOfMessageChar) { // reset the segment rxSegment = System.String.Empty; // change state to waiting for end of segment mllpState = MllpStateEnum.WaitingForEndOfSegmentChar; } else { Console.WriteLine("HL7 - MLLP: Waiting for SOM - got {0}...", rxChar); } break; case MllpStateEnum.WaitingForEndOfSegmentChar: // check if we have got the end of segment if (rxChar == _EndOfSegmentChar) { // check if we have the MSH segment // - we need to get the message delimiters if (rxSegment.StartsWith("MSH") == true) { // set the message delimiters to the values received // - we assume that the MSH segment is formatted properly at least in the first few bytes _messageDelimiters = new Hl7MessageDelimiters(rxSegment.Substring(3,5)); } // segment is complete Hl7Segment segment = new Hl7Segment(); segment.Decode(rxSegment, _messageDelimiters); // add the segment to the HL7 message hl7Message.AddSegment(segment); // reset the segment rxSegment = System.String.Empty; } else if (rxChar == _EndOfMessageChar1) { // we have the first end of message - that's OK // check if any characters have been received since the last end of segment if (rxSegment == System.String.Empty) { // change state to waiting for second end of message mllpState = MllpStateEnum.WaitingForEndOfMessageChar; } else { Console.WriteLine("HL7 - MLLP: First EOM does not immediately follow an EOS"); return null; } } else { // save the received character in the current segment rxSegment += rxChar; } break; case MllpStateEnum.WaitingForEndOfMessageChar: // check if we have got the second end of message if (rxChar == _EndOfMessageChar2) { // message is complete _continueReading = false; } else { Console.WriteLine("HL7 - MLLP: Second EOM does not immediately follow first EOM"); return null; } break; default: break; } } // return the correct instantiation of the received HL7 message return Hl7MessageFactory.CreateHl7Message(hl7Message, _messageDelimiters); }
/// <summary> /// Receive an HL7 message over the connected network stream. /// </summary> /// <param name="messageDelimiters">Initial HL7 message delimiters - updated to actual delimters during method.</param> /// <returns>Correctly instantiated HL7 message.</returns> public Hl7Message ReceiveMessage(out Hl7MessageDelimiters messageDelimiters) { // initialize the message delimiters to the default values messageDelimiters = new Hl7MessageDelimiters(); Hl7Message hl7Message = new Hl7Message(); if (_networkStream == null) return null; // set the read / write timeouts for this stream - zero means no timeout. if (_readTimeout != 0) { _networkStream.ReadTimeout = _readTimeout; } if (_writeTimeout != 0) { _networkStream.WriteTimeout = _writeTimeout; } // initialise the segment content System.String rxSegment = System.String.Empty; // initialise the MLLP state MllpStateEnum mllpState = MllpStateEnum.WaitingForStartOfMessageChar; // loop waiting for the end of message character while (mllpState != MllpStateEnum.DoneWaiting) { // check if data is available on network try { // get the next character from the stream int rxCode = _networkStream.ReadByte(); if (rxCode < 0) { return null; } char rxChar = (char) rxCode; // switch on MLLP state switch(mllpState) { case MllpStateEnum.WaitingForStartOfMessageChar: // check if we have got the SOM if (rxChar == _StartOfMessageChar) { // reset the segment rxSegment = System.String.Empty; // change state to waiting for end of segment mllpState = MllpStateEnum.WaitingForEndOfSegmentChar; } else { Console.WriteLine("HL7 - MLLP: Waiting for SOM - got {0}...", rxChar); } break; case MllpStateEnum.WaitingForEndOfSegmentChar: // check if we have got the end of segment if (rxChar == _EndOfSegmentChar) { // check if we have the MSH segment // - we need to get the message delimiters if (rxSegment.StartsWith("MSH") == true) { // set the message delimiters to the values received // - we assume that the MSH segment is formatted properly at least in the first few bytes messageDelimiters = new Hl7MessageDelimiters(rxSegment.Substring(3,5)); } // segment is complete Hl7Segment segment = new Hl7Segment(); segment.Decode(rxSegment, messageDelimiters); // add the segment to the HL7 message hl7Message.AddSegment(segment); // reset the segment rxSegment = System.String.Empty; } else if (rxChar == _EndOfMessageChar1) { // we have the first end of message - that's OK // check if any characters have been received since the last end of segment if (rxSegment == System.String.Empty) { // change state to waiting for second end of message mllpState = MllpStateEnum.WaitingForEndOfMessageChar; } else { Console.WriteLine("HL7 - MLLP: First EOM does not immediately follow an EOS"); return null; } } else { // save the received character in the current segment rxSegment += rxChar; } break; case MllpStateEnum.WaitingForEndOfMessageChar: // check if we have got the second end of message if (rxChar == _EndOfMessageChar2) { // message is complete mllpState = MllpStateEnum.DoneWaiting; } else { Console.WriteLine("HL7 - MLLP: Second EOM does not immediately follow first EOM"); return null; } break; default: break; } } catch (System.Exception e) { Console.WriteLine("HL7 - MLLP: ReceiveMessage() Exception: {0}", e.Message); return null; } } // return the correct instantiation of the received HL7 message return Hl7MessageFactory.CreateHl7Message(hl7Message, messageDelimiters); }
/// <summary> /// Create a correctly typed HL7 message instance based on the incoming Hl7 message. /// </summary> /// <param name="inHl7Message">Incoming HL7 message.</param> /// <param name="messageDelimiters">HL7 message delimiters.</param> /// <returns>Correctly typed HL7 message instance.</returns> public static Hl7Message CreateHl7Message(Hl7Message inHl7Message, Hl7MessageDelimiters messageDelimiters) { Hl7SegmentId segmentId = new Hl7SegmentId(Hl7SegmentEnum.MSH); Hl7Segment mshSegment = (Hl7Segment)inHl7Message.Segments[segmentId.Id]; // can not determine what kind of message we have - so return the inHl7Message if (mshSegment == null) { return(inHl7Message); } System.String messageType = mshSegment[9]; Hl7Message hl7Message = null; // check for ACK message if (messageType == "ACK") { // now try to get the ORC segment segmentId = new Hl7SegmentId(Hl7SegmentEnum.ORC); Hl7Segment orcSegment = (Hl7Segment)inHl7Message.Segments[segmentId.Id]; if (orcSegment != null) { hl7Message = new OrrMessage(); } else { hl7Message = new AckMessage(); } } else { System.String [] messageTypeComponent = new System.String[3]; messageTypeComponent = messageType.Split(messageDelimiters.ComponentDelimiter[0]); System.String messageMainType = System.String.Empty; if (messageTypeComponent.Length > 0) { messageMainType = messageTypeComponent[0]; } switch (messageMainType) { case "ADR": // ADR message hl7Message = new AdrMessage(); break; case "ADT": // ADT message hl7Message = new AdtMessage(); break; case "ORM": // ORM message hl7Message = new OrmMessage(); break; case "ORU": // ORU message hl7Message = new OruMessage(); break; case "QRY": // QRY message hl7Message = new QryMessage(); break; default: // do not know what kind of HL7 message this is - simply return it return(inHl7Message); } } // add the segments from the inMessage to the new hl7Message ICollection segments = inHl7Message.Segments.Values; foreach (Hl7Segment segment in segments) { hl7Message.CopySegment(segment); } return(hl7Message); }
/// <summary> /// Copy segment to HL7 message /// </summary> /// <param name="segment"></param> public void CopySegment(Hl7Segment segment) { // copy the segment by simply adding it to the message _segments.Add(segment.SegmentId.Id, segment); }
// // - Methods - // /// <summary> /// Decode a Hl7Message object from a given stream. /// </summary> /// <param name="stream">The stream.</param> /// <returns>The decoded Hl7Message.</returns> internal Hl7Message Decode(System.IO.Stream stream) { Hl7Message hl7Message = new Hl7Message(); // initialize the message delimiters to the default values _messageDelimiters = new Hl7MessageDelimiters(); // initialise the segment content System.String rxSegment = System.String.Empty; // read the first character from the stream to determine if the MLLP is used int rxCode = stream.ReadByte(); if (rxCode < 0) { throw new System.Exception("Incomplete HL7 stream."); } stream.Seek(0, System.IO.SeekOrigin.Begin); // initialise the MLLP state MllpStateEnum mllpState = MllpStateEnum.MllpNotUsed; if ((char)rxCode == _StartOfMessageChar) { // SOM read - use the MLLP protocol mllpState = MllpStateEnum.WaitingForStartOfMessageChar; } // loop waiting for the end of message character while (_continueReading) { // get the next character from the stream rxCode = stream.ReadByte(); if (rxCode < 0) { // end of stream reached when not using the MLLP // - check if there is any data left in the rxSegment if ((rxSegment != System.String.Empty) && (mllpState == MllpStateEnum.MllpNotUsed)) { // segment is complete Hl7Segment segment = new Hl7Segment(); segment.Decode(rxSegment, _messageDelimiters); // add the segment to the HL7 message hl7Message.AddSegment(segment); } // message is complete _continueReading = false; break; } char rxChar = (char)rxCode; // switch on MLLP state switch (mllpState) { case MllpStateEnum.MllpNotUsed: // check if we have got the end of segment if (rxChar == _EndOfSegmentChar) { // check if we have the MSH segment // - we need to get the message delimiters if (rxSegment.StartsWith("MSH") == true) { // set the message delimiters to the values received // - we assume that the MSH segment is formatted properly at least in the first few bytes _messageDelimiters = new Hl7MessageDelimiters(rxSegment.Substring(3, 5)); } // segment is complete Hl7Segment segment = new Hl7Segment(); segment.Decode(rxSegment, _messageDelimiters); // add the segment to the HL7 message hl7Message.AddSegment(segment); // reset the segment rxSegment = System.String.Empty; } else if (rxChar == _NewLineChar) { // ignore the line feed character } else { // save the received character in the current segment rxSegment += rxChar; } break; case MllpStateEnum.WaitingForStartOfMessageChar: // check if we have got the SOM if (rxChar == _StartOfMessageChar) { // reset the segment rxSegment = System.String.Empty; // change state to waiting for end of segment mllpState = MllpStateEnum.WaitingForEndOfSegmentChar; } else { Console.WriteLine("HL7 - MLLP: Waiting for SOM - got {0}...", rxChar); } break; case MllpStateEnum.WaitingForEndOfSegmentChar: // check if we have got the end of segment if (rxChar == _EndOfSegmentChar) { // check if we have the MSH segment // - we need to get the message delimiters if (rxSegment.StartsWith("MSH") == true) { // set the message delimiters to the values received // - we assume that the MSH segment is formatted properly at least in the first few bytes _messageDelimiters = new Hl7MessageDelimiters(rxSegment.Substring(3, 5)); } // segment is complete Hl7Segment segment = new Hl7Segment(); segment.Decode(rxSegment, _messageDelimiters); // add the segment to the HL7 message hl7Message.AddSegment(segment); // reset the segment rxSegment = System.String.Empty; } else if (rxChar == _EndOfMessageChar1) { // we have the first end of message - that's OK // check if any characters have been received since the last end of segment if (rxSegment == System.String.Empty) { // change state to waiting for second end of message mllpState = MllpStateEnum.WaitingForEndOfMessageChar; } else { Console.WriteLine("HL7 - MLLP: First EOM does not immediately follow an EOS"); return(null); } } else { // save the received character in the current segment rxSegment += rxChar; } break; case MllpStateEnum.WaitingForEndOfMessageChar: // check if we have got the second end of message if (rxChar == _EndOfMessageChar2) { // message is complete _continueReading = false; } else { Console.WriteLine("HL7 - MLLP: Second EOM does not immediately follow first EOM"); return(null); } break; default: break; } } // return the correct instantiation of the received HL7 message return(Hl7MessageFactory.CreateHl7Message(hl7Message, _messageDelimiters)); }