예제 #1
0
        public override void StartScanning()
        {
            BpLogger.Info("XInputGamepadManager start scanning");
            try
            {
                var controllers = new[]
                {
                    new Controller(UserIndex.One),
                    new Controller(UserIndex.Two),
                    new Controller(UserIndex.Three),
                    new Controller(UserIndex.Four),
                };
                foreach (var c in controllers)
                {
                    if (!c.IsConnected)
                    {
                        continue;
                    }

                    BpLogger.Debug($"Found connected XInput Gamepad for Index {c.UserIndex}");
                    var device = new XInputGamepadDevice(LogManager, c);
                    InvokeDeviceAdded(new DeviceAddedEventArgs(device));
                    InvokeScanningFinished();
                }
            }
            catch (DllNotFoundException e)
            {
                // TODO Should we maybe try testing for this in construction instead of during scanning?
                BpLogger.Error($"Required DirectX DLL not found: {e.Message}\nThis probably means you need to install the DirectX Runtime from June 2010: https://www.microsoft.com/en-us/download/details.aspx?id=8109");
                InvokeScanningFinished();
            }
        }
예제 #2
0
 public override void StartScanning()
 {
     BpLogger.Info("Starting Scanning Serial Ports for ErosTek Devices");
     _isScanning = true;
     _scanThread = new Thread(() => ScanSerialPorts(null));
     _scanThread.Start();
 }
예제 #3
0
 public override void StopScanning()
 {
     // todo We need to be able to kill a CancellationToken here, otherwise things like ET312 connects will stall here.
     _scanLock.Wait();
     _scanTimer.Enabled = false;
     _scanLock.Release();
     BpLogger.Info($"Stopping timed-repeat scanning for {GetType().Name}");
     InvokeScanningFinished();
 }
예제 #4
0
 public override void StartScanning()
 {
     BpLogger.Info("Starting BLE Scanning");
     _seenAddresses.Clear();
     var t = Task.Run(async() =>
     {
         BpLogger.Info("Start BLE Scanning");
         await _adapter.StartScanningForDevicesAsync();
     });
 }
예제 #5
0
 public override void StopScanning()
 {
     BpLogger.Info("Stopping BLE Scanning");
     var t = Task.Run(async() =>
     {
         await _adapter.StopScanningForDevicesAsync();
         BpLogger.Info("Stopped BLE Scanning");
         InvokeScanningFinished();
     });
 }
예제 #6
0
        private void pipeReader(CancellationToken aCancellationToken)
        {
            while (!aCancellationToken.IsCancellationRequested && _pipeServer.IsConnected)
            {
                var    buffer = new byte[4096];
                string msg    = string.Empty;
                var    len    = -1;
                while (len < 0 || (len == buffer.Length && buffer[4095] != '\0'))
                {
                    try
                    {
                        var waiter = _pipeServer.ReadAsync(buffer, 0, buffer.Length);
                        while (!waiter.GetAwaiter().IsCompleted)
                        {
                            if (!_pipeServer.IsConnected)
                            {
                                return;
                            }

                            Thread.Sleep(10);
                        }

                        len = waiter.GetAwaiter().GetResult();
                        if (len > 0)
                        {
                            msg += Encoding.ASCII.GetString(buffer, 0, len);
                        }
                    }
                    catch
                    {
                        continue;
                    }
                }

                switch (_parser.Deserialize(msg))
                {
                case FinishedScanning fs:
                    BpLogger.Info("SimulatorManager recieved stop scanning");
                    _scanning = false;
                    InvokeScanningFinished();
                    break;

                case DeviceAdded da:
                    InvokeDeviceAdded(new DeviceAddedEventArgs(new SimulatedButtplugDevice(this, _logManager, da)));
                    break;

                case DeviceRemoved dr:
                    //InvokeDevice (new DeviceAddedEventArgs(new SimulatedButtplugDevice(_logManager, "Test", "1234")));
                    break;

                default:
                    break;
                }
            }
        }
