Beispiel #1
0
        private static PandaPacket isPriorRequest(string clientID, PandaPacket request)
        {
            //Return prior response if was a prior message
            //Return null if not a prior message
            PandaPacket response = null;

            try {
                //Check if this was a prior message
                PandaPacket priorPacket = null;
                if (LastRequest != null)
                {
                    if (clientID == LastRequest.ClientID && LastRequest.MessageNumber == request.MessageNumber)
                    {
                        priorPacket = LastRequest;
                    }
                }
                //Prior request? return prior response
                if (priorPacket != null)
                {
                    response = priorPacket.Response;
                }
            }
            catch (Exception ex) {
                throw new ApplicationException("Error occurred while validating message", ex);
            }
            return(response);
        }
Beispiel #2
0
        /// <summary>Creates a PandaPacket response to the specified PandaPacket request.</summary>
        /// <param name="clientID">A unique identifier for the socket client; not required.</param>
        /// <param name="messageCode">Identifies the PandA request/response message type.</param>
        /// <param name="flag">Message status (0=message OK; 1=message error).</param>
        /// <param name="iterator">Count of records in the body (always 1).</param>
        /// <param name="messageBody">Message data.</param>
        /// <param name="messageNumber">Unique message identifier from 0001 - 9999.</param>
        /// <param name="request">A reference to the original Tsort.PandA.PandaPacket request.</param>
        /// <returns>An instance of Tsort.PandA.PandaPacket.</returns>
        public static PandaPacket Encode(string clientID, int messageCode, int flag, int iterator, string messageBody, int messageNumber, PandaPacket request)
        {
            //Encode a PandA packet
            PandaPacket packet = null;

            try {
                //Form the message packet
                packet                      = new PandaPacket();
                packet.mClientID            = clientID;
                packet.mReceived            = DateTime.Now;
                packet.mMessageCode         = messageCode;
                packet.mMessageNumber       = messageNumber;
                packet.mOriginalMessageCode = (request != null) ? request.MessageCode : 0;
                packet.mMessageFlags        = flag;
                packet.mRecordIterator      = iterator;
                packet.mMessageBody         = messageBody;
                if (request != null)
                {
                    request.Response = packet;
                }

                //Determine message length and dimension message packet
                packet.mMessageLength = LEN_MIN + packet.mMessageBody.Length;
                packet.mPacket        = new byte[packet.mMessageLength];
                byte[] bytes = makePacketBytes(packet);
                Array.Copy(bytes, 0, packet.mPacket, 0, bytes.Length);
                packet.mMessage = new ASCIIEncoding().GetString(packet.mPacket);
                packet.mValid   = true;
            }
            catch (ApplicationException ex) { packet.mException = ex; packet.mValid = false; }
            catch (Exception ex) { packet.mException = new ApplicationException("Message packet encoding failed.", ex); packet.mValid = false; }
            return(packet);
        }
Beispiel #3
0
        private static PandaPacket getLabelDataResponse(string clientID, PandaPacket request)
        {
            //
            PandaPacket response = null;
            DataSet     ds       = null;

            try {
                //Extract message body
                string barcode1 = request.MessageBody.Substring(0, 32).TrimEnd();
                string barcode2 = request.MessageBody.Substring(32, 32).TrimEnd();
                string barcode3 = request.MessageBody.Substring(64, 32).TrimEnd();
                string barcode4 = request.MessageBody.Substring(96, 32).TrimEnd();
                string barcode5 = request.MessageBody.Substring(128, 32).TrimEnd();
                string barcode6 = request.MessageBody.Substring(160, 32).TrimEnd();
                float  weight   = Convert.ToInt32(request.MessageBody.Substring(192, 5)) / 100;

                //Process the label data request
                ds = CartonMgr.ProcessLabelDataRequest(barcode1, barcode2, barcode3, barcode4, barcode5, barcode6, weight);
                if (ds != null)
                {
                    //New carton
                    response = PandaPacket.Encode(clientID, RESPONSE_LABELDATA, request, 0, 1, PandaPacket.FormatLabelDataMessageBody(ds.Tables["PandATable"].Rows[0]["CartonID"].ToString(), int.Parse(ds.Tables["PandATable"].Rows[0]["StatusCode"].ToString()), ds.Tables["PandATable"].Rows[0]["LabelData"].ToString()));
                }
            }
            catch (Exception ex) {
                AppTrace.Instance().TheTrace.WriteLine(new TraceMessage("Error occurred while processing request for label data- " + ex.ToString(), AppLib.EVENTLOGNAME, LogLevel.Error, "PacketMgr"));
                if (ds != null)
                {
                    response = PandaPacket.Encode(clientID, RESPONSE_LABELDATA, request, 0, 1, PandaPacket.FormatLabelDataMessageBody(ds.Tables["PandATable"].Rows[0]["CartonID"].ToString(), int.Parse(ds.Tables["PandATable"].Rows[0]["StatusCode"].ToString()), ds.Tables["PandATable"].Rows[0]["LabelData"].ToString()));
                }
            }
            return(response);
        }
