/// <summary>
        /// Closes the serial port.
        /// </summary>
        private void CloseSerialPort()
        {
            lock (_lock)
            {
                Trace.TraceInformation("{0}.CloseSerialPort: CommPort={1}", CLASSNAME, _serialPort.PortName);
                // Attempt to close the serial port object
                if (_serialPort != null)
                {
                    _serialPort.DataReceived  -= SerialPort_DataReceived;
                    _serialPort.ErrorReceived -= SerialPort_ErrorReceived;
                    if (_serialPort.IsOpen)
                    {
                        try
                        {
                            _serialPort.Close();
                        }
                        catch (IOException) { }
                        catch (Exception ex)
                        {
                            Trace.TraceError("{0}.CloseSerialPort: CommPort={1} Exception={2}", CLASSNAME, _serialPort.PortName, ex.GetBaseException());
                            throw ex;
                        }
                    }
                    _serialPort.Dispose();
                    _serialPort = null;

                    _buffer = null;
                    _bufPos = 0;
                    _state  = RecvrState.NoDeviceFound;
                }
            } // end lock
        }
        /// <summary>
        /// Opens the serial port.
        /// </summary>
        private void OpenSerialPort(string commPort)
        {
            lock (_lock)
            {
                // Open the serial port connection
                _serialPort = new SerialPort()
                {
                    PortName     = commPort,
                    BaudRate     = BAUD_RATE,
                    DataBits     = DATA_BITS,
                    StopBits     = STOP_BITS,
                    Parity       = PARITY,
                    WriteTimeout = WRITE_TIMEOUT,
                    Handshake    = HANDSHAKE
                };

                Trace.TraceInformation("{0}.OpenSerialPort: CommPort={1}", CLASSNAME, _serialPort.PortName);
                try
                {
                    _serialPort.Open();
                }
                catch (Exception ex)
                {
                    Trace.TraceError("{0}.OpenSerialPort: CommPort={1} Exception={2}", CLASSNAME, _serialPort.PortName, ex.GetBaseException());
                    throw ex;
                }

                _buffer = new byte[BUFFER_SIZE];
                _bufPos = 0;
                _state  = RecvrState.Waiting;
                _serialPort.DataReceived  += SerialPort_DataReceived;
                _serialPort.ErrorReceived += SerialPort_ErrorReceived;
                GC.SuppressFinalize(_serialPort.BaseStream); // Work around, see http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/8a1825d2-c84b-4620-91e7-3934a4d47330
            } // end lock
        }
        /// <summary>
        /// Handles the DataReceived event of the serialPort control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.IO.Ports.SerialDataReceivedEventArgs"/> instance containing the event data.</param>
        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Data format: STX COUNT DATA ... CHECKSUM ETX
            DataPacketReceivedEventArgs eventData = null;

            lock (_lock)
            {
                try
                {
                    while (_serialPort.BytesToRead > 0)
                    {
                        byte data = (byte)_serialPort.ReadByte();

                        switch (_state)
                        {
                        case RecvrState.Waiting:
                            if (data == 0x02)
                            {
                                _state = RecvrState.PacketLength;
                            }
                            break;

                        case RecvrState.PacketLength:
                            _checksum   = data;
                            _dataLength = data - 1;
                            _bufPos     = 0;
                            _buffer.Initialize();
                            _state = RecvrState.PacketData;
                            break;

                        case RecvrState.PacketData:
                            if (_bufPos < _dataLength)
                            {
                                _buffer[_bufPos++] = data;
                                _checksum         ^= data;
                            }

                            if (_bufPos == _dataLength)
                            {
                                _state = RecvrState.Checksum;
                            }
                            break;

                        case RecvrState.Checksum:
                            if (_checksum != data)
                            {
                                Trace.TraceWarning("{0}.SerialPort_DataReceived: Checksum mismatch. Expected={1} Actual={2}", CLASSNAME, _checksum, data);
                                _state = RecvrState.Waiting;
                            }
                            else
                            {
                                _state = RecvrState.Received;
                            }
                            break;

                        case RecvrState.Received:
                            if (data == 0x03)
                            {
                                // We got a message!
                                eventData = new DataPacketReceivedEventArgs()
                                {
                                    CommPort   = _serialPort.PortName,
                                    DataLength = _dataLength,
                                    DataPacket = new byte[_bufPos]
                                };
                                Array.Copy(_buffer, 0, eventData.DataPacket, 0, _bufPos);
                                _state = RecvrState.Waiting;
                            }
                            break;

                        default:
                            Trace.TraceError("{0}.SerialPort_DataReceived: Unknown receive state, resetting state");
                            _state = RecvrState.Waiting;
                            break;
                        }
                    }
                }
                catch (InvalidOperationException ex)
                {
                    Trace.TraceError("{0}.SerialPort_DataReceived: CommPort={1} Exception={2}", CLASSNAME, _serialPort.PortName, ex.GetBaseException());
                }
            } // end lock

            // Fire event if we have data (we are outside our lock here)
            if (eventData != null)
            {
                OnDataPacketReceived(eventData);
            }
        }
 /// <summary>
 /// Handles the ErrorReceived event of the serialPort control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="System.IO.Ports.SerialErrorReceivedEventArgs"/> instance containing the event data.</param>
 private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
 {
     _state = RecvrState.Waiting;
 }
        /// <summary>
        /// Handles the DataReceived event of the serialPort control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.IO.Ports.SerialDataReceivedEventArgs"/> instance containing the event data.</param>
        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            // Data format: STX COUNT DATA ... CHECKSUM ETX
            DataPacketReceivedEventArgs eventData = null;

            lock (_lock)
            {
                try
                {
                    while (_serialPort.BytesToRead > 0)
                    {
                        byte data = (byte)_serialPort.ReadByte();

                        switch (_state)
                        {
                            case RecvrState.Waiting:
                                if (data == 0x02)
                                {
                                    _state = RecvrState.PacketLength;
                                }
                                break;

                            case RecvrState.PacketLength:
                                _checksum = data;
                                _dataLength = data - 1;
                                _bufPos = 0;
                                _buffer.Initialize();
                                _state = RecvrState.PacketData;
                                break;

                            case RecvrState.PacketData:
                                if (_bufPos < _dataLength)
                                {
                                    _buffer[_bufPos++] = data;
                                    _checksum ^= data;
                                }

                                if (_bufPos == _dataLength)
                                {
                                    _state = RecvrState.Checksum;
                                }
                                break;

                            case RecvrState.Checksum:
                                if (_checksum != data)
                                {
                                    Trace.TraceWarning("{0}.SerialPort_DataReceived: Checksum mismatch. Expected={1} Actual={2}", CLASSNAME, _checksum, data);
                                    _state = RecvrState.Waiting;
                                }
                                else
                                {
                                    _state = RecvrState.Received;
                                }
                                break;

                            case RecvrState.Received:
                                if (data == 0x03)
                                {
                                    // We got a message!
                                    eventData = new DataPacketReceivedEventArgs() 
                                    {
                                        CommPort = _serialPort.PortName,
                                        DataLength = _dataLength,
                                        DataPacket = new byte[_bufPos]
                                    };
                                    Array.Copy(_buffer, 0, eventData.DataPacket, 0, _bufPos);
                                    _state = RecvrState.Waiting;
                                }
                                break;

                            default:
                                Trace.TraceError("{0}.SerialPort_DataReceived: Unknown receive state, resetting state");
                                _state = RecvrState.Waiting;
                                break;
                        }
                    }
                }
                catch (InvalidOperationException ex)
                {
                    Trace.TraceError("{0}.SerialPort_DataReceived: CommPort={1} Exception={2}", CLASSNAME, _serialPort.PortName, ex.GetBaseException());
                }
            } // end lock

            // Fire event if we have data (we are outside our lock here)
            if (eventData != null) OnDataPacketReceived(eventData);
        }
 /// <summary>
 /// Handles the ErrorReceived event of the serialPort control.
 /// </summary>
 /// <param name="sender">The source of the event.</param>
 /// <param name="e">The <see cref="System.IO.Ports.SerialErrorReceivedEventArgs"/> instance containing the event data.</param>
 private void SerialPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
 {
     _state = RecvrState.Waiting;
 }
        /// <summary>
        /// Closes the serial port.
        /// </summary>
        private void CloseSerialPort()
        {
            lock (_lock)
            {
                Trace.TraceInformation("{0}.CloseSerialPort: CommPort={1}", CLASSNAME, _serialPort.PortName);
                // Attempt to close the serial port object
                if (_serialPort != null)
                {
                    _serialPort.DataReceived -= SerialPort_DataReceived;
                    _serialPort.ErrorReceived -= SerialPort_ErrorReceived;
                    if (_serialPort.IsOpen)
                    {
                        try
                        {
                            _serialPort.Close();
                        }
                        catch (IOException) { }
                        catch (Exception ex)
                        {
                            Trace.TraceError("{0}.CloseSerialPort: CommPort={1} Exception={2}", CLASSNAME, _serialPort.PortName, ex.GetBaseException());
                            throw ex;
                        }
                    }
                    _serialPort.Dispose();
                    _serialPort = null;

                    _buffer = null;
                    _bufPos = 0;
                    _state = RecvrState.NoDeviceFound;
                }
            } // end lock
        }
        /// <summary>
        /// Opens the serial port.
        /// </summary>
        private void OpenSerialPort(string commPort)
        {
            lock (_lock)
            {
                // Open the serial port connection
                _serialPort = new SerialPort()
                {
                    PortName = commPort,
                    BaudRate = BAUD_RATE,
                    DataBits = DATA_BITS,
                    StopBits = STOP_BITS,
                    Parity = PARITY,
                    WriteTimeout = WRITE_TIMEOUT,
                    Handshake = HANDSHAKE
                };

                Trace.TraceInformation("{0}.OpenSerialPort: CommPort={1}", CLASSNAME, _serialPort.PortName);
                try
                {
                    _serialPort.Open();
                }
                catch (Exception ex)
                {
                    Trace.TraceError("{0}.OpenSerialPort: CommPort={1} Exception={2}", CLASSNAME, _serialPort.PortName, ex.GetBaseException());
                    throw ex;
                }

                _buffer = new byte[BUFFER_SIZE];
                _bufPos = 0;
                _state = RecvrState.Waiting;
                _serialPort.DataReceived += SerialPort_DataReceived;
                _serialPort.ErrorReceived += SerialPort_ErrorReceived;
                GC.SuppressFinalize(_serialPort.BaseStream); // Work around, see http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/8a1825d2-c84b-4620-91e7-3934a4d47330
            } // end lock
        }