예제 #7
0
        public VibHubManager(IButtplugLogManager aLogManager)
            : base(aLogManager)
        {
            BpLogger.Info("Loading VibHub Manager");

            //ToDo: Allow for custom ViBHub server address
            socket = new SocketIO("https://vibhub.io");
            socket.On("dev_online", OnDeviceOnline);
            socket.On("dev_offline", OnDeviceOffline);
            socket.On("aCustom", OnCustomMessage);
        }
예제 #8
0
        public override void StartScanning()
        {
            if (!_pipeServer.IsConnected)
            {
                BpLogger.Info("SimulatorManager can't start scanning until connected");
                return;
            }

            _scanning = true;
            BpLogger.Info("SimulatorManager start scanning");
            _msgQueue.Enqueue(new StartScanning());
        }
예제 #9
0
        public UWPBluetoothManager(IButtplugLogManager aLogManager)
            : base(aLogManager)
        {
            BpLogger.Info("Loading UWP Bluetooth Manager");
            _currentlyConnecting = new List <ulong>();

            // Introspect the ButtplugDevices namespace for all Factory classes, then create
            // instances of all of them.
            _deviceFactories = new List <UWPBluetoothDeviceFactory>();
            BuiltinDevices.ForEach(aDeviceFactory =>
            {
                BpLogger.Debug($"Loading Bluetooth Device Factory: {aDeviceFactory.GetType().Name}");
                _deviceFactories.Add(new UWPBluetoothDeviceFactory(aLogManager, aDeviceFactory));
            });

            _bleWatcher = new BluetoothLEAdvertisementWatcher {
                ScanningMode = BluetoothLEScanningMode.Active
            };

            // We can't filter device advertisements because you can only add one LocalName filter at
            // a time, meaning we would have to set up multiple watchers for multiple devices. We'll
            // handle our own filtering via the factory classes whenever we receive a device.
            _bleWatcher.Received += OnAdvertisementReceived;
            _bleWatcher.Stopped  += OnWatcherStopped;
            var adapterTask = Task.Run(() => BluetoothAdapter.GetDefaultAsync().AsTask());

            adapterTask.Wait();
            var adapter = adapterTask.Result;

            if (adapter == null)
            {
                BpLogger.Warn("No bluetooth adapter available for UWP Bluetooth Manager Connection");
                return;
            }

            if (!adapter.IsLowEnergySupported)
            {
                BpLogger.Warn("Bluetooth adapter available but does not support Bluetooth Low Energy.");
                return;
            }

            BpLogger.Debug("UWP Manager found working Bluetooth LE Adapter");

            // Only run radio information lookup if we're actually logging at the level it will show.
            if (aLogManager.Level >= ButtplugLogLevel.Debug)
            {
                // Do radio lookup in a background task, as the search query is very slow.
                // TODO Should probably try and cancel this if it's still running on object destruction, but the Get() call is uninterruptable?
                _radioTask = Task.Run(() => LogBluetoothRadioInfo());
            }
        }
예제 #10
0
        public XamarinBluetoothManager(IButtplugLogManager aLogManager)
            : base(aLogManager)
        {
            BpLogger.Info("Loading UWP Bluetooth Manager");

            _adapter = CrossBluetoothLE.Current.Adapter;
            if (_adapter == null)
            {
                BpLogger.Warn("No bluetooth adapter available for UWP Bluetooth Manager Connection");
                return;
            }
            _adapter.DeviceAdvertised += _adapter_DeviceAdvertised;

            BpLogger.Debug("UWP Manager found working Bluetooth LE Adapter");
        }