Beispiel #4
0
        private static PandaPacket getHeartbeatResponse(string clientID, PandaPacket request)
        {
            //Reply with a heartbeat signal
            PandaPacket response = null;

            try {
                response = PandaPacket.Encode(clientID, RESPONSE_HEARTBEAT, request, 0, 1, "");
            }
            catch (Exception ex) {
                AppTrace.Instance().TheTrace.WriteLine(new TraceMessage("An error occurred while processing request for heartbeat." + ex.ToString(), AppLib.EVENTLOGNAME, LogLevel.Error, "PacketMgr"));
            }
            return(response);
        }
Beispiel #5
0
        private static byte[] makePacketBytes(PandaPacket packet)
        {
            //Create the byte array for the specified packet
            byte[] bytes = new byte[packet.mMessageLength];
            bytes[0] = STX;

            string msgLen = packet.mMessageLength.ToString().PadLeft(5, '0');

            bytes[1] = (byte)Char.Parse(msgLen.Substring(0, 1));
            bytes[2] = (byte)Char.Parse(msgLen.Substring(1, 1));
            bytes[3] = (byte)Char.Parse(msgLen.Substring(2, 1));
            bytes[4] = (byte)Char.Parse(msgLen.Substring(3, 1));
            bytes[5] = (byte)Char.Parse(msgLen.Substring(4, 1));

            string msgCode = packet.mMessageCode.ToString().PadLeft(4, '0');

            bytes[6] = (byte)Char.Parse(msgCode.Substring(0, 1));
            bytes[7] = (byte)Char.Parse(msgCode.Substring(1, 1));
            bytes[8] = (byte)Char.Parse(msgCode.Substring(2, 1));
            bytes[9] = (byte)Char.Parse(msgCode.Substring(3, 1));

            string msgNum = packet.mMessageNumber.ToString().PadLeft(4, '0');

            bytes[10] = (byte)Char.Parse(msgNum.Substring(0, 1));
            bytes[11] = (byte)Char.Parse(msgNum.Substring(1, 1));
            bytes[12] = (byte)Char.Parse(msgNum.Substring(2, 1));
            bytes[13] = (byte)Char.Parse(msgNum.Substring(3, 1));

            string msgOrigCode = packet.mOriginalMessageCode.ToString().PadLeft(4, '0');

            bytes[14] = (byte)Char.Parse(msgOrigCode.Substring(0, 1));
            bytes[15] = (byte)Char.Parse(msgOrigCode.Substring(1, 1));
            bytes[16] = (byte)Char.Parse(msgOrigCode.Substring(2, 1));
            bytes[17] = (byte)Char.Parse(msgOrigCode.Substring(3, 1));

            bytes[18] = (byte)Char.Parse(packet.mMessageFlags.ToString());

            string msgIterator = packet.mRecordIterator.ToString().PadLeft(3, '0');

            bytes[19] = (byte)Char.Parse(msgIterator.Substring(0, 1));
            bytes[20] = (byte)Char.Parse(msgIterator.Substring(1, 1));
            bytes[21] = (byte)Char.Parse(msgIterator.Substring(2, 1));

            for (int i = 0; i < packet.mMessageBody.Length; i++)
            {
                bytes[i + LEN_MIN - 1] = (byte)Char.Parse(packet.mMessageBody.Substring(i, 1));
            }

            bytes[packet.mMessageLength - 1] = ETX;
            return(bytes);
        }
