public ButtplugServer(ButtplugServerOptions aOptions)
        {
            ButtplugUtils.ArgumentNotNull(aOptions, nameof(aOptions));
            _clientName   = null;
            _serverName   = aOptions.ServerName;
            _maxPingTime  = aOptions.MaxPingTime;
            _pingTimedOut = false;
            if (_maxPingTime != 0)
            {
                // Create a new timer that wont fire any events just yet
                _pingTimer = new Timer(PingTimeoutHandler, null, Timeout.Infinite, Timeout.Infinite);
            }

            BpLogManager = new ButtplugLogManager();
            _bpLogger    = BpLogManager.GetLogger(GetType());
            _bpLogger.Debug("Setting up ButtplugServer");
            _parser        = new ButtplugJsonMessageParser(BpLogManager);
            _deviceManager = aOptions.DeviceManager ?? new DeviceManager(BpLogManager, aOptions.SubtypeManagerSearchPaths);

            _bpLogger.Info("Finished setting up ButtplugServer");
            _deviceManager.DeviceMessageReceived += DeviceMessageReceivedHandler;
            _deviceManager.ScanningFinished      += ScanningFinishedHandler;

            if (!DeviceConfigurationManager.HasManager)
            {
                DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            }
        }
        public void TestDeviceConfigNoMatch()
        {
            DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            var factory = DeviceConfigurationManager.Manager.Find(new BluetoothLEProtocolConfiguration("Whatever"));

            factory.Should().BeNull();
        }
        public void TestDeviceConfigMatching()
        {
            DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            var factory = DeviceConfigurationManager.Manager.Find(new BluetoothLEProtocolConfiguration("LVS-Test"));

            factory.ProtocolName.Should().Be("LovenseProtocol");
        }
        public void TestAddUserConfigWithConflictingBLEName()
        {
            DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            var    mgr  = DeviceConfigurationManager.Manager;
            Action test = () => mgr.LoadUserConfigurationString(@"
protocols:
  mysteryvibe:
    btle:
      names:
        - MV Crescendo
");

            test.Should().Throw <ButtplugDeviceException>();
        }
        public void TestAddUserConfigWithInvalidProtocol()
        {
            DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            var    mgr  = DeviceConfigurationManager.Manager;
            Action test = () => mgr.LoadUserConfigurationString(@"
protocols:
  not-a-protocol:
    serial:
      ports:
        - COM1
        - /dev/ttyUSB0
");

            test.Should().Throw <ButtplugDeviceException>();
        }
        public void TestUserConfig()
        {
            DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            var mgr = DeviceConfigurationManager.Manager;

            mgr.LoadUserConfigurationString(@"
protocols:
  erostek-et312:
    serial:
      ports:
        - COM1
        - /dev/ttyUSB0
");
            mgr.Find(new SerialProtocolConfiguration("COM1")).Should().NotBeNull();
            mgr.Find(new SerialProtocolConfiguration("COM2")).Should().BeNull();
        }
        public void TestAddUserConfigWithConflictingBLEService()
        {
            DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            var    mgr  = DeviceConfigurationManager.Manager;
            Action test = () => mgr.LoadUserConfigurationString(@"
protocols:
  mysteryvibe:
    btle:
      services:
        f0006900-110c-478B-B74B-6F403B364A9C:
          txmode: f0006901-110c-478B-B74B-6F403B364A9C
          txvibrate: f0006903-110c-478B-B74B-6F403B364A9C
");

            test.Should().Throw <ButtplugDeviceException>();
        }
        public void TestAddUserConfigWithInvalidProtocol()
        {
            DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            var    mgr  = DeviceConfigurationManager.Manager;
            Action test = () => mgr.LoadUserConfigurationString(@"
{
   'protocols': {
            'not-a-protocol': {
                'serial': {
                    'ports': [
                    'COM1',
                    '/dev/ttyUSB0'
                        ]
                }
            }
        }
    }
");

            test.Should().Throw <ButtplugDeviceException>();
        }
        public void TestUserConfig()
        {
            DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            var mgr = DeviceConfigurationManager.Manager;

            mgr.LoadUserConfigurationString(@"
{
   'protocols': {
            'erostek-et312': {
                'serial': {
                    'ports': [
                    'COM1',
                    '/dev/ttyUSB0'
                        ]
                }
            }
        }
    }
");
            mgr.Find(new SerialProtocolConfiguration("COM1")).Should().NotBeNull();
            mgr.Find(new SerialProtocolConfiguration("COM2")).Should().BeNull();
        }
        public void TestAddUserConfigWithConflictingBLEService()
        {
            DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            var    mgr  = DeviceConfigurationManager.Manager;
            Action test = () => mgr.LoadUserConfigurationString(@"
{
   'protocols': {
            'mysteryvibe': {
                'btle': {
                    'services': {
                        'f0006900-110c-478B-B74B-6F403B364A9C': {
                            'txmode': 'f0006901-110c-478B-B74B-6F403B364A9C',
                            'txvibrate': 'f0006903-110c-478B-B74B-6F403B364A9C'
                        }
                    }
                }
            }
        }
    }
");

            test.Should().Throw <ButtplugDeviceException>();
        }
Exemple #11
0
        public void RunServer(Options aOptions)
        {
            if (aOptions.Version)
            {
                Console.WriteLine("1");
                return;
            }

            _useProtobufOutput = aOptions.FrontendPipe;
            if (_useProtobufOutput)
            {
                _stdioTask = new Task(ReadStdio);
                _stdioTask.Start();
            }

            if (aOptions.GenerateCertificate)
            {
                // CertUtils.GenerateSelfSignedCert(aOptions.CertFile, aOptions.PrivFile);
                Console.WriteLine("Cannot currently generate certificates.");
                return;
            }

            if (aOptions.DeviceConfigFile != null)
            {
                DeviceConfigurationManager.LoadBaseConfigurationFile(aOptions.DeviceConfigFile);
            }
            else
            {
                DeviceConfigurationManager.LoadBaseConfigurationFromResource();
            }

            if (aOptions.UserDeviceConfigFile != null)
            {
                DeviceConfigurationManager.Manager.LoadUserConfigurationFile(aOptions.UserDeviceConfigFile);
            }

            if (aOptions.WebsocketServerInsecurePort == 0 && aOptions.WebsocketServerSecurePort == 0 && !aOptions.UseIpcServer)
            {
                PrintProcessLog("ERROR: Must specify either IPC server or Websocket server!");
                return;
            }

            var logLevel = ButtplugLogLevel.Off;

            if (aOptions.Log != null)
            {
                if (!Enum.TryParse(aOptions.Log, out logLevel))
                {
                    PrintProcessLog("ERROR: Invalid log level!");
                    return;
                }
            }

            ButtplugServer ServerFactory()
            {
                var server = new CLIServer(aOptions.ServerName, (uint)aOptions.PingTime, _deviceManager);

                // Pull out the device manager for reuse later.
                if (_deviceManager == null)
                {
                    _deviceManager = server.DeviceManager;
                }

                if (logLevel != ButtplugLogLevel.Off)
                {
                    server.LogManager.AddLogListener(logLevel, (aLogMsg) =>
                    {
                        PrintProcessLog(aLogMsg.LogMessage);
                    });
                }

                server.ClientConnected += (aObj, aEvent) =>
                {
                    if (_useProtobufOutput)
                    {
                        SendProcessMessage(new ServerProcessMessage
                        {
                            ClientConnected = new ServerProcessMessage.Types.ClientConnected
                            {
                                ClientName = server.ClientName
                            }
                        });
                    }
                    else
                    {
                        Console.WriteLine($"Client connected: {server.ClientName}");
                    }
                };

                return(server);
            }

            ButtplugIPCServer       ipcServer = null;
            ButtplugWebsocketServer insecureWebsocketServer = null;
            ButtplugWebsocketServer secureWebsocketServer   = null;

            if (aOptions.WebsocketServerInsecurePort != 0)
            {
                insecureWebsocketServer = new ButtplugWebsocketServer();
                insecureWebsocketServer.StartServerAsync(ServerFactory, 1, aOptions.WebsocketServerInsecurePort,
                                                         !aOptions.WebsocketServerAllInterfaces).Wait();
                insecureWebsocketServer.ConnectionClosed += (aSender, aArgs) => { _disconnectWait.SetResult(true); };
                PrintProcessLog("Insecure websocket Server now running...");
            }

            if (aOptions.WebsocketServerSecurePort != 0 && aOptions.CertFile != null &&
                aOptions.PrivFile != null)
            {
                secureWebsocketServer = new ButtplugWebsocketServer();
                secureWebsocketServer.StartServerAsync(ServerFactory, 1, aOptions.WebsocketServerSecurePort,
                                                       !aOptions.WebsocketServerAllInterfaces, aOptions.CertFile, aOptions.PrivFile).Wait();
                secureWebsocketServer.ConnectionClosed += (aSender, aArgs) => { _disconnectWait.SetResult(true); };
                PrintProcessLog("Secure websocket Server now running...");
            }

            if (aOptions.UseIpcServer)
            {
                ipcServer = new ButtplugIPCServer();
                ipcServer.StartServer(ServerFactory, aOptions.IpcPipe);
                ipcServer.ConnectionClosed += (aSender, aArgs) => { _disconnectWait.SetResult(true); };
                PrintProcessLog("IPC Server now running...");
            }

            // Now that all server possibilities are up and running, if we have a pipe, let the
            // parent program know we've started.
            if (_useProtobufOutput)
            {
                var msg = new ServerProcessMessage
                {
                    ProcessStarted = new ServerProcessMessage.Types.ProcessStarted()
                };
                SendProcessMessage(msg);
            }
            else
            {
                Console.WriteLine("Server started, waiting for client connection.");
            }

            do
            {
                _disconnectWait.Task.Wait();

                if (ipcServer != null && ipcServer.Connected)
                {
                    ipcServer?.Disconnect();
                }

                if (insecureWebsocketServer != null && insecureWebsocketServer.Connected)
                {
                    insecureWebsocketServer?.DisconnectAsync().Wait();
                }

                if (secureWebsocketServer != null && secureWebsocketServer.Connected)
                {
                    secureWebsocketServer?.DisconnectAsync().Wait();
                }

                if (_useProtobufOutput)
                {
                    var msg = new ServerProcessMessage
                    {
                        ClientDisconnected = new ServerProcessMessage.Types.ClientDisconnected()
                    };
                    SendProcessMessage(msg);
                }
                else
                {
                    Console.WriteLine("Client disconnected.");
                }
                _disconnectWait = new TaskCompletionSource <bool>();
            } while (aOptions.StayOpen && !_shouldExit);

            if (!_useProtobufOutput)
            {
                return;
            }

            PrintProcessLog("Exiting");

            if (_useProtobufOutput)
            {
                var exitMsg = new ServerProcessMessage
                {
                    ProcessEnded = new ServerProcessMessage.Types.ProcessEnded()
                };
                SendProcessMessage(exitMsg);
            }

            _stdinTokenSource.Cancel();
        }
 public void TestDeviceConfigResourceLoading()
 {
     DeviceConfigurationManager.LoadBaseConfigurationFromResource();
 }
 public void SetUp()
 {
     DeviceConfigurationManager.Clear();
 }