예제 #11
0
        public override void StartScanning()
        {
            BpLogger.Info("Starting Scanning Serial Ports for ErosTek Devices");
            _isScanning = true;
            foreach (var entry in _portDeviceTypeMap)
            {
                var device = entry.Value.CreateDevice(LogManager, entry.Key);
                if (device == null)
                {
                    BpLogger.Error($"Cannot open device on port {entry.Key}.");
                    continue;
                }

                device.InitializeAsync().Wait();
            }
        }
        public UWPBluetoothManager(IButtplugLogManager aLogManager)
            : base(aLogManager)
        {
            BpLogger.Info("Loading UWP Bluetooth Manager");
            _currentlyConnecting = new List <ulong>();

            // Introspect the ButtplugDevices namespace for all Factory classes, then create instances of all of them.
            _deviceFactories = new List <UWPBluetoothDeviceFactory>();
            BuiltinDevices.ForEach(aDeviceFactory =>
            {
                BpLogger.Debug($"Loading Bluetooth Device Factory: {aDeviceFactory.GetType().Name}");
                _deviceFactories.Add(new UWPBluetoothDeviceFactory(aLogManager, aDeviceFactory));
            });

            _bleWatcher = new BluetoothLEAdvertisementWatcher {
                ScanningMode = BluetoothLEScanningMode.Active
            };

            // We can't filter device advertisements because you can only add one LocalName filter at a time, meaning we
            // would have to set up multiple watchers for multiple devices. We'll handle our own filtering via the factory
            // classes whenever we receive a device.
            _bleWatcher.Received += OnAdvertisementReceived;
            _bleWatcher.Stopped  += OnWatcherStopped;
            var adapterTask = Task.Run(() => BluetoothAdapter.GetDefaultAsync().AsTask());

            adapterTask.Wait();
            var adapter = adapterTask.Result;

            if (adapter == null)
            {
                BpLogger.Warn("No bluetooth adapter available for UWP Bluetooth Manager Connection");
                return;
            }

            if (!adapter.IsLowEnergySupported)
            {
                BpLogger.Warn("Bluetooth adapter available but does not support Bluetooth Low Energy.");
                return;
            }

            BpLogger.Debug("UWP Manager found working Bluetooth LE Adapter");
        }
예제 #13
0
        private async Task InitUnsynced()
        {
            // It worked! Discard the rest of the response
            await ReadAsync(2).ConfigureAwait(false);

            // Commence handshake
            BpLogger.Info("Encryption is not yet set up. Send Handshake.");

            await SendCommand(new byte[]
            {
                (byte)ET312Consts.SerialCommand.KeyExchange, // synch command
                0,                                           // our key
            }).ConfigureAwait(false);

            // Receive box key
            // byte 0 - return code
            // byte 1 - box key
            // byte 2 - checksum
            var recBuffer = await ReadAsync(3).ConfigureAwait(false);

            // Response valid?
            if (recBuffer[0] != ((byte)ET312Consts.SerialResponse.KeyExchange | 0x20))
            {
                throw new ErostekET312CommunicationException("Unexpected return code from device.");
            }

            if (recBuffer[2] != Checksum(recBuffer))
            {
                throw new ErostekET312CommunicationException("Checksum error in reply from device.");
            }

            _boxKey = (byte)(recBuffer[1] ^ 0x55);

            // Override the random box key with our own (0x10) so we can reconnect to an already
            // synched box without having to guess the box key
            await Poke((uint)ET312Consts.RAM.BoxKey, 0x10).ConfigureAwait(false);

            _boxKey = 0x10;

            BpLogger.Info("Handshake with ET312 successful.");
        }
예제 #14
0
        public SimulatorManager(IButtplugLogManager aLogManager)
            : base(aLogManager)
        {
            BpLogger.Info("Loading Simulator Manager");
            _scanning = false;

            _parser = new PipeMessageParser();

            _logManager = new ButtplugLogManager();

            _pipeServer = new NamedPipeServerStream("ButtplugDeviceSimulator", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);

            _tokenSource = new CancellationTokenSource();
            _readThread  = new Task(() => { connAccepter(_tokenSource.Token); }, _tokenSource.Token, TaskCreationOptions.LongRunning);
            _writeThread = new Task(() => { pipeWriter(_tokenSource.Token); }, _tokenSource.Token, TaskCreationOptions.LongRunning);
            _pingThread  = new Task(() => { pingWriter(_tokenSource.Token); }, _tokenSource.Token, TaskCreationOptions.LongRunning);

            _readThread.Start();
            _writeThread.Start();
            _pingThread.Start();
        }