Beispiel #6
0
        /// <summary>Decodes a PandA Message packet into a PandaPacket object.</summary>
        /// <param name="clientID">A unique identifier for the socket client; not required.</param>
        /// <param name="message">A byte array containing a message that adheres to the PandA Message Protocol.</param>
        /// <returns>An instance of Tsort.PandA.PandaPacket.</returns>
        public static PandaPacket Decode(string clientID, byte[] message)
        {
            //Decode a PandA message packet
            //NOTE: This method never throws an exception; the exception is in the PandaPacket
            PandaPacket packet    = null;
            Encoding    oEncoding = new ASCIIEncoding();

            try {
                //Retain packet
                packet           = new PandaPacket();
                packet.mClientID = clientID;
                packet.mReceived = DateTime.Now;
                packet.mPacket   = new byte[message.Length];
                Array.Copy(message, 0, packet.mPacket, 0, message.Length);

                //Validate packet integrity
                if (packet.mPacket.Length < LEN_MIN)
                {
                    throw new ApplicationException("Invalid message length; length less than minimum.");
                }
                if ((packet.mPacket[0] != STX) || (packet.mPacket[packet.mPacket.Length - 1] != ETX))
                {
                    throw new ApplicationException("The message either did not begin with STX or did not end with ETX");
                }

                //Extract message parameters
                packet.mMessage             = oEncoding.GetString(packet.mPacket);
                packet.mMessageLength       = Convert.ToInt32(packet.mMessage.Substring(START_MSG, LEN_MSG));
                packet.mMessageCode         = Convert.ToInt32(packet.mMessage.Substring(START_CODE, LEN_CODE));
                packet.mMessageNumber       = Convert.ToInt32(packet.mMessage.Substring(START_NUM, LEN_NUM));
                packet.mOriginalMessageCode = Convert.ToInt32(packet.mMessage.Substring(START_ORIGCODE, LEN_CODE));
                packet.mMessageFlags        = Convert.ToInt32(packet.mMessage.Substring(START_FLAGS, LEN_FLAGS));
                packet.mRecordIterator      = Convert.ToInt32(packet.mMessage.Substring(START_ITERATOR, LEN_ITERATOR));
                packet.mMessageBody         = packet.mMessage.Substring(START_BODY, packet.mMessageLength - START_BODY - 1);

                //Validate packet integrity
                if (ValidateMessageLength && packet.mPacket.Length != packet.mMessageLength)
                {
                    throw new ApplicationException("Invalid message length; length does not match header length member.");
                }
                packet.mValid = true;
            }
            catch (ApplicationException ex) { packet.mException = ex; packet.mValid = false; }
            catch (Exception ex) { packet.mException = new ApplicationException("Message packet decoding failed.", ex); packet.mValid = false; }
            return(packet);
        }
Beispiel #7
0
        private static PandaPacket getVerifyLabelResponse(string clientID, PandaPacket request)
        {
            //Verify the requested carton
            PandaPacket response = null;

            try {
                //Find the carton
                string cartonID   = request.MessageBody.Substring(0, PandaPacket.CartonIDLength).TrimEnd();
                string verifyCode = request.MessageBody.Substring(PandaPacket.CartonIDLength, 1).TrimEnd();
                string verifyFlag = CartonMgr.ProcessVerifyLabelRequest(cartonID, verifyCode);
                response = PandaPacket.Encode(clientID, RESPONSE_VERIFYLABEL, request, 0, 1, verifyFlag);
            }
            catch (Exception ex) {
                AppTrace.Instance().TheTrace.WriteLine(new TraceMessage("An error occurred while processing request to verify label." + ex.ToString(), AppLib.EVENTLOGNAME, LogLevel.Error, "PacketMgr"));
                response = PandaPacket.Encode(clientID, RESPONSE_VERIFYLABEL, request, 0, 1, "N");
            }
            return(response);
        }
