string IPortAdapter.ReadChars() { System.Text.StringBuilder buffer = new System.Text.StringBuilder(); bool timedOut = false; try { /* There are a few messages that won't end in a NewLine, * so we have to read one character at a time until we run out of them. */ do { // Read one char at a time until the ReadChar times out. try { buffer.Append(GetCharString()); } catch (Exception) { timedOut = true; } } while (!timedOut); } catch (Exception ex) { ServiceMain.HandleEx(ex); throw; } return(buffer.ToString()); }
private void FrameMessage(string InputString) { /* According to the ASTM E1381-95 standard, frames longer than 240 characters * -- 247 characters including frame overhead (<STX>[FrameNumber]...<ETX>[Checksum]<CR><LF>) -- * are sent as one or more intermediate frames followed by an end frame. * Shorter messages are sent as a single end frame. * Intermediate frames use <ETB> in place of <ETX> to indicate that it is continued * in the next frame. * This procedure splits long frames into intermediate frames if necessary * before appending the checksum and <CR><LF> and adding the frame to the message FrameList. * CLSI-LIS1-A increased this frame size to 64,000 including frame overhead. * The use_legacy_frame_size setting in config.yml is used to specify which size to use. */ if (InputString.Length > frameSize + 3) // <STX> + FrameNumber + frame + <ETX> { string firstString = InputString.Substring(0, frameSize + 2); // +2 to make room for the <ETB> int firstStringLength = firstString.Length; int iLength = InputString.Length - firstStringLength; firstString += Constants.ETB; firstString += ServiceMain.CHKSum(firstString); firstString += Constants.CR + Constants.LF; string nextString = InputString.Substring(firstStringLength, iLength); // The remainder of the string FrameList.Add(firstString); // Add intermediate frame to list // is passed to this function recursively FrameMessage(nextString); // to be added as its own frame(s) } else { InputString += ServiceMain.CHKSum(InputString) + Constants.CR + Constants.LF; // Tag on the checksum and <CR><LF> FrameList.Add(InputString); // Add the end frame } }
public void ParseMessageLine(string messageLine) { // Parse each line of the incoming message as it's received. // This is done by assembling the CurrentMessage (a MessageBody) with Header, Patient, Order, Result, etc., records. // Receiving a Header record triggers instantiation of a new MessageBody. // As each subsequent component is received, add it to the CurrentMessage. // The message will be processed by the CommPortDataReceived method when the EOT signal is received. if (messageLine.Length < 5) { ServiceMain.AppendToLog($"Invalid message: {messageLine}"); return; } int position = messageLine.IndexOf(Constants.ETB); if (position >= 0) { bInterFrame = true; if (intermediateFrame?.Length > 2) { intermediateFrame += messageLine.Substring(2, position); } else { intermediateFrame += messageLine.Substring(0, position); } return; // Don't process yet. } else { if (bInterFrame) // If it's an intermediate frame, trim off the frame number and concatenate with previous frame. { intermediateFrame += messageLine.Substring(2, position); messageLine = intermediateFrame; intermediateFrame = ""; bInterFrame = false; } } switch (messageLine.Substring(2, 1)) { case "H": // New message header. CurrentMessage = new Message(messageLine); break; case "P": // Patient record. CurrentMessage.Patients.Add(new Patient(messageLine)); break; case "O": // Order record. CurrentMessage.Patients[^ 1].Orders.Add(new Order(messageLine));
/// <summary> /// The main entry point for the application. /// </summary> static void Main(string[] args) { if (System.Environment.UserInteractive) { // Execute the program as a console app for debugging purposes. ServiceMain service1 = new ServiceMain(); service1.DebuggingRoutine(args); } else { // Run the service normally. ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new ServiceMain() }; ServiceBase.Run(ServicesToRun); } }
void CommPortDataReceived(object sender, EventArgs e) { /* When new data is received, * parse the message line-by-line. */ IPortAdapter port = (IPortAdapter)sender; StringBuilder buffer = new StringBuilder(); try { idleTimer.Stop(); #if DEBUG System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); // This stopwatch is an attempt at performance optimization. #endif /* There are a few messages that won't end in a NewLine, * so we have to read one character at a time until we run out of them. */ // Read one char at a time until the ReadChar times out. try { buffer.Append(port.ReadChars()); } catch (Exception) { #if DEBUG stopwatch.Stop(); #endif } #if DEBUG ServiceMain.AppendToLog($"Elapsed port read time: {stopwatch.ElapsedMilliseconds}"); #endif ServiceMain.AppendToLog($"In: \t{buffer}"); CommState.RcvInput(buffer.ToString()); idleTimer.Start(); } catch (Exception ex) { ServiceMain.HandleEx(ex); throw; } }