/// <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)); }