예제 #15
0
        private async Task InitSynced(CancellationToken aToken)
        {
            // Since the previous command looked like complete garbage to the box send a string of 0s
            // to get the command parser back in sync
            // Clear();
            for (var i = 0; i < 11; i++)
            {
                await Interface.WriteValueAsync(new[] { (byte)ErostekET312ProtocolConsts.SerialCommand.Sync }, aToken).ConfigureAwait(false);

                try
                {
                    // This read will fail at least once, so we can't use ReadAsync here since it
                    // doesn't currently provide a timeout. However, we can expose ReadByte() on the
                    // backing stream and use that.
                    var errByte = await Interface.ReadValueAsync(new ButtplugDeviceReadOptions { ReadLength = 1 }, aToken);

                    if (errByte.Length == 0 || errByte[0] == -1)
                    {
                        continue;
                    }

                    if (errByte[0] == (byte)ErostekET312ProtocolConsts.SerialResponse.Error)
                    {
                        break;
                    }
                }
                catch (TimeoutException)
                {
                    // No response? Keep trying.
                }
            }

            // Try reading from RAM with our pre-set box key of 0x10 - if this fails, the device is
            // in an unknown state, throw an exception.
            _boxKey = 0x10;
            await Peek((uint)ErostekET312ProtocolConsts.Flash.BoxModel, aToken).ConfigureAwait(false);

            // If we got this far we're back in business!
            BpLogger.Info("Encryption already set up. No handshake required.");
        }
예제 #16
0
        public UWPBluetoothManager(IButtplugLogManager aLogManager)
            : base(aLogManager)
        {
            BpLogger.Info("Loading UWP Bluetooth Manager");

            // We can't filter device advertisements because you can only add one LocalName filter at
            // a time, meaning we would have to set up multiple watchers for multiple devices. We'll
            // handle our own filtering via the factory classes whenever we receive a device.
            _bleWatcher.Received += OnAdvertisementReceived;
            _bleWatcher.Stopped  += OnWatcherStopped;
            var adapterTask = Task.Run(() => BluetoothAdapter.GetDefaultAsync().AsTask());

            adapterTask.Wait();
            var adapter = adapterTask.Result;

            if (adapter == null)
            {
                BpLogger.Warn("No bluetooth adapter available for UWP Bluetooth Manager Connection");
                return;
            }

            if (!adapter.IsLowEnergySupported)
            {
                BpLogger.Warn("Bluetooth adapter available but does not support Bluetooth Low Energy.");
                return;
            }

            BpLogger.Debug("UWP Manager found working Bluetooth LE Adapter");

            // Only run radio information lookup if we're actually logging at the level it will show.
            if (aLogManager.MaxLevel >= ButtplugLogLevel.Debug)
            {
                // Do radio lookup in a background task, as the search query is very slow. TODO
                // Should probably try and cancel this if it's still running on object destruction,
                // but the Get() call is uninterruptable?
                _radioTask = Task.Run(() => LogBluetoothRadioInfo());
            }
        }
        public override void StartScanning()
        {
            BpLogger.Info("XInputGamepadManager start scanning");
            var controllers = new[]
            {
                new Controller(UserIndex.One),
                new Controller(UserIndex.Two),
                new Controller(UserIndex.Three),
                new Controller(UserIndex.Four),
            };

            foreach (var c in controllers)
            {
                if (!c.IsConnected)
                {
                    continue;
                }

                BpLogger.Debug($"Found connected XInput Gamepad for Index {c.UserIndex}");
                var device = new XInputGamepadDevice(LogManager, c);
                InvokeDeviceAdded(new DeviceAddedEventArgs(device));
                InvokeScanningFinished();
            }
        }
예제 #18
0
        protected override void RunScan()
        {
            BpLogger.Info("VibHubManager start scanning");
            try
            {
                var devices = File.ReadAllLines(@"vibhub.txt");
                if (!devices.Any())
                {
                    return;
                }

                if (!socket.Connected)
                {
                    socket.ConnectAsync();
                    socket.EmitAsync("app", "B******g Server");
                }

                foreach (var dev in devices)
                {
                    if (dev.Length > 0)
                    {
                        socket.EmitAsync("hookup", data => HookupAck(data, dev), dev);
                    }
                }
            }
            catch (FileNotFoundException e)
            {
                BpLogger.Info(e.Message);
            }
            catch (Exception e)
            {
                BpLogger.Error(e.Message);
            }

            InvokeScanningFinished();
        }