Beispiel #8
0
        public static byte[] ProcessPandARequest(string clientID, byte[] bytes)
        {
            //Process a PandA request from a remote socket client
            PandaPacket request  = null;
            PandaPacket response = null;
            DateTime    started  = DateTime.Now;

            try {
                //Process the message
                request = PandaPacket.Decode(clientID, bytes);
                AppTrace.Instance().TheTrace.WriteLine(new TraceMessage("REQUEST:" + request.Message, AppLib.EVENTLOGNAME, LogLevel.Information, "PacketMgr"));
                if (request.Valid)
                {
                    //Check if this was a prior request
                    PandaPacket priorResponse = isPriorRequest(clientID, request);
                    if (priorResponse != null)
                    {
                        //This was a prior message; return prior response
                        response = priorResponse;
                        AppTrace.Instance().TheTrace.WriteLine(new TraceMessage("PRIOR RESPONSE: " + priorResponse.Message, AppLib.EVENTLOGNAME, LogLevel.Information, "PacketMgr"));
                    }
                    else
                    {
                        //New, valid message; persist request and route to message handler
                        switch (request.MessageCode)
                        {
                        case REQUEST_LABELDATA:
                            response    = getLabelDataResponse(clientID, request);
                            LastRequest = request;
                            try { request.ProcessingTime = ((TimeSpan)DateTime.Now.Subtract(started)).TotalSeconds; } catch {}
                            if (LabelDataRequestComplete != null)
                            {
                                LabelDataRequestComplete(null, new PandaPacketEventArgs(request));
                            }
                            break;

                        case REQUEST_VERIFYLABEL:
                            response    = getVerifyLabelResponse(clientID, request);
                            LastRequest = request;
                            try { request.ProcessingTime = ((TimeSpan)DateTime.Now.Subtract(started)).TotalSeconds; } catch {}
                            if (VerifyLabelRequestComplete != null)
                            {
                                VerifyLabelRequestComplete(null, new PandaPacketEventArgs(request));
                            }
                            break;

                        case REQUEST_HEARTBEAT:
                            response = getHeartbeatResponse(clientID, request);
                            if (HeartbeatRequestComplete != null)
                            {
                                HeartbeatRequestComplete(null, EventArgs.Empty);
                            }
                            break;

                        case REQUEST_RESEND:
                            response = LastRequest.Response;
                            AppTrace.Instance().TheTrace.WriteLine(new TraceMessage("Resend requested.", AppLib.EVENTLOGNAME, LogLevel.Warning, "PacketMgr"));
                            if (ResendRequestComplete != null)
                            {
                                ResendRequestComplete(null, EventArgs.Empty);
                            }
                            break;

                        default:
                            AppTrace.Instance().TheTrace.WriteLine(new TraceMessage("Unknown message code.", AppLib.EVENTLOGNAME, LogLevel.Warning, "PacketMgr"));
                            break;
                        }
                    }
                }
                else
                {
                    //Invalid message packet
                    response = PandaPacket.Encode(clientID, RESPONSE_MSGERROR, request, 0, 0, "");
                    AppTrace.Instance().TheTrace.WriteLine(new TraceMessage("Message failed (decode) validation...", AppLib.EVENTLOGNAME, LogLevel.Warning, "PacketMgr"));
                }
            }
            catch (Exception ex) {
                response = PandaPacket.Encode(clientID, RESPONSE_MSGERROR, request, 0, 0, "");
                AppTrace.Instance().TheTrace.WriteLine(new TraceMessage("Error occurred while processing message: " + ex.ToString(), AppLib.EVENTLOGNAME, LogLevel.Error, "PacketMgr"));
            }
            return(response != null?response.Bytes:null);
        }
