private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;

            //
            try
            {
                byte[] data  = new byte[sp.BytesToRead];
                int    count = sp.Read(data, 0, data.Length);

                if (count > 0)
                {
                    for (int i = 0; i < count; i++)
                    {
                        ParseReceivedData(data[i]);
                    }
                }
            }
            catch (Exception ex)
            {
                _receiveStep = ReceiveSteps.Free;
                if (_currentCommand != null)
                {
                    _currentCommand.EndReceive(false, ex);
                    _currentCommand = null;
                }
            }
        }
        private void ParseReceivedData(byte b)
        {
            switch (_receiveStep)
            {
            case ReceiveSteps.DeviceMessageId:
                _lastDeviceMessageId = b;
                _receiveStep         = ReceiveSteps.CommandId;
                break;

            case ReceiveSteps.CommandId:
                _lastCommandID = (SharerCommandID)b;

                _receiveStep = ReceiveSteps.SupervisorMessageId;
                // to do : handle asynchronous messages
                break;

            case ReceiveSteps.SupervisorMessageId:

                lock (_sentCommands)
                {
                    // command without request
                    if (_notificationCommand.ContainsKey(_lastCommandID))
                    {
                        _currentCommand = (SharerSentCommand)Activator.CreateInstance(_notificationCommand[_lastCommandID]);
                        _receiveStep    = ReceiveSteps.Body;
                    }
                    else
                    {
                        _currentCommand = _sentCommands.FirstOrDefault((x) => x.CommandID == _lastCommandID && x.SentID == b);

                        if (_currentCommand == null)
                        {
                            _receiveStep = ReceiveSteps.Free;

                            throw new Exception("Command ID " + _lastCommandID + " not found in history");
                        }
                        else
                        {
                            _sentCommands.Remove(_currentCommand);
                            _receiveStep = ReceiveSteps.Body;
                        }
                    }
                }
                break;

            case ReceiveSteps.Body:

                var decodageDone = _currentCommand.DecodeArgument(b);

                if (decodageDone)
                {
                    _currentCommand.EndReceive(true);     // indicate that the command has been received
                    _receiveStep = ReceiveSteps.Free;

                    switch (_currentCommand.CommandID)
                    {
                    case SharerCommandID.Ready:
                        AsyncNotifyReady();
                        break;

                    case SharerCommandID.Error:

                        break;
                    }
                }
                break;

            default:
                if (b == SHARER_START_COMMAND_CHAR)
                {
                    _receiveStep = ReceiveSteps.DeviceMessageId;
                }
                else
                {
                    // to do : store value for user stream
                }
                break;
            }
        }