예제 #19
0
 public WinUSBManager(IButtplugLogManager aLogManager)
     : base(aLogManager)
 {
     BpLogger.Info("Loading WinUSB Manager");
 }
 public override void StartScanning()
 {
     BpLogger.Info("Starting BLE Scanning");
     _bleWatcher.Start();
 }
 public override void StopScanning()
 {
     BpLogger.Info("Stopping BLE Scanning");
     _bleWatcher.Stop();
 }
예제 #22
0
 public XInputGamepadManager(IButtplugLogManager aLogManager)
     : base(aLogManager)
 {
     BpLogger.Info("Loading XInput Gamepad Manager");
 }
 private void OnWatcherStopped(BluetoothLEAdvertisementWatcher aObj,
                               BluetoothLEAdvertisementWatcherStoppedEventArgs aEvent)
 {
     BpLogger.Info("Stopped BLE Scanning");
     InvokeScanningFinished();
 }
예제 #24
0
 public override void StopScanning()
 {
     _scanning = false;
     BpLogger.Info("SimulatorManager stop scanning");
     _msgQueue.Enqueue(new StopScanning());
 }
예제 #25
0
 public ETSerialManager(IButtplugLogManager aLogManager)
     : base(aLogManager)
 {
     BpLogger.Info("Loading ErosTek Serial Port Manager");
 }
예제 #26
0
 public override void StopScanning()
 {
     // noop
     BpLogger.Info("XInputGamepadManager stop scanning");
 }
예제 #27
0
        private void ScanSerialPorts(string[] selectedComPorts)
        {
            _isScanning = true;
            var count = 5;

            while (_isScanning && count-- > 0)
            {
                // Enumerate Ports
                string[] comPortsToScan;
                if (selectedComPorts == null || selectedComPorts.Length == 0)
                {
                    comPortsToScan = SerialPort.GetPortNames();
                }
                else
                {
                    comPortsToScan = selectedComPorts;
                }

                // try to detect devices on all port
                foreach (var port in comPortsToScan)
                {
                    BpLogger.Info("Scanning " + port);

                    SerialPort serialPort = new SerialPort(port)
                    {
                        ReadTimeout  = 200,
                        WriteTimeout = 200,
                        BaudRate     = 19200,
                        Parity       = Parity.None,
                        StopBits     = StopBits.One,
                        DataBits     = 8,
                        Handshake    = Handshake.None,
                    };

                    try
                    {
                        serialPort.Open();
                    }
                    catch (Exception ex)
                    {
                        if (ex is UnauthorizedAccessException ||
                            ex is ArgumentOutOfRangeException ||
                            ex is IOException)
                        {
                            // This port is inaccessible.
                            // Possibly because a device detected earlier is already using it,
                            // or because our required parameters are not supported
                            continue;
                        }

                        throw;
                    }

                    // We send 0x00 up to 11 times until we get 0x07 back.
                    // Why 11? See et312-protocol.org
                    var detected = false;

                    for (var i = 0; i < 11; i++)
                    {
                        try
                        {
                            serialPort.Write(new[] { (byte)SerialCommand.Sync }, 0, 1);
                        }
                        catch (Exception ex)
                        {
                            if (ex is TimeoutException ||
                                ex is UnauthorizedAccessException ||
                                ex is IOException)
                            {
                                // Can't write to this port? Skip to the next one.
                                break;
                            }

                            throw;
                        }

                        try
                        {
                            if (serialPort.ReadByte() != (byte)SerialResponse.Error)
                            {
                                continue;
                            }

                            detected = true;
                            break;
                        }
                        catch (Exception ex)
                        {
                            if (ex is TimeoutException ||
                                ex is UnauthorizedAccessException ||
                                ex is IOException)
                            {
                                // Can't write to this port? Skip to the next one.
                                continue;
                            }

                            throw;
                        }
                    }

                    if (detected)
                    {
                        // This seems to be an ET312! Let's try to create the device.
                        try
                        {
                            var device = new ET312Device(serialPort, LogManager, "Erostek ET-312", port);

                            BpLogger.Info("Found device at port " + port);

                            // Device succesfully created!
                            InvokeDeviceAdded(new DeviceAddedEventArgs(device));
                            continue;
                        }
                        catch (ET312HandshakeException)
                        {
                            // Sync Failed. Not the device we were expecting or comms garbled.
                        }
                    }

                    // No useful device detected on this port. Close the port.
                    serialPort.Close();
                    serialPort.Dispose();
                }

                Thread.Sleep(3000);

                // _isScanning = false; // Uncomment to disable continuuous serial port scanning
            }

            if (count < 0)
            {
                BpLogger.Info("Automatically Stopping Scanning Serial Ports for ErosTek Devices");
            }

            _isScanning = false;
            InvokeScanningFinished();
        }
