public void TestToErrorMessage() { var msg = new Error("test1", Error.ErrorClass.ERROR_DEVICE, 2); var err = ButtplugException.FromError(msg); err.ButtplugErrorMessage.Should().BeEquivalentTo(msg); }
/// <summary> /// Message Received event handler. Either tries to match incoming messages as replies to /// messages we've sent, or fires an event related to an incoming event, like device /// additions/removals, log messages, etc. /// </summary> /// <param name="aSender">Object sending the open event, unused.</param> /// <param name="aArgs">Event parameters, including the data received.</param> private async void MessageReceivedHandler(object aSender, MessageReceivedEventArgs aArgs) { var msg = aArgs.Message; switch (msg) { case Log l: Log?.Invoke(this, new LogEventArgs(l)); break; case DeviceAdded d: var dev = new ButtplugClientDevice(_bpLogManager, this, SendDeviceMessageAsync, d); _devices.Add(d.DeviceIndex, dev); DeviceAdded?.Invoke(this, new DeviceAddedEventArgs(dev)); break; case DeviceRemoved d: if (!_devices.ContainsKey(d.DeviceIndex)) { ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs( new ButtplugDeviceException(_bpLogger, "Got device removed message for unknown device.", msg.Id))); return; } var oldDev = _devices[d.DeviceIndex]; _devices.Remove(d.DeviceIndex); DeviceRemoved?.Invoke(this, new DeviceRemovedEventArgs(oldDev)); break; case ScanningFinished _: // The scanning finished event is self explanatory and doesn't require extra arguments. ScanningFinished?.Invoke(this, new EventArgs()); break; case Error e: // This will both log the error and fire it from our ErrorReceived event handler. ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs(ButtplugException.FromError(_bpLogger, e))); if (e.ErrorCode == Error.ErrorClass.ERROR_PING) { PingTimeout?.Invoke(this, EventArgs.Empty); await DisconnectAsync().ConfigureAwait(false); } break; default: ErrorReceived?.Invoke(this, new ButtplugExceptionEventArgs( new ButtplugMessageException(_bpLogger, $"Got unhandled message: {msg}", msg.Id))); break; } }
public void HandleErrorInvoked(object aObj, ButtplugExceptionEventArgs aEx) { if (_errorInvoked) { Assert.Fail("Multiple errors thrown without resets."); } _errorInvoked = true; _currentException = aEx.Exception; }
public void TestFromError() { ButtplugException.FromError(new Error("test", Error.ErrorClass.ERROR_DEVICE, ButtplugConsts.SystemMsgId)) .Should().BeOfType <ButtplugDeviceException>(); ButtplugException.FromError(new Error("test", Error.ErrorClass.ERROR_UNKNOWN, ButtplugConsts.SystemMsgId)) .Should().BeOfType <ButtplugException>(); ButtplugException.FromError(new Error("test", Error.ErrorClass.ERROR_INIT, ButtplugConsts.SystemMsgId)) .Should().BeOfType <ButtplugHandshakeException>(); ButtplugException.FromError(new Error("test", Error.ErrorClass.ERROR_MSG, ButtplugConsts.SystemMsgId)) .Should().BeOfType <ButtplugMessageException>(); ButtplugException.FromError(new Error("test", Error.ErrorClass.ERROR_PING, ButtplugConsts.SystemMsgId)) .Should().BeOfType <ButtplugPingException>(); }
/// <summary> /// Sends a message, expecting a response of message type <see cref="Ok"/>. /// </summary> /// <param name="aMsg">Message to send.</param> /// <param name="aToken">Cancellation token, for cancelling action externally if it is not yet finished.</param> /// <returns>True if successful.</returns> private async Task SendMessageExpectOk(ButtplugMessage aMsg, CancellationToken aToken = default(CancellationToken)) { var msg = await SendMessageAsync(aMsg, aToken).ConfigureAwait(false); switch (msg) { case Ok _: return; case Error err: throw ButtplugException.FromError(_bpLogger, err); default: throw new ButtplugMessageException(_bpLogger, $"Message type {msg.Name} not handled by SendMessageExpectOk", msg.Id); } }
public void CheckMessage(ButtplugMessage aMsg, IButtplugLog aLog = null) { // We'll never match a system message, those are server -> client only. if (aMsg.Id == 0) { throw new ButtplugMessageException(aLog, "Cannot sort message with System ID", aMsg.Id); } // If we haven't gotten a system message and we're not currently waiting for the message // id, throw. if (!_waitingMsgs.TryRemove(aMsg.Id, out var queued)) { throw new ButtplugMessageException(aLog, "Message with non-matching ID received.", aMsg.Id); } if (aMsg is Error errMsg) { queued.SetException(ButtplugException.FromError(errMsg)); return; } queued.SetResult(aMsg); }
// ReSharper disable once UnusedMember.Global public async Task ConnectAsync(CancellationToken aToken = default(CancellationToken)) { if (Connected) { throw new ButtplugHandshakeException(_bpLogger, "Client already connected to a server."); } _connector.MessageReceived += MessageReceivedHandler; await _connector.ConnectAsync(aToken).ConfigureAwait(false); var res = await SendMessageAsync(new RequestServerInfo(Name), aToken).ConfigureAwait(false); switch (res) { case ServerInfo si: if (si.MaxPingTime > 0) { _pingTimer = new Timer(OnPingTimer, null, 0, Convert.ToInt32(Math.Round(((double)si.MaxPingTime) / 2, 0))); } if (si.MessageVersion < ButtplugConsts.CurrentSpecVersion) { await DisconnectAsync().ConfigureAwait(false); throw new ButtplugHandshakeException(_bpLogger, $"B******g Server's schema version ({si.MessageVersion}) is less than the client's ({ButtplugConsts.CurrentSpecVersion}). A newer server is required.", res.Id); } // Get full device list and populate internal list var resp = await SendMessageAsync(new RequestDeviceList()).ConfigureAwait(false); if (!(resp is DeviceList)) { await DisconnectAsync().ConfigureAwait(false); if (resp is Error errResp) { throw ButtplugException.FromError(_bpLogger, errResp); } throw new ButtplugHandshakeException(_bpLogger, "Received unknown response to DeviceList handshake query"); } foreach (var d in (resp as DeviceList).Devices) { if (_devices.ContainsKey(d.DeviceIndex)) { continue; } var device = new ButtplugClientDevice(_bpLogManager, this, SendDeviceMessageAsync, d); _devices[d.DeviceIndex] = device; DeviceAdded?.Invoke(this, new DeviceAddedEventArgs(device)); } break; case Error e: await DisconnectAsync().ConfigureAwait(false); throw ButtplugException.FromError(_bpLogger, e); default: await DisconnectAsync().ConfigureAwait(false); throw new ButtplugHandshakeException(_bpLogger, $"Unrecognized message {res.Name} during handshake", res.Id); } }