Exemplo n.º 1
0
        /// <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;
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Class constructor.
 /// </summary>
 public Hl7PeerToPeerConfig() : base()
 {
     //
     // Constructor activities
     //
     _sessionId         = 0;
     _messageDelimiters = new Hl7MessageDelimiters();
 }
Exemplo n.º 3
0
 /// <summary>
 /// Class constructor.
 /// </summary>
 public Hl7PeerToPeerConfig()
     : base()
 {
     //
     // Constructor activities
     //
     _sessionId = 0;
     _messageDelimiters = new Hl7MessageDelimiters();
 }
Exemplo n.º 4
0
        private void ValidateMessage(Hl7Message hl7RequestMessage, Hl7MessageDelimiters messageDelimiters)
        {
            try
            {
                // validate the HL7 message
                System.String facility = hl7RequestMessage.SendingFacility;
                System.String version  = hl7RequestMessage.VersionId;
                if (_hl7ProfileStore != null)
                {
                    // get the validation profile - keyed off the facility, version and messageType
                    System.String messageType = hl7RequestMessage.MessageType;
                    if (hl7RequestMessage.MessageSubType != System.String.Empty)
                    {
                        messageType += ("^" + hl7RequestMessage.MessageSubType);
                    }

                    System.String xmlProfile = _hl7ProfileStore.GetXmlHl7Profile(new Hl7ProfileId(facility, version, messageType));

                    if (_hl7ValidationContext != null)
                    {
                        // get the validation context
                        System.String xmlValidationContext = _hl7ValidationContext.XmlValidationContext;

                        if ((xmlProfile != System.String.Empty) &&
                            (xmlValidationContext != System.String.Empty) &&
                            (_nistWebServiceClient != null))
                        {
                            System.String errorDescription    = System.String.Empty;
                            System.String xmlValidationResult = _nistWebServiceClient.Validate(xmlProfile, xmlValidationContext, hl7RequestMessage.ToString(messageDelimiters), false, out errorDescription);
                            if (errorDescription != System.String.Empty)
                            {
                                _hl7ThreadForHl7Server.LogError(errorDescription);
                            }

                            NistXmlResultsParser xmlParser = new NistXmlResultsParser(xmlValidationResult);
                            _hl7ThreadForHl7Server.UpdateValidationErrorCount(xmlParser.ErrorCount);
                            _hl7ThreadForHl7Server.UpdateValidationWarningCount(xmlParser.WarningCount);
                            _hl7ThreadForHl7Server.WriteXmlStringToResults(xmlParser.RemoveHeader(xmlValidationResult));
                        }
                    }
                }
            }
            catch (System.Exception e)
            {
                System.String message = System.String.Format("NIST Validation Exception: {0} - {1}",
                                                             e.Message, e.StackTrace);
                Console.WriteLine(message);
                _hl7ThreadForHl7Server.LogInformation(message);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Generate string representation to HL7 Message - include the end of segment character.
        /// </summary>
        /// <param name="messageDelimiters">HL7 message delimiters.</param>
        /// <param name="addNewLine">Add new line boolean - for display purposes.</param>
        /// <returns>string - HL7 ER7 format string.</returns>
        private System.String ToString(Hl7MessageDelimiters messageDelimiters, bool addNewLine)
        {
            System.String stringValue = System.String.Empty;

            // stream all the segments - ordered by sequence number and then segment index
            int sequenceNumber = 0;
            int segmentIndex = 1;
            bool streaming = true;
            while (streaming == true)
            {
                bool segmentStreamed = false;
                ICollection segments = _segments.Values;
                foreach (Hl7Segment hl7Segment in segments)
                {
                    if (hl7Segment.SequenceNumber == sequenceNumber)
                    {
                        if (hl7Segment.SegmentId.SegmentIndex == segmentIndex)
                        {
                            System.String encodedStream = hl7Segment.Encode(messageDelimiters);
                            if (encodedStream != System.String.Empty)
                            {
                                stringValue += (encodedStream + _EndOfSegmentChar);

                                if (addNewLine == true)
                                {
                                    // for display purposes only
                                    stringValue += _NewLineChar;
                                }
                            }

                            segmentIndex++;
                            segmentStreamed = true;
                            break;
                        }
                    }
                }

                if (segmentStreamed == false)
                {
                    if (sequenceNumber < _segments.Count)
                    {
                        sequenceNumber++;
                        segmentIndex = 1;
                    }
                    else
                    {
                        streaming = false;
                    }
                }
            }

            return stringValue;
        }
Exemplo n.º 6
0
 /// <summary>
 /// Generate string representation to HL7 Message - include the end of segment character.
 /// </summary>
 /// <param name="messageDelimiters">HL7 message delimiters.</param>
 /// <returns>string - HL7 ER7 format string.</returns>
 public System.String ToString(Hl7MessageDelimiters messageDelimiters)
 {
     return ToString(messageDelimiters, false);
 }
Exemplo n.º 7
0
        private System.String ReplaceString(System.String inputString, Hl7MessageDelimiters messageDelimiters)
        {
            // get the default message delimiters - these will have been used in the HL7 scripts, etc
            Hl7MessageDelimiters defaultMessageDelimiters = new Hl7MessageDelimiters();

            // update the string to use the given message delimiters
            System.String localString1 = inputString.Replace(defaultMessageDelimiters.ComponentDelimiter, messageDelimiters.ComponentDelimiter);
            System.String localString2 = localString1.Replace(defaultMessageDelimiters.SubComponentDelimiter, messageDelimiters.SubComponentDelimiter);
            System.String outputString = localString2.Replace(defaultMessageDelimiters.RepetitionSeparator, messageDelimiters.RepetitionSeparator);

            return outputString;
        }
Exemplo n.º 8
0
        /// <summary>
        /// Encode the segment.
        /// </summary>
        /// <param name="messageDelimiters">HL7 message delimiters to use to encode the message.</param>
        /// <returns>String - encoded segment.</returns>
        public System.String Encode(Hl7MessageDelimiters messageDelimiters)
        {
            System.String segment = System.String.Empty;

            if (_values.Count > 1)
            {
                if (_segmentId.SegmentName == Hl7SegmentEnum.MSH)
                {
                    // initialize the first fields of the MSH segment
                    segment = (System.String)_values[0] + messageDelimiters.ToString() + messageDelimiters.FieldDelimiter;

                    // ecode the rest of the MSH segment from the 3rd field
                    for (int index = 3; index < _values.Count; index++)
                    {
                        segment += ReplaceString((System.String)_values[index], messageDelimiters);;
                        if (index + 1 != _values.Count)
                        {
                            segment += messageDelimiters.FieldDelimiter;
                        }
                    }
                }
                else
                {
                    int index = 0;
                    foreach (System.String val in _values)
                    {
                        segment += ReplaceString(val, messageDelimiters);
                        index++;
                        if (index != _values.Count)
                        {
                            segment += messageDelimiters.FieldDelimiter;
                        }
                    }
                }
            }

            return segment;
        }
Exemplo n.º 9
0
        private void ValidateMessage(Hl7Message hl7ResponseMessage, Hl7MessageDelimiters messageDelimiters)
        {
            try
            {
                // validate the HL7 message
                System.String facility = hl7ResponseMessage.SendingFacility;
                System.String version = hl7ResponseMessage.VersionId;
                if (_hl7ProfileStore != null)
                {
                    // get the validation profile - keyed off the facility, version and messageType
                    System.String messageType = hl7ResponseMessage.MessageType;
                    if (hl7ResponseMessage.MessageSubType != System.String.Empty)
                    {
                        messageType += ("^" + hl7ResponseMessage.MessageSubType);
                    }

                    System.String xmlProfile = _hl7ProfileStore.GetXmlHl7Profile(new Hl7ProfileId(facility, version, messageType));

                    if (_hl7ValidationContext != null)
                    {
                        // get the validation context
                        System.String xmlValidationContext = _hl7ValidationContext.XmlValidationContext;

                        if ((xmlProfile != System.String.Empty) &&
                            (xmlValidationContext != System.String.Empty) &&
                            (_nistWebServiceClient != null))
                        {
                            System.String errorDescription = System.String.Empty;
                            System.String xmlValidationResult = _nistWebServiceClient.Validate(xmlProfile, xmlValidationContext, hl7ResponseMessage.ToString(messageDelimiters), false, out errorDescription);
                            if (errorDescription != System.String.Empty)
                            {
                                _hl7ThreadForHl7Client.LogError(errorDescription);
                            }
                            NistXmlResultsParser xmlParser = new NistXmlResultsParser(xmlValidationResult);
                            _hl7ThreadForHl7Client.UpdateValidationErrorCount(xmlParser.ErrorCount);
                            _hl7ThreadForHl7Client.UpdateValidationWarningCount(xmlParser.WarningCount);
                            _hl7ThreadForHl7Client.WriteXmlStringToResults(xmlParser.RemoveHeader(xmlValidationResult));
                        }
                    }
                }
            }
            catch (System.Exception e)
            {
                System.String message = System.String.Format("NIST Validation Exception: {0} - {1}",
                    e.Message, e.StackTrace);
                Console.WriteLine(message);
                _hl7ThreadForHl7Client.LogInformation(message);
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Send an HL7 message over the connected network stream.
        /// </summary>
        /// <param name="hl7Message">HL7 message to encode.</param>
        /// <param name="messageDelimiters">HL7 message delimiters.</param>
        /// <returns>bool - successful sent = true else false.</returns>
        public bool SendMessage(Hl7Message hl7Message, Hl7MessageDelimiters messageDelimiters)
        {
            if (_networkStream == null) return false;

            // set the read / write timeouts for this stream - zero means no timeout.
            if (_readTimeout != 0)
            {
                _networkStream.ReadTimeout = _readTimeout;
            }
            if (_writeTimeout != 0)
            {
                _networkStream.WriteTimeout = _writeTimeout;
            }

            // write the start of message character
            _networkStream.WriteByte((byte)_StartOfMessageChar);

             			// stream all the segments - ordered by sequence number and then segment index
            int sequenceNumber = 0;
            int segmentIndex = 1;
            bool streaming = true;
            while (streaming == true)
            {
                bool segmentStreamed = false;
                ICollection segments = hl7Message.Segments.Values;
                foreach (Hl7Segment hl7Segment in segments)
                {
                    if (hl7Segment.SequenceNumber == sequenceNumber)
                    {
                        if (hl7Segment.SegmentId.SegmentIndex == segmentIndex)
                        {
                            System.String encodedStream = hl7Segment.Encode(messageDelimiters);
                            if (encodedStream != System.String.Empty)
                            {
                                byte[] buffer = new byte[encodedStream.Length];
                                for (int j = 0; j < encodedStream.Length; j++)
                                {
                                    buffer[j] = (byte) encodedStream[j];
                                }

                                // write the segment
                                _networkStream.Write(buffer, 0, encodedStream.Length);

                                // write the end of segment character
                                _networkStream.WriteByte((byte)_EndOfSegmentChar);
                            }

                            segmentIndex++;
                            segmentStreamed = true;
                            break;
                        }
                    }
                }

                if (segmentStreamed == false)
                {
                    if (sequenceNumber < hl7Message.Segments.Count)
                    {
                        sequenceNumber++;
                        segmentIndex = 1;
                    }
                    else
                    {
                        streaming = false;
                    }
                }
            }

            // write the end of message characters
            _networkStream.WriteByte((byte)_EndOfMessageChar1);
            _networkStream.WriteByte((byte)_EndOfMessageChar2);
            _networkStream.Flush();

            return true;
        }
Exemplo n.º 11
0
        /// <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);
        }
Exemplo n.º 12
0
        private void ProcessTrigger(Hl7Trigger trigger)
        {
            _hl7Mllp = new Hl7Mllp();

            // get the next transaction number - needed to sort the
            // transactions correctly
            int transactionNumber = TransactionNumber.GetNextTransactionNumber();

            System.String message = System.String.Format("HL7 Client thread - connecting to \"{0}\" on port {1}...", _config.ToActorIpAddress, _config.PortNumber);
            _hl7ThreadForHl7Client.LogInformation(message);

            if (_hl7Mllp.Connect(_config.ToActorIpAddress, _config.PortNumber))
            {
                Hl7Message hl7RequestMessage = trigger.Trigger;

                // Set the sending and receiving applications
                hl7RequestMessage.SendingApplication   = _config.FromActorAeTitle;
                hl7RequestMessage.ReceivingApplication = _config.ToActorAeTitle;

                // Add the control id and date/time of message
                hl7RequestMessage.MessageControlId = _messageControlId.ToString();
                _messageControlId++;
                hl7RequestMessage.DateTimeOfMessage = System.DateTime.Now.ToString("yyyyMMddhhmmss", System.Globalization.CultureInfo.InvariantCulture);

                // get initial HL7 message delimiters from the config
                Hl7MessageDelimiters messageDelimiters = _config.MessageDelimiters;

                System.String messageType = hl7RequestMessage.Value(Hl7SegmentEnum.MSH, 9);
                _hl7ThreadForHl7Client.LogInformation(System.String.Format("HL7 Client thread - send message \"{0}\".", messageType));
                _hl7ThreadForHl7Client.LogInformation(hl7RequestMessage.ToString(messageDelimiters));

                if (_hl7Mllp.SendMessage(hl7RequestMessage, messageDelimiters) == true)
                {
                    Hl7Message hl7ResponseMessage = _hl7Mllp.ReceiveMessage(out messageDelimiters);

                    if (hl7ResponseMessage != null)
                    {
                        messageType = hl7ResponseMessage.Value(Hl7SegmentEnum.MSH, 9);
                        _hl7ThreadForHl7Client.LogInformation(System.String.Format("HL7 Client thread - received message \"{0}\".", messageType));
                        _hl7ThreadForHl7Client.LogInformation(hl7ResponseMessage.ToString(messageDelimiters));

                        // Validate the message
                        if (_config.AutoValidate == true)
                        {
                            ValidateMessage(hl7ResponseMessage, messageDelimiters);
                        }

                        // save the transaction
                        Hl7Transaction transaction = new Hl7Transaction(TransactionNameEnum.RAD_1, TransactionDirectionEnum.TransactionSent);
                        transaction.Request  = hl7RequestMessage;
                        transaction.Response = hl7ResponseMessage;

                        ActorsTransaction actorsTransaction = new ActorsTransaction(transactionNumber,
                                                                                    ActorName,             // from actor
                                                                                    ParentActor.ActorName, // to actor
                                                                                    transaction,
                                                                                    _hl7ThreadForHl7Client.Options.ResultsFileNameOnly,
                                                                                    _hl7ThreadForHl7Client.Options.ResultsFullFileName,
                                                                                    (uint)_hl7ThreadForHl7Client.NrErrors,
                                                                                    (uint)_hl7ThreadForHl7Client.NrWarnings);

                        // save the transaction in the Actor log
                        ParentActor.ActorsTransactionLog.Add(actorsTransaction);

                        // publish the transaction event to any interested parties
                        PublishTransactionAvailableEvent(ActorName, actorsTransaction);
                    }
                }

                _hl7Mllp.Stop();

                _hl7ThreadForHl7Client.StopResultsGathering();
                _hl7ThreadForHl7Client.StartResultsGathering();
            }

            if (_awaitCompletion == true)
            {
                _semaphore.Signal();
            }
        }
Exemplo n.º 13
0
        //
        // - 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);
        }
Exemplo n.º 14
0
        /// <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;
        }
Exemplo n.º 15
0
        /// <summary>
        /// Send an HL7 message over the connected network stream.
        /// </summary>
        /// <param name="hl7Message">HL7 message to encode.</param>
        /// <param name="messageDelimiters">HL7 message delimiters.</param>
        /// <returns>bool - successful sent = true else false.</returns>
        public bool SendMessage(Hl7Message hl7Message, Hl7MessageDelimiters messageDelimiters)
        {
            if (_networkStream == null)
            {
                return(false);
            }

            // set the read / write timeouts for this stream - zero means no timeout.
            if (_readTimeout != 0)
            {
                _networkStream.ReadTimeout = _readTimeout;
            }
            if (_writeTimeout != 0)
            {
                _networkStream.WriteTimeout = _writeTimeout;
            }

            // write the start of message character
            _networkStream.WriteByte((byte)_StartOfMessageChar);

            // stream all the segments - ordered by sequence number and then segment index
            int  sequenceNumber = 0;
            int  segmentIndex   = 1;
            bool streaming      = true;

            while (streaming == true)
            {
                bool        segmentStreamed = false;
                ICollection segments        = hl7Message.Segments.Values;
                foreach (Hl7Segment hl7Segment in segments)
                {
                    if (hl7Segment.SequenceNumber == sequenceNumber)
                    {
                        if (hl7Segment.SegmentId.SegmentIndex == segmentIndex)
                        {
                            System.String encodedStream = hl7Segment.Encode(messageDelimiters);
                            if (encodedStream != System.String.Empty)
                            {
                                byte[] buffer = new byte[encodedStream.Length];
                                for (int j = 0; j < encodedStream.Length; j++)
                                {
                                    buffer[j] = (byte)encodedStream[j];
                                }

                                // write the segment
                                _networkStream.Write(buffer, 0, encodedStream.Length);

                                // write the end of segment character
                                _networkStream.WriteByte((byte)_EndOfSegmentChar);
                            }

                            segmentIndex++;
                            segmentStreamed = true;
                            break;
                        }
                    }
                }

                if (segmentStreamed == false)
                {
                    if (sequenceNumber < hl7Message.Segments.Count)
                    {
                        sequenceNumber++;
                        segmentIndex = 1;
                    }
                    else
                    {
                        streaming = false;
                    }
                }
            }

            // write the end of message characters
            _networkStream.WriteByte((byte)_EndOfMessageChar1);
            _networkStream.WriteByte((byte)_EndOfMessageChar2);
            _networkStream.Flush();

            return(true);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Decode the segment. The HL7 message delimiters has been set to the correct value before calling this method.
        /// </summary>
        /// <param name="segmentString">Encoded segment string.</param>
        /// <param name="messageDelimiters">HL7 message delimiters to use to encode the message.</param>
        public void Decode(System.String segmentString, Hl7MessageDelimiters messageDelimiters)
        {
            int index = 0;
            System.String val = System.String.Empty;
            int i = 0;
            bool isVal = false;
            while (i < segmentString.Length)
            {
                if (segmentString.Substring(i,1) == messageDelimiters.FieldDelimiter)
                {
                    _values.Insert(index, val);
                    index++;

                    if ((index == 1) &&
                        ((System.String)_values[0] == "MSH"))
                    {
                        // special insert for the field delimiter itself.
                        _values.Insert(index, messageDelimiters.FieldDelimiter);
                        index++;
                    }

                    val = System.String.Empty;
                    isVal = false;
                }
                else
                {
                    val += segmentString[i];
                    isVal = true;
                }
                i++;
            }

            if (isVal == true)
            {
                _values.Insert(index, val);
            }

            if (_values.Count > 0)
            {
                // use segment index 0 here - the correct value will be determined when the segment is added to the message
                _segmentId = new Hl7SegmentId(SegmentNames.NameEnum((System.String)_values[0]), 0);
            }
        }
Exemplo n.º 17
0
        /// <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));
        }
Exemplo n.º 18
0
        /// <summary>
        /// Process Hl7 requests and responses.
        /// </summary>
        public void ProcessMessages()
        {
            _hl7Mllp = new Hl7Mllp();

            for (;;)
            {
                System.String message = System.String.Format("Listening for incoming HL7 connection on port {0}...", _config.PortNumber);
                _hl7ThreadForHl7Server.LogInformation(message);

                try
                {
                    // listen for a connection
                    _hl7Mllp.Listen(_config.PortNumber);

                    for (;;)
                    {
                        // accept the connection - only one at a time
                        _hl7Mllp.Accept();

                        // the message delimiters will be filled in by the ReceiveMessage method
                        Hl7MessageDelimiters messageDelimiters = null;

                        // receive an HL7 message
                        Hl7Message hl7RequestMessage = _hl7Mllp.ReceiveMessage(out messageDelimiters);
                        if (hl7RequestMessage != null)
                        {
                            System.String messageType = hl7RequestMessage.Value(Hl7SegmentEnum.MSH, 9);
                            message = System.String.Format("HL7 Server thread - received message \"{0}\".", messageType);
                            _hl7ThreadForHl7Server.LogInformation(message);
                            _hl7ThreadForHl7Server.LogInformation(hl7RequestMessage.ToString(messageDelimiters));

                            // Validate the message
                            if (_config.AutoValidate == true)
                            {
                                ValidateMessage(hl7RequestMessage, messageDelimiters);
                            }

                            // call the message handler to get a response
                            Hl7Message hl7ResponseMessage = MessageHandler(hl7RequestMessage);

                            // copy some fields from the request
                            hl7ResponseMessage.SendingApplication   = hl7RequestMessage.ReceivingApplication;
                            hl7ResponseMessage.SendingFacility      = hl7RequestMessage.ReceivingFacility;
                            hl7ResponseMessage.ReceivingApplication = hl7RequestMessage.SendingApplication;
                            hl7ResponseMessage.ReceivingFacility    = hl7RequestMessage.SendingFacility;
                            hl7ResponseMessage.MessageControlId     = hl7RequestMessage.MessageControlId;

                            // set the date/time of message
                            hl7ResponseMessage.DateTimeOfMessage = System.DateTime.Now.ToString("yyyyMMddhhmmss", System.Globalization.CultureInfo.InvariantCulture);

                            // send the response
                            _hl7Mllp.SendMessage(hl7ResponseMessage, messageDelimiters);

                            messageType = hl7ResponseMessage.Value(Hl7SegmentEnum.MSH, 9);
                            message     = System.String.Format("HL7 Server thread - sent message \"{0}\".", messageType);
                            _hl7ThreadForHl7Server.LogInformation(message);
                            _hl7ThreadForHl7Server.LogInformation(hl7ResponseMessage.ToString(messageDelimiters));

                            // get the next transaction number - needed to sort the
                            // transactions correctly
                            int transactionNumber = TransactionNumber.GetNextTransactionNumber();

                            // save the transaction
                            Hl7Transaction transaction = new Hl7Transaction(TransactionNameEnum.RAD_1, TransactionDirectionEnum.TransactionReceived);
                            transaction.Request  = hl7RequestMessage;
                            transaction.Response = hl7ResponseMessage;

                            _hl7ThreadForHl7Server.LogInformation(String.Format("{0} - received Hl7 event from {1}", ParentActor.ActorName, ActorName));

                            ActorsTransaction actorsTransaction = new ActorsTransaction(transactionNumber,
                                                                                        ActorName,             // from actor
                                                                                        ParentActor.ActorName, // to actor
                                                                                        transaction,
                                                                                        _hl7ThreadForHl7Server.Options.ResultsFileNameOnly,
                                                                                        _hl7ThreadForHl7Server.Options.ResultsFullFileName,
                                                                                        (uint)_hl7ThreadForHl7Server.NrErrors,
                                                                                        (uint)_hl7ThreadForHl7Server.NrWarnings);

                            // save the transaction in the Actor log
                            ParentActor.ActorsTransactionLog.Add(actorsTransaction);

                            // publish the transaction event to any interested parties
                            PublishTransactionAvailableEvent(ActorName, actorsTransaction);
                        }

                        _hl7Mllp.Close();

                        _hl7ThreadForHl7Server.StopResultsGathering();
                        _hl7ThreadForHl7Server.StartResultsGathering();
                    }
                }
                catch
                {
                    // System.Net.Sockets.Socket.Accept() exception thrown when the server is stopped by closing the listen socket.
                    break;
                }
            }
        }