public async Task <ButtplugMessage> SendMsg(ButtplugMessage aMsg) { return(await SendMessage(aMsg)); }
protected async Task <bool> SendMessageExpectOk(ButtplugMessage aMsg) { return(await SendMessage(aMsg) is Ok); }
public string Serialize(ButtplugMessage aMsg) { ButtplugUtils.ArgumentNotNull(aMsg, nameof(aMsg)); return(_parser.Serialize(aMsg, _clientSpecVersion)); }
public async Task <ButtplugMessage> SendAsync(ButtplugMessage aMsg, CancellationToken aToken = default(CancellationToken)) { return(await Server.SendMessageAsync(aMsg).ConfigureAwait(false)); }
public async Task <ButtplugMessage> SendMessage(ButtplugMessage aMsg) { var id = aMsg.Id; switch (aMsg) { case StartScanning _: _bpLogger.Debug("Got StartScanning Message"); StartScanning(); return(new Ok(id)); case StopScanning _: _bpLogger.Debug("Got StopScanning Message"); StopScanning(); return(new Ok(id)); case StopAllDevices _: _bpLogger.Debug("Got StopAllDevices Message"); var isOk = true; var errorMsg = string.Empty; foreach (var d in _devices.ToList()) { if (!d.Value.IsConnected) { continue; } var r = await d.Value.ParseMessage(new StopDeviceCmd(d.Key, aMsg.Id)); if (r is Ok) { continue; } isOk = false; errorMsg += $"{(r as Error).ErrorMessage}; "; } if (isOk) { return(new Ok(aMsg.Id)); } return(new Error(errorMsg, Error.ErrorClass.ERROR_DEVICE, aMsg.Id)); case RequestDeviceList _: _bpLogger.Debug("Got RequestDeviceList Message"); var msgDevices = _devices.Where(aDevice => aDevice.Value.IsConnected) .Select(aDevice => new DeviceMessageInfo( aDevice.Key, aDevice.Value.Name, GetAllowedMessageTypesAsDictionary(aDevice.Value))).ToList(); return(new DeviceList(msgDevices.ToArray(), id)); // If it's a device message, it's most likely not ours. case ButtplugDeviceMessage m: _bpLogger.Trace($"Sending {aMsg.GetType().Name} to device index {m.DeviceIndex}"); if (_devices.ContainsKey(m.DeviceIndex)) { return(await _devices[m.DeviceIndex].ParseMessage(m)); } return(_bpLogger.LogErrorMsg(id, Error.ErrorClass.ERROR_DEVICE, $"Dropping message for unknown device index {m.DeviceIndex}")); } return(_bpLogger.LogErrorMsg(id, Error.ErrorClass.ERROR_MSG, $"Message type {aMsg.GetType().Name} unhandled by this server.")); }
public async Task <ButtplugMessage> SendMessageAsync([NotNull] ButtplugMessage aMsg, CancellationToken aToken = default(CancellationToken)) { var combinedToken = CancellationTokenSource.CreateLinkedTokenSource(_internalToken.Token, aToken); _bpLogger.Trace($"Got Message {aMsg.Id} of type {aMsg.GetType().Name} to send"); var id = aMsg.Id; ButtplugUtils.ArgumentNotNull(aMsg, nameof(aMsg)); if (id == ButtplugConsts.SystemMsgId) { throw new ButtplugMessageException(_bpLogger, "Message Id 0 is reserved for outgoing system messages. Please use another Id.", id); } if (aMsg is IButtplugMessageOutgoingOnly) { throw new ButtplugMessageException(_bpLogger, $"Message of type {aMsg.GetType().Name} cannot be sent to server", id); } if (_pingTimedOut) { throw new ButtplugPingException(_bpLogger, "Ping timed out.", id); } // If we get a message that's not RequestServerInfo first, return an error. if (!_receivedRequestServerInfo && !(aMsg is RequestServerInfo)) { throw new ButtplugHandshakeException(_bpLogger, "RequestServerInfo must be first message received by server!", id); } _bpLogger.Debug($"Got {aMsg.Name} message."); switch (aMsg) { case RequestLog m: BpLogManager.AddLogListener(m.LogLevel, LogMessageReceivedHandler); return(new Ok(id)); case Ping _: // Start the timer _pingTimer?.Change((int)_maxPingTime, (int)_maxPingTime); return(new Ok(id)); case RequestServerInfo rsi: if (_receivedRequestServerInfo) { throw new ButtplugHandshakeException(_bpLogger, "Already received RequestServerInfo, cannot be sent twice.", id); } _receivedRequestServerInfo = true; _clientSpecVersion = rsi.MessageVersion; _deviceManager.SpecVersion = _clientSpecVersion; // Start the timer _pingTimer?.Change((int)_maxPingTime, (int)_maxPingTime); _clientName = rsi.ClientName; ClientConnected?.Invoke(this, EventArgs.Empty); return(new ServerInfo(_serverName, ButtplugConsts.CurrentSpecVersion, _maxPingTime, id)); case Core.Messages.Test m: return(new Core.Messages.Test(m.TestString, id)); } return(await _deviceManager.SendMessageAsync(aMsg, combinedToken.Token).ConfigureAwait(false)); }
/// <summary> /// Converts a single <see cref="ButtplugMessage"/> into a JSON string. /// </summary> /// <param name="aMsg">Message to convert.</param> /// <returns>The JSON string representation of the message.</returns> public string Serialize(ButtplugMessage aMsg) { return(_parser.Serialize(aMsg, ButtplugConsts.CurrentSpecVersion)); }
public async Task <ButtplugMessage> SendMessageAsync(ButtplugMessage aMsg, CancellationToken aToken = default(CancellationToken)) { ButtplugUtils.ArgumentNotNull(aMsg, nameof(aMsg)); var id = aMsg.Id; switch (aMsg) { case StartScanning _: _bpLogger.Debug("Got StartScanning Message"); try { await StartScanning(); } catch (ButtplugDeviceException aEx) { // Catch and rethrow here, adding the message Id onto the exception throw new ButtplugDeviceException(_bpLogger, aEx.Message, id); } return(new Ok(id)); case StopScanning _: _bpLogger.Debug("Got StopScanning Message"); StopScanning(); return(new Ok(id)); case StopAllDevices _: _bpLogger.Debug("Got StopAllDevices Message"); var isOk = true; var errorMsg = string.Empty; foreach (var d in Devices.ToList()) { if (!d.Value.Connected) { continue; } try { await d.Value.ParseMessageAsync(new StopDeviceCmd(d.Key, aMsg.Id), aToken).ConfigureAwait(false); } catch (ButtplugDeviceException e) { isOk = false; errorMsg += $"{e.Message}; "; } } if (isOk) { return(new Ok(aMsg.Id)); } throw new ButtplugDeviceException(_bpLogger, errorMsg, aMsg.Id); case RequestDeviceList _: _bpLogger.Debug("Got RequestDeviceList Message"); var msgDevices = Devices.Where(aDevice => aDevice.Value.Connected) .Select(aDevice => new DeviceMessageInfo( aDevice.Key, aDevice.Value.Name, GetAllowedMessageTypesAsDictionary(aDevice.Value, SpecVersion))).ToList(); return(new DeviceList(msgDevices.ToArray(), id)); // If it's a device message, it's most likely not ours. case ButtplugDeviceMessage m: _bpLogger.Trace($"Sending {aMsg.GetType().Name} to device index {m.DeviceIndex}"); if (!Devices.ContainsKey(m.DeviceIndex)) { throw new ButtplugDeviceException(_bpLogger, $"Dropping message for unknown device index {m.DeviceIndex}", id); } return(await Devices[m.DeviceIndex].ParseMessageAsync(m, aToken).ConfigureAwait(false)); } throw new ButtplugMessageException(_bpLogger, $"Message type {aMsg.GetType().Name} unhandled by this server.", id); }
public void SetMessageResponse <T>(ButtplugMessage aMsg) where T : ButtplugMessage { _messageResponse.Remove(typeof(T)); _messageResponse.Add(typeof(T), aMsg); }
public void SendServerMessage(ButtplugMessage aMsg) { MessageReceived?.Invoke(this, new MessageReceivedEventArgs(aMsg)); }
public string Serialize(ButtplugMessage aMsg) { return(_parser.Serialize(aMsg)); }
private async Task ConnectionAccepter(string aPipeName, CancellationToken aToken) { while (!aToken.IsCancellationRequested) { var pipeServer = new NamedPipeServerStream(aPipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous); await pipeServer.WaitForConnectionAsync(aToken).ConfigureAwait(false); if (!pipeServer.IsConnected) { continue; } var server = pipeServer; var buttplugServer = _serverFactory(); void MsgReceived(object aObject, MessageReceivedEventArgs aEvent) { var msg = buttplugServer.Serialize(aEvent.Message); if (msg == null) { return; } try { if (server != null && server.IsConnected) { var output = Encoding.UTF8.GetBytes(msg); server.WriteAsync(output, 0, output.Length, aToken); } var error = aEvent.Message as Error; if (error != null && error.ErrorCode == Error.ErrorClass.ERROR_PING && server != null && server.IsConnected) { server.Close(); } } catch (WebSocketException e) { // Probably means we're replying to a message we received just before shutdown. _logger.Error(e.Message, true); } } buttplugServer.MessageReceived += MsgReceived; void ClientConnected(object aObject, EventArgs aUnused) { ConnectionAccepted?.Invoke(this, new IPCConnectionEventArgs(buttplugServer.ClientName)); } buttplugServer.ClientConnected += ClientConnected; try { _connections.Enqueue(server); while (!aToken.IsCancellationRequested && server.IsConnected) { var buffer = new byte[4096]; var msg = string.Empty; var len = -1; while (len < 0 || (len == buffer.Length && buffer[4095] != '\0')) { try { len = await server.ReadAsync(buffer, 0, buffer.Length, aToken).ConfigureAwait(false); if (len > 0) { msg += Encoding.UTF8.GetString(buffer, 0, len); } } catch { // no-op? } } if (msg.Length > 0) { ButtplugMessage[] respMsgs; try { respMsgs = await buttplugServer.SendMessageAsync(msg).ConfigureAwait(false); } catch (ButtplugException e) { respMsgs = new ButtplugMessage[] { e.ButtplugErrorMessage }; } var respMsg = buttplugServer.Serialize(respMsgs); if (respMsg == null) { continue; } var output = Encoding.UTF8.GetBytes(respMsg); await server.WriteAsync(output, 0, output.Length, aToken).ConfigureAwait(false); foreach (var m in respMsgs) { if (m is Error && (m as Error).ErrorCode == Error.ErrorClass.ERROR_PING && server.IsConnected) { server.Close(); } } } } } catch (Exception e) { _logger.Error(e.Message, true); try { server.Close(); } catch { // noop } } finally { buttplugServer.MessageReceived -= MsgReceived; await buttplugServer.ShutdownAsync().ConfigureAwait(false); buttplugServer = null; _connections.TryDequeue(out var stashed); while (stashed != server && _connections.Any()) { _connections.Enqueue(stashed); _connections.TryDequeue(out stashed); } server.Close(); server.Dispose(); server = null; ConnectionClosed?.Invoke(this, new IPCConnectionEventArgs()); } } }
protected string Serialize(ButtplugMessage aMsg) { return(_parser.Serialize(aMsg, ButtplugMessage.CurrentSchemaVersion)); }
protected string Serialize(ButtplugMessage aMsg) { return(_parser.Serialize(aMsg)); }
public async Task RunServerSession() { try { var readTask = _ws.ReadStringAsync(_linkedCancelSource.Token); var writeTask = _outgoingMessages.OutputAvailableAsync(_linkedCancelSource.Token); while (_ws.IsConnected && !_linkedCancelSource.IsCancellationRequested) { var msgTasks = new Task[] { readTask, writeTask, }; var completedTaskIndex = Task.WaitAny(msgTasks); if (completedTaskIndex == 0) { var incomingMsg = await((Task <string>)msgTasks[0]).ConfigureAwait(false); if (incomingMsg != null) { ButtplugMessage[] msg; try { msg = await _server.SendMessageAsync(incomingMsg).ConfigureAwait(false); } catch (ButtplugException ex) { msg = new ButtplugMessage[] { ex.ButtplugErrorMessage }; } await QueueMessage(msg).ConfigureAwait(false); } readTask = _ws.ReadStringAsync(_linkedCancelSource.Token); } else { try { _outgoingMessages.TryReceiveAll(out var msgs); var outMsgs = msgs.Aggregate(string.Empty, (current, msg) => current + msg); if (_ws != null && _ws.IsConnected) { await _ws.WriteStringAsync(outMsgs, _linkedCancelSource.Token).ConfigureAwait(false); } writeTask = _outgoingMessages.OutputAvailableAsync(_linkedCancelSource.Token); } catch (WebSocketException e) { // Probably means we're replying to a message we received just before shutdown. _logger.Error(e.Message, true); } } } } catch (Exception e) { _logger.Error(e.Message, true); } finally { await ShutdownSession().ConfigureAwait(false); } }
public abstract void SetResult(ButtplugMessage result);
private void CheckValidTestMessage([NotNull] ButtplugMessage aMsg) { aMsg.Should().BeOfType <Messages.Test>(); (aMsg as Messages.Test).TestString.Should().Be("Test"); }