private void sendCommand(SharerSentCommand cmd)
        {
            lock (_sentCommands)
            {
                _currentSupervisorCommandID++;

                cmd.BeginSend(_currentSupervisorCommandID);

                var header = new byte[] { SHARER_START_COMMAND_CHAR, _currentSupervisorCommandID, (byte)cmd.CommandID };

                // Write header, same for all commands
                _serialPort.Write(header, 0, header.Length);

                // write optionnal arguments
                var buffer = cmd.ArgumentsToSend();
                if (buffer != null && buffer.Length > 0)
                {
                    _serialPort.Write(buffer, 0, buffer.Length);
                }



                _sentCommands.Add(cmd);
            }
        }
        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;
            }
        }