예제 #28
0
 public override void StartScanning()
 {
     BpLogger.Info("SimulatorManager start scanning");
     _scanning = true;
     _msgQueue.Enqueue(new StartScanning());
 }
예제 #29
0
        protected override void RunScan()
        {
            foreach (var factory in DeviceConfigurationManager.Manager.GetAllFactoriesOfType <USBProtocolConfiguration>())
            {
                BpLogger.Info("WinUSBManager start scanning");
                var deviceKey =
                    Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Enum\USB\VID_0B49&PID_064F");
                if (deviceKey == null)
                {
                    BpLogger.Debug("No TranceVibrator Devices found in registry.");
                    InvokeScanningFinished();
                    return;
                }

                var deviceKeyNames = deviceKey.GetSubKeyNames();
                if (deviceKeyNames.Length == 0)
                {
                    BpLogger.Debug("No TranceVibrator Devices with drivers found in registry.");
                    InvokeScanningFinished();
                    return;
                }

                var deviceSubKey = deviceKey.OpenSubKey(deviceKeyNames[0]);
                if (deviceSubKey == null)
                {
                    BpLogger.Debug("No TranceVibrator Devices with drivers subkeys found in registry.");
                    InvokeScanningFinished();
                    return;
                }

                var deviceParameters = deviceSubKey.OpenSubKey("Device Parameters");
                if (deviceParameters == null)
                {
                    BpLogger.Debug("No TranceVibrator Devices with drivers parameters found in registry.");
                    InvokeScanningFinished();
                    return;
                }

                var    deviceRegistryObject = deviceParameters.GetValue("DeviceInterfaceGUIDs", string.Empty);
                string deviceGuid           = string.Empty;
                if (deviceRegistryObject == null)
                {
                    BpLogger.Debug("No TranceVibrator Devices Driver GUIDs found in registry.");
                    InvokeScanningFinished();
                    return;
                }

                try
                {
                    var guidStrings = (string[])deviceRegistryObject;
                    deviceGuid = guidStrings[0];
                }
                catch (Exception)
                {
                    try
                    {
                        // Some versions of Zadig, the registry key writes as a string, not a string array?
                        deviceGuid = (string)deviceRegistryObject;
                    }
                    catch (Exception)
                    {
                        BpLogger.Error("Cannot cast device GUID from registry value, cannot connect to Trancevibe.");
                    }
                }

                if (deviceGuid.Length == 0)
                {
                    BpLogger.Error("Cannot find device GUID from registry value, cannot connect to Trancevibe.");
                    return;
                }

                // Only valid for our Trancevibrator install
                var devices = USBDevice.GetDevices(deviceGuid);
                if (devices == null || devices.Length == 0)
                {
                    BpLogger.Error("No USB Device found!");
                    InvokeScanningFinished();
                    return;
                }

                uint index = 0;
                foreach (var deviceinfo in devices)
                {
                    var device = new USBDevice(deviceinfo);
                    BpLogger.Debug("Found TranceVibrator Device");
                    var bpDevice = factory.CreateDevice(LogManager, new WinUSBDeviceImpl(LogManager, device)).Result;
                    InvokeDeviceAdded(new DeviceAddedEventArgs(bpDevice));
                }
            }

            InvokeScanningFinished();
        }
예제 #30
0
 public override void StopScanning()
 {
     BpLogger.Info("Stopping Scanning Serial Ports for ErosTek Devices");
     _isScanning = false;
 }