Beispiel #9
0
        private void OnMenuClick(object sender, System.EventArgs e)
        {
            //Event hanlder for menu click events
            try {
                MenuItem mnu = (MenuItem)sender;
                switch (mnu.Text)
                {
                case "Open":
                    switch (this.tabMain.SelectedTab.Name)
                    {
                    case "tabCtns":         break;

                    case "tabMsgs":
                        OpenFileDialog dlgOpen = new OpenFileDialog();
                        dlgOpen.Filter      = "Text Files (*.xml) | *.xml";
                        dlgOpen.FilterIndex = 0;
                        if (dlgOpen.ShowDialog(this) == DialogResult.OK)
                        {
                            PandaDS packets = new PandaDS();
                            packets.ReadXml(dlgOpen.FileName, XmlReadMode.ReadSchema);
                            if (packets.PacketTable.Rows.Count == 0)
                            {
                                MessageBox.Show(this, "No PandA packets found in file " + dlgOpen.FileName + ".", "Open PandA Packets", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                            else
                            {
                                for (int i = 0; i < packets.PacketTable.Rows.Count; i++)
                                {
                                    PandaDS.PacketTableRow packet = packets.PacketTable[i];
                                    this.lsvMsgs.Items.Add(new ListViewItem(new string[] { packet.ClientID, packet.Received.ToString("MM-dd-yyyy HH:mm:ss.fff"), packet.ProcessingTime.ToString(), packet.MessageLength.ToString(), packet.MessageCode.ToString(), packet.MessageNumber.ToString(), packet.OriginalMessageCode.ToString(), packet.MessageFlags.ToString(), packet.RecordIterator.ToString(), packet.MessageBody, packet.Valid.ToString(), packet.Exception }));
                                }
                            }
                        }
                        break;

                    case "tabTrace":        break;
                    }
                    break;

                case "Clear":
                    switch (this.tabMain.SelectedTab.Name)
                    {
                    case "tabCtns":         this.lsvCtns.Items.Clear(); break;

                    case "tabMsgs":         this.lsvMsgs.Items.Clear(); break;

                    case "tabTrace":        this.txtTrace.Clear(); break;
                    }
                    break;

                case "Save":
                    #region Save a view to file
                    SaveFileDialog dlgSave = new SaveFileDialog();
                    dlgSave.AddExtension    = true;
                    dlgSave.FilterIndex     = 0;
                    dlgSave.OverwritePrompt = true;
                    switch (this.tabMain.SelectedTab.Name)
                    {
                    case "tabCtns":
                        dlgSave.Filter   = "Text Files (*.xml) | *.xml";
                        dlgSave.Title    = "Save Cartons As...";
                        dlgSave.FileName = "cartons_" + DateTime.Today.ToString("yyyyMMdd") + ".xml";
                        if (dlgSave.ShowDialog(this) == DialogResult.OK)
                        {
                            PandaDS cartons = new PandaDS();
                            #region Populate dataset with all cartons that are in lsvCtns
                            for (int i = 0; i < this.lsvCtns.Items.Count; i++)
                            {
                                PandaDS.CartonTableRow carton = cartons.CartonTable.NewCartonTableRow();
                                carton.CartonID       = this.lsvCtns.Items[i].SubItems[0].Text;
                                carton.StatusCode     = int.Parse(this.lsvCtns.Items[i].SubItems[1].Text);
                                carton.LabelFormat    = this.lsvCtns.Items[i].SubItems[2].Text;
                                carton.LabelException = this.lsvCtns.Items[i].SubItems[3].Text;
                                carton.Verify         = this.lsvCtns.Items[i].SubItems[4].Text;
                                carton.SaveException  = this.lsvCtns.Items[i].SubItems[5].Text;
                                carton.Barcode1       = this.lsvCtns.Items[i].SubItems[6].Text;
                                carton.Barcode2       = this.lsvCtns.Items[i].SubItems[7].Text;
                                carton.Barcode3       = this.lsvCtns.Items[i].SubItems[8].Text;
                                carton.Barcode4       = this.lsvCtns.Items[i].SubItems[9].Text;
                                carton.Barcode5       = this.lsvCtns.Items[i].SubItems[10].Text;
                                carton.Barcode6       = this.lsvCtns.Items[i].SubItems[11].Text;
                                carton.ItemWeight     = decimal.Parse(this.lsvCtns.Items[i].SubItems[12].Text);
                                cartons.CartonTable.AddCartonTableRow(carton);
                            }
                            #endregion
                            cartons.WriteXml(dlgSave.FileName, XmlWriteMode.WriteSchema);
                        }
                        break;

                    case "tabMsgs":
                        dlgSave.Filter   = "Text Files (*.xml) | *.xml";
                        dlgSave.Title    = "Save Packets As...";
                        dlgSave.FileName = "packets_" + DateTime.Today.ToString("yyyyMMdd") + ".xml";
                        if (dlgSave.ShowDialog(this) == DialogResult.OK)
                        {
                            PandaDS packets = new PandaDS();
                            #region Populate dataset with all packets that are in lsvMsgs
                            for (int i = 0; i < this.lsvMsgs.Items.Count; i++)
                            {
                                PandaDS.PacketTableRow packet = packets.PacketTable.NewPacketTableRow();
                                packet.ClientID            = this.lsvMsgs.Items[i].SubItems[0].Text;
                                packet.Received            = DateTime.Parse(this.lsvMsgs.Items[i].SubItems[1].Text);
                                packet.ProcessingTime      = float.Parse(this.lsvMsgs.Items[i].SubItems[2].Text);
                                packet.MessageLength       = int.Parse(this.lsvMsgs.Items[i].SubItems[3].Text);
                                packet.MessageCode         = int.Parse(this.lsvMsgs.Items[i].SubItems[4].Text);
                                packet.MessageNumber       = int.Parse(this.lsvMsgs.Items[i].SubItems[5].Text);
                                packet.OriginalMessageCode = int.Parse(this.lsvMsgs.Items[i].SubItems[6].Text);
                                packet.MessageFlags        = int.Parse(this.lsvMsgs.Items[i].SubItems[7].Text);
                                packet.RecordIterator      = int.Parse(this.lsvMsgs.Items[i].SubItems[8].Text);
                                packet.MessageBody         = this.lsvMsgs.Items[i].SubItems[9].Text;
                                packet.Valid     = bool.Parse(this.lsvMsgs.Items[i].SubItems[10].Text);
                                packet.Exception = this.lsvMsgs.Items[i].SubItems[11].Text;
                                packets.PacketTable.AddPacketTableRow(packet);
                            }
                            #endregion
                            packets.WriteXml(dlgSave.FileName, XmlWriteMode.WriteSchema);
                        }
                        break;

                    case "tabTrace":
                        dlgSave.Filter   = "Text Files (*.txt) | *.txt";
                        dlgSave.Title    = "Save Trace Log As...";
                        dlgSave.FileName = "tracelog_" + DateTime.Today.ToString("yyyyMMdd") + ".txt";
                        if (dlgSave.ShowDialog(this) == DialogResult.OK)
                        {
                            this.txtTrace.SaveFile(dlgSave.FileName, RichTextBoxStreamType.PlainText);
                        }
                        break;
                    }
                    #endregion
                    break;

                case "Run":
                    switch (this.tabMain.SelectedTab.Name)
                    {
                    case "tabCtns":         break;

                    case "tabMsgs":
                        #region Populate datarow with all fields that are in lsvMsgs selected item
                        PandaDS packets = new PandaDS();
                        PandaDS.PacketTableRow packet = packets.PacketTable.NewPacketTableRow();
                        packet.ClientID            = this.lsvMsgs.SelectedItems[0].SubItems[0].Text;
                        packet.Received            = DateTime.Parse(this.lsvMsgs.SelectedItems[0].SubItems[1].Text);
                        packet.ProcessingTime      = float.Parse(this.lsvMsgs.SelectedItems[0].SubItems[2].Text);
                        packet.MessageLength       = int.Parse(this.lsvMsgs.SelectedItems[0].SubItems[3].Text);
                        packet.MessageCode         = int.Parse(this.lsvMsgs.SelectedItems[0].SubItems[4].Text);
                        packet.MessageNumber       = int.Parse(this.lsvMsgs.SelectedItems[0].SubItems[5].Text);
                        packet.OriginalMessageCode = int.Parse(this.lsvMsgs.SelectedItems[0].SubItems[6].Text);
                        packet.MessageFlags        = int.Parse(this.lsvMsgs.SelectedItems[0].SubItems[7].Text);
                        packet.RecordIterator      = int.Parse(this.lsvMsgs.SelectedItems[0].SubItems[8].Text);
                        packet.MessageBody         = this.lsvMsgs.SelectedItems[0].SubItems[9].Text;
                        packet.Valid     = bool.Parse(this.lsvMsgs.SelectedItems[0].SubItems[10].Text);
                        packet.Exception = this.lsvMsgs.SelectedItems[0].SubItems[11].Text;
                        #endregion
                        PandaPacket request = new PandaPacket(packet);
                        this.mPandaSvc.ProcessPandARequest("", request);
                        break;

                    case "tabTrace":        break;
                    }
                    break;
                }
            }
            catch (Exception ex) { reportError(ex); }
        }
Beispiel #10
0
 /// <summary></summary>
 /// <param name="packet"></param>
 public PandaPacketEventArgs(PandaPacket packet)
 {
     this._packet = packet;
 }
Beispiel #11
0
        /// <summary>Processes </summary>
        /// <param name="clientID">A unique identifier for the requestor (can be an empty string).</param>
        /// <param name="request">A Tsort.PandA.PandaPacket request.</param>
        /// <exceptions cref="ApplicationException">Thrown for unexpected errors.</exceptions>
        /// <returns>An instance of Tsort.PandA.PandaPacket containing the response.</returns>
        public PandaPacket ProcessPandARequest(string clientID, PandaPacket request)
        {
            //Process a PandA request from a remote socket client
            PandaPacket response = null;
            DateTime    started  = DateTime.Now;

            try {
                //Process the PandA message; Decode() always returns a non-null request object
                ArgixTrace.WriteLine(new TraceMessage("", AppLib.PRODUCTNAME, LogLevel.Information, "PandaSvc"));
                ArgixTrace.WriteLine(new TraceMessage("REQUEST:" + request.Message, AppLib.PRODUCTNAME, LogLevel.Information, "PandaSvc"));
                if (request.Valid)
                {
                    //Check if this was a prior request
                    PandaPacket priorResponse = isPriorRequest(clientID, request);
                    if (priorResponse != null)
                    {
                        //This was a prior message; return prior response
                        response = priorResponse;
                        ArgixTrace.WriteLine(new TraceMessage("PRIOR RESPONSE: " + priorResponse.Message, AppLib.PRODUCTNAME, LogLevel.Information, "PandaSvc"));
                    }
                    else
                    {
                        //New, valid message; persist request and route to message handler
                        switch (request.MessageCode)
                        {
                        case REQUEST_LABELDATA:
                            DataSet ds = null;
                            try {
                                //Extract message body and process message request
                                string   barcode1 = request.MessageBody.Substring(0, 32).TrimEnd();
                                string   barcode2 = request.MessageBody.Substring(32, 32).TrimEnd();
                                string   barcode3 = request.MessageBody.Substring(64, 32).TrimEnd();
                                string   barcode4 = request.MessageBody.Substring(96, 32).TrimEnd();
                                string   barcode5 = request.MessageBody.Substring(128, 32).TrimEnd();
                                string   barcode6 = request.MessageBody.Substring(160, 32).TrimEnd();
                                decimal  weight   = decimal.Parse(request.MessageBody.Substring(192, 5)) / 100;
                                string[] inputs   = new string[] { barcode1, barcode2, barcode3, barcode4, barcode5, barcode6 };
                                ds = ProcessLabelDataRequest(inputs, weight);
                                if (ds != null)
                                {
                                    response = PandaPacket.Encode(clientID, RESPONSE_LABELDATA, 0, 1, PandaPacket.FormatLabelDataMessageBody(ds.Tables["PandATable"].Rows[0]["CartonID"].ToString(), int.Parse(ds.Tables["PandATable"].Rows[0]["StatusCode"].ToString()), ds.Tables["PandATable"].Rows[0]["LabelData"].ToString()), request.MessageNumber, request);
                                }
                            }
                            catch (Exception ex) {
                                if (ds != null)
                                {
                                    response = PandaPacket.Encode(clientID, RESPONSE_LABELDATA, 0, 1, PandaPacket.FormatLabelDataMessageBody(ds.Tables["PandATable"].Rows[0]["CartonID"].ToString(), int.Parse(ds.Tables["PandATable"].Rows[0]["StatusCode"].ToString()), ds.Tables["PandATable"].Rows[0]["LabelData"].ToString()), request.MessageNumber, request);
                                }
                                ArgixTrace.WriteLine(new TraceMessage("An error occurred while processing Panda label data request-->" + ex.Message, AppLib.PRODUCTNAME, LogLevel.Error, "PandaSvc"));
                            }
                            this.mLastRequest = request;
                            try { request.ProcessingTime = (float)((TimeSpan)DateTime.Now.Subtract(started)).TotalSeconds; } catch {}
                            if (PandaRequestComplete != null)
                            {
                                PandaRequestComplete(null, new PandaPacketEventArgs(request));
                            }
                            break;

                        case REQUEST_VERIFYLABEL:
                            try {
                                //Find the carton
                                string cartonID   = request.MessageBody.Substring(0, PandaPacket.CartonIDLength).TrimEnd();
                                string verifyCode = request.MessageBody.Substring(PandaPacket.CartonIDLength, 1).TrimEnd();
                                string verifyFlag = ProcessVerifyLabelRequest(cartonID, verifyCode);
                                response = PandaPacket.Encode(clientID, RESPONSE_VERIFYLABEL, 0, 1, verifyFlag, request.MessageNumber, request);
                            }
                            catch (Exception ex) {
                                response = PandaPacket.Encode(clientID, RESPONSE_VERIFYLABEL, 0, 1, VERIFY_NO, request.MessageNumber, request);
                                ArgixTrace.WriteLine(new TraceMessage("An error occurred while processing Panda verify label request-->" + ex.Message, AppLib.PRODUCTNAME, LogLevel.Error, "PandaSvc"));
                            }
                            this.mLastRequest = request;
                            try { request.ProcessingTime = (float)((TimeSpan)DateTime.Now.Subtract(started)).TotalSeconds; } catch {}
                            if (PandaRequestComplete != null)
                            {
                                PandaRequestComplete(null, new PandaPacketEventArgs(request));
                            }
                            break;

                        case REQUEST_RESEND:
                            response = this.mLastRequest.Response;
                            ArgixTrace.WriteLine(new TraceMessage("Resend requested.", AppLib.PRODUCTNAME, LogLevel.Warning, "PandaSvc"));
                            if (PandaResendComplete != null)
                            {
                                PandaResendComplete(null, EventArgs.Empty);
                            }
                            break;

                        case REQUEST_HEARTBEAT:
                            try {
                                response = PandaPacket.Encode(clientID, RESPONSE_HEARTBEAT, 0, 1, "", request.MessageNumber, request);
                            }
                            catch (Exception ex) {
                                ArgixTrace.WriteLine(new TraceMessage("An error occurred while processing Panda heartbeat request-->" + ex.Message, AppLib.PRODUCTNAME, LogLevel.Error, "PandaSvc"));
                            }
                            if (HeartbeatRequestComplete != null)
                            {
                                HeartbeatRequestComplete(null, EventArgs.Empty);
                            }
                            break;

                        default:
                            ArgixTrace.WriteLine(new TraceMessage("Unknown message code.", AppLib.PRODUCTNAME, LogLevel.Warning, "PandaSvc"));
                            break;
                        }
                    }
                }
                else
                {
                    //Invalid message packet
                    response = PandaPacket.Encode(clientID, RESPONSE_MSGERROR, 0, 0, "", request.MessageNumber, request);
                    ArgixTrace.WriteLine(new TraceMessage("Message failed (decode) validation...", AppLib.PRODUCTNAME, LogLevel.Warning, "PandaSvc"));
                }
            }
            catch (Exception ex) {
                response = PandaPacket.Encode(clientID, RESPONSE_MSGERROR, 0, 0, "", request.MessageNumber, request);
                ArgixTrace.WriteLine(new TraceMessage("An error occurred while processing Panda message-->" + ex.Message, AppLib.PRODUCTNAME, LogLevel.Error, "PandaSvc"));
            }
            finally {
                if (response != null)
                {
                    ArgixTrace.WriteLine(new TraceMessage("RESPONSE: " + new ASCIIEncoding().GetString(response.Bytes), AppLib.PRODUCTNAME, LogLevel.Information, "PandaSvc"));
                }
                else
                {
                    ArgixTrace.WriteLine(new TraceMessage("RESPONSE: NULL", AppLib.PRODUCTNAME, LogLevel.Warning, "PandaSvc"));
                }
            }
            return(response);
        }