public void Send(Message_Upload msg) { //add it to the queue to send and let the send message thread take care of it. lock (MsgSeqLock) { //Get rid of any data on the queue that is older than one hour while (SendMsgQueue.Count > 0 && SendMsgQueue.Peek().MsgToSend.Age > 60000 * 60) { RemoveFromQueue(); } //queue it up. SendMsg myMsg = new SendMsg(); myMsg.Initialize(new MsgSendInfo(), msg); SendMsgQueue.Enqueue(myMsg); //Save it to a file, in case of power loss or program shuts down. SerializeQueueToXML(); } }
private Message_Upload KeepAliveMessage() { Message_Upload keepAlive = new Message_Upload(MessageType.KeepAlive); keepAlive.MachineID = MachID; keepAlive.SequenceNum = LastMsgSeqNum; keepAlive.VendorName = "ESYSCORP"; keepAlive.ModelNum = "MES "; keepAlive.PortType = mPortType; keepAlive.KeepAliveAddlTextMessage = sVersion; keepAlive.ResponseType = MessageResponseType.DataMessage; return keepAlive; }
public bool PFCSSendNAK(Esys.IO.PFCS.Message_Upload msgToRespondTo, Esys.IO.PFCS.MessageErrors NAK_Error) { try { Message_Upload ack = new Message_Upload(msgToRespondTo.MsgType); ack.MachineID = MachID; ack.SequenceNum = msgToRespondTo.SequenceNum; ack.MsgType = msgToRespondTo.MsgType; ack.Error = NAK_Error; ack.ResponseType = MessageResponseType.NAK; Send(ack); return true; } catch (Exception ex) { if (StateChanged != null) StateChanged(this, new StateChangeEventArgs(StateChange.ErrorHappened, ex.ToString())); return false; } }
public bool PFCSSendSolData(Esys.IO.PFCS.MessageType msgType, string data, string _MachineID) { try { if (this.PortType != PORT_TYPE.Soliciated) { if (StateChanged != null) StateChanged(this, new StateChangeEventArgs(StateChange.ErrorHappened, "Can only send data (PFCSSendSolData) on Solicated Port.")); return false; } if (!(msgType == MessageType.SendingTestResults || msgType == MessageType.SendingDataRequestOnSolPort)) { if (StateChanged != null) StateChanged(this, new StateChangeEventArgs(StateChange.ErrorHappened, "Can only send message types of SendingDataRequestOnSolPort and SendingTestResults (PFCSSendSolData).")); return false; } if (data.Length > 1024) { if (StateChanged != null) StateChanged(this, new StateChangeEventArgs(StateChange.ErrorHappened, "data to send must be 1024 bytes or less. (PFCSSendSolData)")); return false; } Message_Upload msg = new Message_Upload(); msg.MachineID = _MachineID; msg.SequenceNum = 1; //Send Routine will automatically set the correct sequence number msg.PortType = PORT_TYPE.Soliciated; msg.MsgType = msgType; msg.ResponseType = MessageResponseType.DataMessage; msg.Data = data; Send(msg); return true; } catch (Exception ex) { if (StateChanged != null) StateChanged(this, new StateChangeEventArgs(StateChange.ErrorHappened, ex.ToString())); return false; } }
public void Initialize(MsgSendInfo _SendInfo, Message_Upload _MessageToSend) { SendInfo = _SendInfo; MsgToSend = _MessageToSend; }
/// <summary> /// Creates an ACK message from a message to respond to /// </summary> /// <param name="msgToRespondTo"></param> /// <param name="msgError"></param> /// <returns></returns> public Message_Upload PFCSCreateACK(Esys.IO.PFCS.Message_Upload msgToRespondTo, Esys.IO.PFCS.MessageErrors msgError) { try { Message_Upload ack = new Message_Upload(msgToRespondTo.MsgType); ack.MachineID = MachID; ack.SequenceNum = msgToRespondTo.SequenceNum; ack.MsgType = msgToRespondTo.MsgType; ack.Error = msgError; ack.ResponseType = MessageResponseType.ACK; //Send(ack); return ack; } catch (Exception ex) { if (StateChanged != null) StateChanged(this, new StateChangeEventArgs(StateChange.ErrorHappened, ex.ToString())); return null; } }
public MessageReceivedEventArgs(Message_Upload message) { Message = message; }
//Fills out the Data property for a data message and double checks length and such //Returns the filled out properties in msgToCreate //Precondition: The header of the data must have already been processed private static void CreateData_Msg(byte[] data, ref Message_Upload msgToCreate) { int i; if (data.Length < 22) { msgToCreate.Error = MessageErrors.ERR_NAK_A; return; } //.ERR_SHORT; return; } //17 - 20 Byte count of data in data area of message int intByteCount; StringBuilder ByteCount = new StringBuilder(""); for (i = 17; i <= 20; i++) { ByteCount.Append((char)data[i]); } try { intByteCount = Convert.ToInt16(ByteCount.ToString()); } catch { msgToCreate.Error = MessageErrors.ERR_NAK_J; //MessageErrors.ERR_BYTE_COUNT_LOW; return; } //Data section. Length needs to be what is specified in the byte count section above. StringBuilder sbData = new StringBuilder(""); for (i = 21; i < data.Length - 1; i++) { sbData.Append((char)data[i]); } msgToCreate.Data = sbData.ToString(); // for backwards compatibility BAD BYTE COUNT data messages are still valid if (intByteCount < data.Length - 21 - 1) { msgToCreate.Error = MessageErrors.ERR_NAK_J; //.ERR_BYTE_COUNT_LOW; } if (intByteCount > data.Length - 21 - 1) { msgToCreate.Error = MessageErrors.ERR_NAK_J; //.ERR_BYTE_COUNT_HIGH; } //Hopefully the last character is the CR if (!(data[data.Length - 1] == 0x0D)) msgToCreate.Error = MessageErrors.ERR_NAK_A; //.ERR_UNRECOG_CHAR; return; }
//Fills out the Error code for the ACK/NAK message and double checks length //Returns the filled out properties in msgToCreate //Precondition: The header of the data must have already been processed private static void CreateACK_NAK_Msg(byte[] data, ref Message_Upload msgToCreate) { if (data.Length < 19) { msgToCreate.Error = MessageErrors.ERR_NAK_A; return; }//.ERR_SHORT; return; } if (data.Length > 19) { msgToCreate.Error = MessageErrors.ERR_NAK_A; return; }//.ERR_INVALID_LEN; return; } if (msgToCreate.ResponseType == MessageResponseType.NAK ){ if (data[17] == 'A') { msgToCreate.mError = MessageErrors.ERR_NAK_A; return; } if (data[17] == 'B') { msgToCreate.mError = MessageErrors.ERR_NAK_B; return; } if (data[17] == 'E') { msgToCreate.mError = MessageErrors.ERR_NAK_E; return; } if (data[17] == 'H') { msgToCreate.mError = MessageErrors.ERR_NAK_H; return; } if (data[17] == 'I') { msgToCreate.mError = MessageErrors.ERR_NAK_I; return; } if (data[17] == 'J') { msgToCreate.mError = MessageErrors.ERR_NAK_J; } } else { if (msgToCreate.ResponseType == MessageResponseType.ACK) { if (data[17] == 'D') msgToCreate.mError = MessageErrors.ERR_ACK_D; } else { msgToCreate.mError = MessageErrors.ERR_NAK_A; //.ERR_BAD_MSG_RESULT; return; } } //Hopefully the last character is the CR if (!(data[18] == 0x0D)) msgToCreate.Error = MessageErrors.ERR_NAK_A;// MessageErrors.ERR_UNRECOG_CHAR; return; }
public static bool TryParse(byte[] data, out Message_Upload message) { try { message = Message_Upload.Parse(data); return true; } catch { message = null; return false; } }
public static Message_Upload Parse(byte[] dataToParse) { Message_Upload newMsg = new Message_Upload(); newMsg.mRawData_Bytes = dataToParse; //HEADER //BYTES //0 - 3 Machine ID e.g... TM01 //4 - 6 ACK/NAK area //7 - 12 Message Sequence Number //13 - 16 Echo of Message Type. //Verfiy the length int i; int msgend = 0; for (i = 0; i < dataToParse.Length; i++) { if (dataToParse[i] == (byte)0x0D) { msgend = i; break; } } if (msgend == 0) { newMsg.mError = MessageErrors.ERR_NAK_I; //Input exceeds 1024 return newMsg; } else if (msgend < 18) { newMsg.mError = MessageErrors.ERR_NAK_A;//.ERR_BYTE_COUNT_LOW; return newMsg; } byte[] data = new byte[msgend+1] ; for (i = 0; i <= msgend; i++) { data[i] = dataToParse[i]; } //Set mRawData_Bytes again except this time with just the data up to the 0x0D newMsg.mRawData_Bytes = data; //Set the machineID //0 - 3 Machine ID e.g... TM01 StringBuilder machID = new StringBuilder(""); for (i = 0; i <= 3; i++) { machID.Append((char)data[i]); } newMsg.MachineID = machID.ToString(); //4 - 6 ACK/NAK area StringBuilder strACK_NAK = new StringBuilder(""); for (i = 4; i <= 6; i++) { strACK_NAK.Append((char)data[i]); } if (strACK_NAK.ToString().ToUpper() == "ACK") newMsg.ResponseType = MessageResponseType.ACK; else if (strACK_NAK.ToString().ToUpper() == "NAK") newMsg.ResponseType = MessageResponseType.NAK; else if (strACK_NAK.ToString() == " ") newMsg.ResponseType = MessageResponseType.DataMessage; else { newMsg.MachineID = "XXXX"; newMsg.Error = MessageErrors.ERR_NAK_A;// .ERR_BAD_REQ_TYPE ; return newMsg; } //7 - 12 Message Sequence Number StringBuilder SeqNum = new StringBuilder(""); for (i = 7; i <= 12; i++) { SeqNum.Append((char)data[i]); } try { newMsg.SequenceNum = Convert.ToInt32(SeqNum.ToString()); } catch { newMsg.Error = MessageErrors.ERR_NAK_E; return newMsg; } //13 - 16 Echo of Message Type. StringBuilder MsgType = new StringBuilder(""); for (i = 13; i <= 16; i++) { MsgType.Append((char) data[i]); } try { int intMessageType = Convert.ToInt16(MsgType.ToString()); newMsg.MsgType = (MessageType) intMessageType; } catch { newMsg.Error = MessageErrors.ERR_NAK_H; return newMsg; } //check for invalid characters for (i = 0; i < data.Length - 1; i++) { if (isprint((Char)data[i]) == false) { newMsg.Error = MessageErrors.ERR_NAK_A; return newMsg;}//.ERR_UNRECOG_CHAR; return newMsg; } } //We parsed the header and now we have to parse either an ACK/NAK message or a data message if (newMsg.ResponseType == MessageResponseType.DataMessage) //Parse data message out... CreateData_Msg(data, ref newMsg); else CreateACK_NAK_Msg(data, ref newMsg); return newMsg; }