public async Task <ButtplugMessage> SendMessage([NotNull] ButtplugMessage aMsg)
        {
            _bpLogger.Trace($"Got Message {aMsg.Id} of type {aMsg.GetType().Name} to send");
            var id = aMsg.Id;

            if (id == 0)
            {
                return(_bpLogger.LogWarnMsg(id, Error.ErrorClass.ERROR_MSG,
                                            "Message Id 0 is reserved for outgoing system messages. Please use another Id."));
            }

            if (aMsg is IButtplugMessageOutgoingOnly)
            {
                return(_bpLogger.LogWarnMsg(id, Error.ErrorClass.ERROR_MSG,
                                            $"Message of type {aMsg.GetType().Name} cannot be sent to server"));
            }

            if (_pingTimedOut)
            {
                return(_bpLogger.LogErrorMsg(id, Error.ErrorClass.ERROR_PING, "Ping timed out."));
            }

            // If we get a message that's not RequestServerInfo first, return an error.
            if (!_receivedRequestServerInfo && !(aMsg is RequestServerInfo))
            {
                return(_bpLogger.LogErrorMsg(id, Error.ErrorClass.ERROR_INIT,
                                             "RequestServerInfo must be first message received by server!"));
            }

            switch (aMsg)
            {
            case RequestLog m:
                _bpLogger.Debug("Got RequestLog Message");
                BpLogManager.Level = m.LogLevel;
                return(new Ok(id));

            case Ping _:
                // Start the timer
                _pingTimer?.Change((int)_maxPingTime, (int)_maxPingTime);

                return(new Ok(id));

            case RequestServerInfo rsi:
                _bpLogger.Debug("Got RequestServerInfo Message");
                _receivedRequestServerInfo = true;
                _clientMessageVersion      = rsi.MessageVersion;

                // Start the timer
                _pingTimer?.Change((int)_maxPingTime, (int)_maxPingTime);
                ClientConnected?.Invoke(this, new MessageReceivedEventArgs(rsi));
                return(new ServerInfo(_serverName, 1, _maxPingTime, id));

            case Test m:
                return(new Test(m.TestString, id));
            }

            return(await _deviceManager.SendMessage(aMsg));
        }
        public async Task <ButtplugMessage> SendMessage([NotNull] ButtplugMessage aMsg)
        {
            _bpLogger.Trace($"Got Message {aMsg.Id} of type {aMsg.GetType().Name} to send");
            var id = aMsg.Id;

            if (id == 0)
            {
                return(_bpLogger.LogWarnMsg(id, Error.ErrorClass.ERROR_MSG,
                                            "Message Id 0 is reserved for outgoing system messages. Please use another Id."));
            }

            if (aMsg is IButtplugMessageOutgoingOnly)
            {
                return(_bpLogger.LogWarnMsg(id, Error.ErrorClass.ERROR_MSG,
                                            $"Message of type {aMsg.GetType().Name} cannot be sent to server"));
            }

            if (_pingTimedOut)
            {
                return(_bpLogger.LogErrorMsg(id, Error.ErrorClass.ERROR_PING, "Ping timed out."));
            }

            // If we get a message that's not RequestServerInfo first, return an error.
            if (!_receivedRequestServerInfo && !(aMsg is RequestServerInfo))
            {
                return(_bpLogger.LogErrorMsg(id, Error.ErrorClass.ERROR_INIT,
                                             "RequestServerInfo must be first message received by server!"));
            }

            switch (aMsg)
            {
            case RequestLog m:
                _bpLogManager.Level = m.LogLevel;
                return(new Ok(id));

            case Ping _:
                if (_pingTimer != null)
                {
                    _pingTimer.Stop();
                    _pingTimer.Start();
                }

                return(new Ok(id));

            case RequestServerInfo _:
                _receivedRequestServerInfo = true;
                _pingTimer?.Start();
                return(new ServerInfo(_serverName, 1, _maxPingTime, id));

            case Test m:
                return(new Test(m.TestString, id));
            }

            return(await _deviceManager.SendMessage(aMsg));
        }