public void ProcessData(byte[] data)
        {
            byte dataCrcHighByte, dataCrcLowByte;

            for (int i = 0; i < data.Length; i++)
            {
                switch (currentState)
                {
                case ProcessingState.WAITING_FOR_START_OF_HEADER:
                    if (data[i] == START_OF_HEADER)
                    {
                        currentCRC   = XModemCRC.CalculateCRC(data[i], 0);
                        currentState = ProcessingState.WAITING_FOR_SYSTEM_ID;
                    }
                    break;

                case ProcessingState.WAITING_FOR_SYSTEM_ID:
                    if (data[i] == SYSTEM_ID)
                    {
                        currentCRC   = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState = ProcessingState.WAITING_FOR_SUBSYSTEM_ID;
                    }
                    else
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_SUBSYSTEM_ID:
                    if (data[i] == SUBSYSTEM_ID)
                    {
                        currentCRC   = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState = ProcessingState.WAITING_FOR_NODE_ID;
                    }
                    else
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_NODE_ID:
                    if (data[i] == NODE_ID)
                    {
                        currentCRC   = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState = ProcessingState.WAITING_FOR_COMPONENT_ID;
                    }
                    else
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_COMPONENT_ID:
                    if (data[i] == COMPONENT_ID)
                    {
                        currentCRC   = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState = ProcessingState.WAITING_FOR_MAJOR_SOFTWARE_VERSION;
                    }
                    else
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_MAJOR_SOFTWARE_VERSION:
                    if (data[i] <= MAJOR_SOFTWARE_VERSION)
                    {
                        majorSoftwareVersion = data[i];
                        currentCRC           = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState         = ProcessingState.WAITING_FOR_MINOR_SOFTWARE_VERSION;
                    }
                    else
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_MINOR_SOFTWARE_VERSION:
                    if ((majorSoftwareVersion == MAJOR_SOFTWARE_VERSION && data[i] <= MINOR_SOFTWARE_VERSION) || (majorSoftwareVersion < MAJOR_SOFTWARE_VERSION))
                    {
                        minorSoftwareVersion = data[i];
                        currentCRC           = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState         = ProcessingState.WAITING_FOR_MESSAGE_ID_0;
                    }
                    else          //if majorSoftwareVersion == MAJOR_SOFTWARE_VERSION && minorSoftwareVersion > MINOR_SOFTWARE_VERSION
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_MESSAGE_ID_0:
                    messageIdHighByte = data[i];
                    currentCRC        = XModemCRC.CalculateCRC(data[i], currentCRC);
                    currentState      = ProcessingState.WAITING_FOR_MESSAGE_ID_1;
                    break;

                case ProcessingState.WAITING_FOR_MESSAGE_ID_1:
                    messageIdLowByte = data[i];
                    currentCRC       = XModemCRC.CalculateCRC(data[i], currentCRC);
                    currentState     = ProcessingState.WAITING_FOR_PAYLOAD_LENGTH;
                    break;

                case ProcessingState.WAITING_FOR_PAYLOAD_LENGTH:
                    payloadLength = data[i];
                    currentCRC    = XModemCRC.CalculateCRC(data[i], currentCRC);
                    if (payloadLength > 0)
                    {
                        payload         = new byte[payloadLength];
                        payloadPosition = 0;
                        currentState    = ProcessingState.PROCESSING_PAYLOAD;
                    }
                    else           //payloadLength == 0
                    {
                        payload      = null;
                        currentState = ProcessingState.WAITING_FOR_CRC_BYTE_0;
                    }
                    break;

                case ProcessingState.PROCESSING_PAYLOAD:
                    payload[payloadPosition++] = data[i];
                    currentCRC = XModemCRC.CalculateCRC(data[i], currentCRC);
                    if (payloadPosition >= payloadLength)
                    {
                        currentState = ProcessingState.WAITING_FOR_CRC_BYTE_0;
                    }
                    break;

                case ProcessingState.WAITING_FOR_CRC_BYTE_0:
                    CRC_BYTE_0   = data[i];
                    currentState = ProcessingState.WAITING_FOR_CRC_BYTE_1;
                    break;

                case ProcessingState.WAITING_FOR_CRC_BYTE_1:
                    CRC_BYTE_1 = data[i];

                    dataCrcHighByte = (byte)(currentCRC >> 8);
                    dataCrcLowByte  = (byte)(currentCRC & 0x00FF);

                    if ((dataCrcHighByte == CRC_BYTE_0) && (dataCrcLowByte == CRC_BYTE_1))
                    {
                        owner.LogData(new Message(majorSoftwareVersion, minorSoftwareVersion, messageIdHighByte, messageIdLowByte, payload));
                    }
                    else           //Failed CRC Check
                    {
                        crcCheckFails++;
                    }

                    currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                    break;

                default:
                    MessageBox.Show("Unexpected Default Case in Process Data");
                    break;
                }
            }
        }
        public int ProcessData(byte[] data)
        {
            busy = true;
            //TODO - take these out and turn functions back into void function
            DateTime timestamp1 = DateTime.Now;
            DateTime timestamp2;
            byte     dataCrcHighByte, dataCrcLowByte;

            for (int i = 0; i < data.Length; i++)
            {
                switch (currentState)
                {
                case ProcessingState.WAITING_FOR_START_OF_HEADER:
                    if (data[i] == START_OF_HEADER)
                    {
                        timestamp    = DateTime.Now;
                        currentCRC   = XModemCRC.CalculateCRC(data[i], 0);
                        currentState = ProcessingState.WAITING_FOR_SYSTEM_ID;
                    }
                    break;

                case ProcessingState.WAITING_FOR_SYSTEM_ID:
                    if (data[i] == SYSTEM_ID)
                    {
                        currentCRC   = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState = ProcessingState.WAITING_FOR_SUBSYSTEM_ID;
                    }
                    else
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_SUBSYSTEM_ID:
                    if (data[i] == SUBSYSTEM_ID)
                    {
                        currentCRC   = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState = ProcessingState.WAITING_FOR_NODE_ID;
                    }
                    else
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_NODE_ID:
                    if (data[i] == NODE_ID)
                    {
                        currentCRC   = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState = ProcessingState.WAITING_FOR_COMPONENT_ID;
                    }
                    else
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_COMPONENT_ID:
                    if (data[i] == COMPONENT_ID)
                    {
                        currentCRC   = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState = ProcessingState.WAITING_FOR_MAJOR_SOFTWARE_VERSION;
                    }
                    else
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_MAJOR_SOFTWARE_VERSION:
                    if (data[i] <= MAJOR_SOFTWARE_VERSION)
                    {
                        majorSoftwareVersion = data[i];
                        currentCRC           = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState         = ProcessingState.WAITING_FOR_MINOR_SOFTWARE_VERSION;
                    }
                    else
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_MINOR_SOFTWARE_VERSION:
                    if ((majorSoftwareVersion == MAJOR_SOFTWARE_VERSION && data[i] <= MINOR_SOFTWARE_VERSION) || (majorSoftwareVersion < MAJOR_SOFTWARE_VERSION))
                    {
                        minorSoftwareVersion = data[i];
                        currentCRC           = XModemCRC.CalculateCRC(data[i], currentCRC);
                        currentState         = ProcessingState.WAITING_FOR_MESSAGE_ID_0;
                    }
                    else          //if majorSoftwareVersion == MAJOR_SOFTWARE_VERSION && minorSoftwareVersion > MINOR_SOFTWARE_VERSION || majorSoftwareVersion > MAJOR_SOFTWARE_VERSION
                    {
                        currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                        goto case ProcessingState.WAITING_FOR_START_OF_HEADER;
                    }
                    break;

                case ProcessingState.WAITING_FOR_MESSAGE_ID_0:
                    messageIdHighByte = data[i];
                    currentCRC        = XModemCRC.CalculateCRC(data[i], currentCRC);
                    currentState      = ProcessingState.WAITING_FOR_MESSAGE_ID_1;
                    break;

                case ProcessingState.WAITING_FOR_MESSAGE_ID_1:
                    messageIdLowByte = data[i];
                    currentCRC       = XModemCRC.CalculateCRC(data[i], currentCRC);
                    currentState     = ProcessingState.WAITING_FOR_PAYLOAD_LENGTH;
                    break;

                case ProcessingState.WAITING_FOR_PAYLOAD_LENGTH:
                    payloadLength = data[i];
                    currentCRC    = XModemCRC.CalculateCRC(data[i], currentCRC);
                    if (payloadLength > 0)
                    {
                        payload         = new byte[payloadLength];
                        payloadPosition = 0;
                        currentState    = ProcessingState.PROCESSING_PAYLOAD;
                    }
                    else           //payloadLength == 0
                    {
                        payload      = null;
                        currentState = ProcessingState.WAITING_FOR_CRC_BYTE_0;
                    }
                    break;

                case ProcessingState.PROCESSING_PAYLOAD:
                    payload[payloadPosition++] = data[i];
                    currentCRC = XModemCRC.CalculateCRC(data[i], currentCRC);
                    if (payloadPosition >= payloadLength)
                    {
                        currentState = ProcessingState.WAITING_FOR_CRC_BYTE_0;
                    }
                    break;

                case ProcessingState.WAITING_FOR_CRC_BYTE_0:
                    CRC_BYTE_0   = data[i];
                    currentState = ProcessingState.WAITING_FOR_CRC_BYTE_1;
                    break;

                case ProcessingState.WAITING_FOR_CRC_BYTE_1:
                    CRC_BYTE_1 = data[i];

                    dataCrcHighByte = (byte)(currentCRC >> 8);
                    dataCrcLowByte  = (byte)(currentCRC & 0x00FF);

                    if ((dataCrcHighByte == CRC_BYTE_0) && (dataCrcLowByte == CRC_BYTE_1))
                    {
                        owner.LogData(new Message(majorSoftwareVersion, minorSoftwareVersion, messageIdHighByte, messageIdLowByte, payload, timestamp));
                    }
                    else           //Failed CRC Check
                    {
                        crcCheckFails++;
                    }

                    currentState = ProcessingState.WAITING_FOR_START_OF_HEADER;
                    break;

                default:
                    MessageBox.Show("Unexpected Default Case in Process Data");
                    break;
                }
            }
            //TODO - take timestamp comparision out
            timestamp2 = DateTime.Now;
            int time;

            if (timestamp1.Millisecond > timestamp2.Millisecond)
            {
                time = timestamp2.Millisecond + (1000 - timestamp1.Millisecond);
            }
            else
            {
                time = timestamp2.Millisecond - timestamp1.Millisecond;
            }

            busy = false;

            return(time);
        }