// Confirm to remote device that firmware was completely transmitted private void sendUpdateComplete() { byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength - 1]; transferData[0] = (byte)Commands.CMD_UPDATE_COMPLETE; expectedAck = AckTypes.COMPLETE_ACK; SendDataAndWait(transferData); }
private void SetACK(AckTypes ackType, String messageString) { Terser terser = new Terser(hl7Ack.Message); ISegment err = terser.getSegment("/ERR(0)"); ISegment criticalSegment = TryToRecoverCriticalDataFromMessage(messageString); try { FillMSHSegment((ISegment)hl7Ack.Message.GetStructure("MSH"), criticalSegment); if (criticalSegment == null) { terser.Set("/MSA-1", Enum.GetName(typeof(AckTypes), ackType)); terser.Set("/MSA-2", ""); } else { terser.Set("/MSA-1", Enum.GetName(typeof(AckTypes), ackType)); terser.Set("/MSA-2", Terser.Get(criticalSegment, 10, 0, 1, 1)); } } catch (HL7Exception he) { _errorMessage.Append(he.Message); return; //do not throw exceptions; } //terser.Set("ERR(0)-7", _errorMessage); terser.Set("/ERR(0)-7-1-1", _errorMessage.ToString()); }
// Initiate search for compatible RF device public void connect() { byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength - 1]; transferData[0] = (byte)Commands.CMD_INIT; SendDataAndWait(transferData); StatusUpdate(this, new MessageEventArgs("Searching for compatible device.")); expectedAck = AckTypes.INIT_ACK; }
// Starts verification, called once for every line. Sends requests for hex Lines to device. public void requestLine() { byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength - 1]; transferData[0] = (byte)Commands.CMD_READ; // Attach size of line and msb and lsb of address . transferData[1] = hexLines[verifiedLines][HEX_LINE_SIZE_INDEX]; transferData[2] = hexLines[verifiedLines][HEX_LINE_MSB_ADDR_INDEX]; transferData[3] = hexLines[verifiedLines][HEX_LINE_LSB_ADDR_INDEX]; expectedAck = AckTypes.READ_ACK; SendDataAndWait(transferData); }
// Send a Hex line private void sendLine() { byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength - 1]; transferData[0] = (byte)Commands.CMD_WRITE; List <byte> tempLine = hexLines[sentLines]; for (int B = 0; B < tempLine.Count; B++) { transferData[1 + B] = tempLine[B]; } expectedAck = AckTypes.LINE_ACK; //StatusUpdate(this, new MessageEventArgs("Sending Line.")); SendDataAndWait(transferData); }
// Called when cancel button of progress dialog pushed. // Aborts transfers and sends new init to remote device. public void cancel() { StatusUpdate(this, new MessageEventArgs("Cancelling and reconnecting.")); // Disable sending and receiving of data aborting = true; // Wait while other thread is finishing it's current calls. System.Threading.Thread.Sleep(200); // Enable communication and send a init command to restart the connection. aborting = false; byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength - 1]; transferData[0] = (byte)Commands.CMD_INIT; expectedAck = AckTypes.INIT_ACK; SendDataAndWait(transferData); }
internal void SetACK(AckTypes ackType, String messageString, IMessage message) { if (message == null) { SetACK(ackType, messageString); return; } Terser inboundTerser = new Terser(message); ISegment inboundHeader = inboundTerser.getSegment("MSH"); string version = null; version = message.Version; if (string.IsNullOrEmpty(version)) { try { version = Terser.Get(inboundHeader, 12, 0, 1, 1); } catch (NHapi.Base.HL7Exception he) { version = NHapi.Model.V251.Constants.VERSION; } } FillMSHSegment((ISegment)message.GetStructure("MSH"), (ISegment)hl7Ack.Message.GetStructure("MSH")); string messageTypeName = message.GetMessageType(); string acktype = HL7Parser.GetAckTypeFromRequest(messageTypeName, version); string AckID = HL7Parser.GetMessageIDFromMessageType(acktype, version); hl7Ack.SetValue("/MSH(0)-21-1", AckID); //MEssage Code if (acktype.Split('_').Length > 1) { hl7Ack.SetValue("/MSH-9-1-1", acktype.Split('_')[0]); //MEssage Code hl7Ack.SetValue("/MSH-9-2-1", acktype.Split('_')[1]); //MEssage Code } //ackTerser.Set("/MSH-12", NHapi.Model.V251.Constants.VERSION); hl7Ack.SetValue("/MSA-1", Enum.GetName(typeof(AckTypes), ackType)); string code = Terser.Get(inboundHeader, 10, 0, 1, 1); hl7Ack.SetValue("/MSA-2", Terser.Get(inboundHeader, 10, 0, 1, 1)); }
// Sends initiate update command along with number of bytes and hex lines, // the starting long jump instruction of the Hex and a checksum. public void flashRemote(bool autoVerify) { this.autoVerify = autoVerify; if (validHexLoaded) { byte checksum = 0; byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength - 1]; transferData[0] = (byte)Commands.CMD_UPDATE_START; // Split 16 bit bytecount in two bytes transferData[1] = (byte)(byteCount >> 8); transferData[2] = (byte)byteCount; // Send Long jump as part of init packet transferData[3] = longJumpAddress[0]; transferData[4] = longJumpAddress[1]; transferData[5] = longJumpAddress[2]; // Byte indicating version of new firmware transferData[6] = newVersion; // Generate checksum for linecount and Long jump address for (int i = 1; i <= 6; i++) { checksum += transferData[i]; } transferData[7] = (byte)-checksum; if (StatusUpdate != null) { StatusUpdate(this, new MessageEventArgs("Initiating firmware update.")); } sentLines = 0; expectedAck = AckTypes.UPDATE_START_ACK; SendDataAndWait(transferData); } else { if (StatusUpdate != null) { StatusUpdate(this, new MessageEventArgs("ERROR: Tried flashing invalid hex.")); } } }
/// <summary> /// Builds an Ack message to acknowledge a message /// </summary> /// <param name="id">ID of the message to acknowledge</param> /// <param name="type">Type of the acknowledge message</param> public AckMessage(long id, AckTypes type) { _id = id; _type = type; _data = null; }
// Starts verification, called once for every line. Sends requests for hex Lines to device. public void requestLine() { byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength-1]; transferData[0] = (byte)Commands.CMD_READ; // Attach size of line and msb and lsb of address . transferData[1] = hexLines[verifiedLines][HEX_LINE_SIZE_INDEX]; transferData[2] = hexLines[verifiedLines][HEX_LINE_MSB_ADDR_INDEX]; transferData[3] = hexLines[verifiedLines][HEX_LINE_LSB_ADDR_INDEX]; expectedAck = AckTypes.READ_ACK; SendDataAndWait(transferData); }
// Sends initiate update command along with number of bytes and hex lines, // the starting long jump instruction of the Hex and a checksum. public void flashRemote(bool autoVerify) { this.autoVerify = autoVerify; if (validHexLoaded) { byte checksum = 0; byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength - 1]; transferData[0] = (byte)Commands.CMD_UPDATE_START; // Split 16 bit bytecount in two bytes transferData[1] = (byte)(byteCount >> 8); transferData[2] = (byte)byteCount; // Send Long jump as part of init packet transferData[3] = longJumpAddress[0]; transferData[4] = longJumpAddress[1]; transferData[5] = longJumpAddress[2]; // Byte indicating version of new firmware transferData[6] = newVersion; // Generate checksum for linecount and Long jump address for (int i = 1; i <= 6; i++) { checksum += transferData[i]; } transferData[7] = (byte)-checksum; if (StatusUpdate != null) StatusUpdate(this, new MessageEventArgs("Initiating firmware update.")); sentLines = 0; expectedAck = AckTypes.UPDATE_START_ACK; SendDataAndWait(transferData); } else { if (StatusUpdate != null) StatusUpdate(this, new MessageEventArgs("ERROR: Tried flashing invalid hex.")); } }
/// <summary> /// Generate an Ack message based on current message. /// </summary> /// <param name="message">Current message object</param> /// <param name="ackType">Ack response type</param> /// <param name="appCommName">Application communication name</param> /// <param name="envName">Environment name</param> /// <param name="errorMessage">Error message to include in Ack (in case op AE or AR)</param> /// <returns>Ack message based on the current message</returns> public static IMessage GenerateAck(this IMessage message, AckTypes ackType, string appCommName, string envName, string errorMessage) { Ack ack = new Ack(appCommName, envName); return(ack.MakeACK(message, ackType, errorMessage)); }
// Determines suitable response for received ack private void HandleAck(byte[] packet) { switch (expectedAck) { case AckTypes.NO_ACK: // Got ack when none expected, do nothing break; case AckTypes.INIT_ACK: // Awaiting initial ack. Store provided info and notify gui. { model = packet[1]; version = packet[2]; this.DeviceConnected(this, new ConnectionEventArgs(model, version)); StatusUpdate(this, new MessageEventArgs("Connected to remote device.")); } break; case AckTypes.UPDATE_START_ACK: // Our request for firmware update approved. { // Notify gui if (UpdateStarted != null) { UpdateStarted(this, EventArgs.Empty); } expectedAck = AckTypes.NO_ACK; StatusUpdate(this, new MessageEventArgs("Got update approval from device.")); // Send first line sendLine(); } break; case AckTypes.LINE_ACK: { // Sent line was confirmed received reSends = 0; sentLines++; // Notify gui of current progress UpdateProgressChanged(this, new ProgressEventArgs((double)sentLines / lineCount)); if (sentLines != lineCount) { sendLine(); } else { // This was the final line, start verifying if verify box checked UpdateComplete(this, new BoolEventArgs(true)); if (autoVerify) { startVerification(); } else { // If not, notify device of complete transfer sendUpdateComplete(); } } } break; case AckTypes.COMPLETE_ACK: // Ack for update complete message, notify gui. { expectedAck = AckTypes.NO_ACK; StatusUpdate(this, new MessageEventArgs("Device confirmed update complete.")); if (ReadyToRun != null) { ReadyToRun(this, EventArgs.Empty); } } break; case AckTypes.READ_ACK: // Answer to request for a flash memory line. // Copy and start verification { expectedAck = AckTypes.NO_ACK; packet.CopyTo(receivedLine, 0); verifyFlashLine(); } break; } }
/// <summary> /// Generate an Ack message based on current message. /// </summary> /// <param name="message">Current message object</param> /// <param name="ackType">Ack response type</param> /// <param name="appCommName">Application communication name</param> /// <param name="envName">Environment name</param> /// <returns>Ack message based on the current message</returns> public static IMessage GenerateAck(this IMessage message, AckTypes ackType, string appCommName, string envName) { return(GenerateAck(message, ackType, appCommName, envName, null)); }
// Initiate search for compatible RF device public void connect() { byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength-1]; transferData[0] = (byte)Commands.CMD_INIT; SendDataAndWait(transferData); StatusUpdate(this, new MessageEventArgs("Searching for compatible device.")); expectedAck = AckTypes.INIT_ACK; }
// Determines suitable response for received ack private void HandleAck(byte[] packet) { switch (expectedAck) { case AckTypes.NO_ACK: // Got ack when none expected, do nothing break; case AckTypes.INIT_ACK: // Awaiting initial ack. Store provided info and notify gui. { model = packet[1]; version = packet[2]; this.DeviceConnected(this, new ConnectionEventArgs(model, version)); StatusUpdate(this, new MessageEventArgs("Connected to remote device.")); } break; case AckTypes.UPDATE_START_ACK: // Our request for firmware update approved. { // Notify gui if (UpdateStarted != null) UpdateStarted(this, EventArgs.Empty); expectedAck = AckTypes.NO_ACK; StatusUpdate(this, new MessageEventArgs("Got update approval from device.")); // Send first line sendLine(); } break; case AckTypes.LINE_ACK: { // Sent line was confirmed received reSends = 0; sentLines++; // Notify gui of current progress UpdateProgressChanged(this, new ProgressEventArgs((double)sentLines / lineCount)); if (sentLines != lineCount) { sendLine(); } else { // This was the final line, start verifying if verify box checked UpdateComplete(this, new BoolEventArgs(true)); if (autoVerify) { startVerification(); } else { // If not, notify device of complete transfer sendUpdateComplete(); } } } break; case AckTypes.COMPLETE_ACK: // Ack for update complete message, notify gui. { expectedAck = AckTypes.NO_ACK; StatusUpdate(this, new MessageEventArgs("Device confirmed update complete.")); if (ReadyToRun != null) ReadyToRun(this, EventArgs.Empty); } break; case AckTypes.READ_ACK: // Answer to request for a flash memory line. // Copy and start verification { expectedAck = AckTypes.NO_ACK; packet.CopyTo(receivedLine, 0); verifyFlashLine(); } break; } }
// Send a Hex line private void sendLine() { byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength - 1]; transferData[0] = (byte)Commands.CMD_WRITE; List<byte> tempLine = hexLines[sentLines]; for (int B = 0; B < tempLine.Count; B++) { transferData[1 + B] = tempLine[B]; } expectedAck = AckTypes.LINE_ACK; //StatusUpdate(this, new MessageEventArgs("Sending Line.")); SendDataAndWait(transferData); }
// Confirm to remote device that firmware was completely transmitted private void sendUpdateComplete() { byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength - 1]; transferData[0] = (byte)Commands.CMD_UPDATE_COMPLETE; expectedAck = AckTypes.COMPLETE_ACK; SendDataAndWait(transferData); }
/// <summary> /// Builds an ACK_PROCESSED message with additional data (data can be null) /// </summary> /// <param name="id">ID of the message to acknowledge</param> /// <param name="data">data (xml string) to be inserted in the ack</param> public AckMessage(long id, string data) { _type = AckTypes.ACK_PROCESSED; _id = id; _data = data; }
/// <summary> /// Create an Ack message based on a received message /// </summary> /// <param name="inboundMessage">received message</param> /// <param name="ackResult">Send AA, AE or AR message.</param> /// <param name="errorMessage">The reason the message was rejected or an error. If "AA" was supplied as ackCode the errorMessage should be null.</param> /// <returns>Created ACK message</returns> public IMessage MakeACK(IMessage inboundMessage, AckTypes ackResult, string errorMessage) { IMessage ackMessage = null; // Get an object from the right ACK class string ackClassType = string.Format("NHapi.Model.V{0}.Message.ACK, NHapi.Model.V{0}", inboundMessage.Version.Replace(".", "")); Type x = Type.GetType(ackClassType); if (x != null) ackMessage = (IMessage)Activator.CreateInstance(x); else { // Fix for V2.2 and V2.1 Since tha ACK message class is missing there in NHapi if (inboundMessage.Version == "2.1") ackMessage = (IMessage)new NHapiTools.Base.CustomImplementation.V21.Messages.ACK(); if (inboundMessage.Version == "2.2") ackMessage = (IMessage)new NHapiTools.Base.CustomImplementation.V22.Messages.ACK(); } Terser inboundTerser = new Terser(inboundMessage); ISegment inboundHeader = null; inboundHeader = inboundTerser.getSegment("MSH"); // Find the HL7 version of the inbound message: string version = null; try { version = Terser.Get(inboundHeader, 12, 0, 1, 1); } catch (NHapi.Base.HL7Exception) { // I'm not happy to proceed if we can't identify the inbound // message version. throw new NHapi.Base.HL7Exception("Failed to get valid HL7 version from inbound MSH-12-1"); } // Create a Terser instance for the outbound message (the ACK). Terser terser = new Terser(ackMessage); // Populate outbound MSH fields using data from inbound message ISegment outHeader = (ISegment)terser.getSegment("MSH"); DeepCopy.copy(inboundHeader, outHeader); // Now set the message type, HL7 version number, acknowledgement code // and message control ID fields: string sendingApp = terser.Get("/MSH-3"); string sendingEnv = terser.Get("/MSH-4"); terser.Set("/MSH-3", appCommunicationName); terser.Set("/MSH-4", environmentIdentifier); terser.Set("/MSH-5", sendingApp); terser.Set("/MSH-6", sendingEnv); terser.Set("/MSH-7", DateTime.Now.ToString("yyyyMMddmmhh")); terser.Set("/MSH-9", "ACK"); terser.Set("/MSH-12", version); terser.Set("/MSA-1", Enum.GetName(typeof(AckTypes), ackResult)); terser.Set("/MSA-2", Terser.Get(inboundHeader, 10, 0, 1, 1)); // Set error message if (errorMessage != null) terser.Set("/ERR-1-1", errorMessage); return ackMessage; }
/// <summary> /// Create an Ack message based on a received message /// </summary> /// <param name="inboundMessage">received message</param> /// <param name="ackResult">Send AA, AE or AR message.</param> /// <param name="errorMessage">The reason the message was rejected or an error. If "AA" was supplied as ackCode the errorMessage should be null.</param> /// <returns>Created ACK message</returns> public IMessage MakeACK(IMessage inboundMessage, AckTypes ackResult, string errorMessage) { //this should avoid an unhandled null reference exception in "inboundMessage.Version", because people tend to send the inboudMessage without a check if (inboundMessage == null) { throw new ArgumentNullException("Either process the valid message while retreiving the ack or handle invalid message differently"); } IMessage ackMessage = null; // Get an object from the right ACK class string ackClassType = string.Format("NHapi.Model.V{0}.Message.ACK, NHapi.Model.V{0}", inboundMessage.Version.Replace(".", "")); Type x = Type.GetType(ackClassType); if (x != null) { ackMessage = (IMessage)Activator.CreateInstance(x); } else { // Fix for V2.2 and V2.1 Since tha ACK message class is missing there in NHapi if (inboundMessage.Version == "2.1") { ackMessage = (IMessage) new NHapiTools.Base.CustomImplementation.V21.Messages.ACK(); } if (inboundMessage.Version == "2.2") { ackMessage = (IMessage) new NHapiTools.Base.CustomImplementation.V22.Messages.ACK(); } } Terser inboundTerser = new Terser(inboundMessage); ISegment inboundHeader = null; inboundHeader = inboundTerser.getSegment("MSH"); // Find the HL7 version of the inbound message: string version = null; try { version = Terser.Get(inboundHeader, 12, 0, 1, 1); } catch (NHapi.Base.HL7Exception) { // I'm not happy to proceed if we can't identify the inbound // message version. throw new NHapi.Base.HL7Exception("Failed to get valid HL7 version from inbound MSH-12-1"); } // Create a Terser instance for the outbound message (the ACK). Terser terser = new Terser(ackMessage); // Populate outbound MSH fields using data from inbound message ISegment outHeader = (ISegment)terser.getSegment("MSH"); DeepCopy.copy(inboundHeader, outHeader); // Now set the message type, HL7 version number, acknowledgement code // and message control ID fields: string sendingApp = terser.Get("/MSH-3"); string sendingEnv = terser.Get("/MSH-4"); terser.Set("/MSH-3", appCommunicationName); terser.Set("/MSH-4", environmentIdentifier); terser.Set("/MSH-5", sendingApp); terser.Set("/MSH-6", sendingEnv); terser.Set("/MSH-7", DateTime.Now.ToString("yyyyMMddmmhh")); terser.Set("/MSH-9", "ACK"); terser.Set("/MSH-9-3", "ACK"); terser.Set("/MSH-12", version); terser.Set("/MSA-1", Enum.GetName(typeof(AckTypes), ackResult)); terser.Set("/MSA-2", Terser.Get(inboundHeader, 10, 0, 1, 1)); // Set error message if (errorMessage != null) { terser.Set("/ERR-1-1", errorMessage); } return(ackMessage); }
// Called when cancel button of progress dialog pushed. // Aborts transfers and sends new init to remote device. public void cancel() { StatusUpdate(this, new MessageEventArgs("Cancelling and reconnecting.")); // Disable sending and receiving of data aborting = true; // Wait while other thread is finishing it's current calls. System.Threading.Thread.Sleep(200); // Enable communication and send a init command to restart the connection. aborting = false; byte[] transferData = new byte[this.usbHidPort1.SpecifiedDevice.OutputReportLength - 1]; transferData[0] = (byte)Commands.CMD_INIT; expectedAck = AckTypes.INIT_ACK; SendDataAndWait(transferData); }