public LovehoneyDesireProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, "Lovehoney Desire Device", aInterface) { if (_deviceMap.TryGetValue(aInterface.Name, out var dev)) { _devInfo = dev; Name = $"Lovehoney Desire {dev.Name}"; } else { _devInfo = new LovehoneyDesireType() { Name = "Unknown Lovehoney Desire Device", VibeCount = 1, }; } AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes() { FeatureCount = _devInfo.VibeCount }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public CuemeProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, "Cueme Unknown", aInterface) { var bits = aInterface.Name.Split('_'); if (bits.Length == 3 && uint.TryParse(bits[2], out var typeNum) && DevInfos.ContainsKey(typeNum)) { _devInfo = DevInfos[typeNum]; } else { BpLogger.Warn($"Cannot identify Cueme device {Name}, defaulting to Womens settings."); _devInfo = DevInfos[3]; } Name = $"Cueme {_devInfo.Name}"; // Create a new timer that wont fire any events just yet _updateValueTimer.Interval = DelayTimeMS; _updateValueTimer.Elapsed += CuemeUpdateHandler; _updateValueTimer.Enabled = false; aInterface.DeviceRemoved += OnDeviceRemoved; AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes { FeatureCount = _devInfo.VibeCount }); }
public KiirooGen1Protocol([NotNull] IButtplugLogManager aLogManager, [NotNull] IButtplugDeviceImpl aInterface) : base(aLogManager, $"Kiiroo {aInterface.Name}", aInterface) { AddMessageHandler <KiirooCmd>(HandleKiirooRawCmd); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); // ReSharper disable once ConvertIfStatementToSwitchStatement if (aInterface.Name == "PEARL") { AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes() { FeatureCount = 1 }); AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); } else if (aInterface.Name == "ONYX") { AddMessageHandler <LinearCmd>(HandleLinearCmd, new MessageAttributes() { FeatureCount = 1 }); AddMessageHandler <FleshlightLaunchFW12Cmd>(HandleFleshlightLaunchFW12Cmd); } }
public LiBoProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, $"LiBo ({aInterface.Name})", aInterface) { if (DevInfos.ContainsKey(aInterface.Name)) { _devInfo = DevInfos[aInterface.Name]; Name = $"LiBo {_devInfo.Name}"; } else { // Pick the single vibe baseline BpLogger.Warn($"Cannot identify device {Name}, defaulting to LuLu settings."); _devInfo = DevInfos["LuXiaoHan"]; } AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); if (_devInfo.VibeCount > 0) { AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes { FeatureCount = _devInfo.VibeCount }); } // TODO Add an explicit handler for Estim shocking, kegel pressure and add a battery handler. }
public WeVibeProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, $"WeVibe {aInterface.Name}", aInterface) { if (DualVibes.Contains(aInterface.Name)) { _vibratorCount = 2; } if (NameMap.ContainsKey(aInterface.Name)) { Name = $"WeVibe {NameMap[aInterface.Name]}"; } if (EightBitSpeed.Contains(aInterface.Name)) { _eightBitSpeed = true; } AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes() { FeatureCount = _vibratorCount }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public TestProtocolDoubleAdd(ButtplugLogManager aLogger, IButtplugDeviceImpl aDevice) : base(aLogger, aDevice) { // Add HandleRotateCmd twice, should throw AddMessageHandler <RotateCmd>(HandleRotateCmd); AddMessageHandler <RotateCmd>(HandleRotateCmd); }
public LovenseProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, "Lovense Device (Uninitialized)", aInterface) { AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public RealTouchProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aDevice) : base(aLogManager, "RealTouch", aDevice) { // TODO How do we get a product string here, to tell what firmware version we're on? // AddMessageHandler<RotateCmd>(HandleRotateCmd, new MessageAttributes() { FeatureCount = 1 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); AddMessageHandler <FleshlightLaunchFW12Cmd>(HandleFleshlightLaunchFW12Cmd); AddMessageHandler <LinearCmd>(HandleLinearCmd); }
public static ButtplugDevice Create <T>(IButtplugLogManager aLogManager, IButtplugDeviceImpl aDevice, Func <IButtplugLogManager, IButtplugDeviceImpl, T> aProtocolCreationFunc) where T : IButtplugDeviceProtocol, new() { var p = aProtocolCreationFunc(aLogManager, aDevice); return(new ButtplugDevice(aLogManager, p, aDevice)); }
public VorzeSAProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, "Vorze SA Unknown", aInterface) { switch (aInterface.Name) { case "CycSA": _deviceType = DeviceType.CycloneOrUnknown; _commandType = CommandType.Rotate; Name = "Vorze A10 Cyclone SA"; break; case "UFOSA": _deviceType = DeviceType.UFO; _commandType = CommandType.Rotate; Name = "Vorze UFO SA"; break; case "Bach smart": _deviceType = DeviceType.Bach; _commandType = CommandType.Vibrate; Name = "Vorze Bach"; break; default: // If the device doesn't identify, warn and try sending it Cyclone packets. BpLogger.Warn($"Vorze product with unrecognized name ({Name}) found. This product may not work with B******g. Contact the developers for more info."); break; } switch (_commandType) { case CommandType.Rotate: AddMessageHandler <VorzeA10CycloneCmd>(HandleVorzeA10CycloneCmd); AddMessageHandler <RotateCmd>(HandleRotateCmd, new MessageAttributes() { FeatureCount = 1 }); break; case CommandType.Vibrate: AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes() { FeatureCount = 1 }); break; default: BpLogger.Error("Unhandled command type."); break; } AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public XInputProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aDevice) : base(aLogManager, "XBox Compatible Gamepad (XInput)", aDevice) { AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes() { FeatureCount = 2 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
/// <summary> /// Initializes a new instance of the <see cref="ButtplugDevice"/> class. /// </summary> /// <param name="aLogManager">The log manager.</param> /// <param name="aDevice">The device implementation (Bluetooth, USB, etc).</param> /// <param name="aProtocolType">A Type for a protocol, which we will create an instance of.</param> public ButtplugDevice([NotNull] IButtplugLogManager aLogManager, [NotNull] Type aProtocolType, [NotNull] IButtplugDeviceImpl aDevice) : this(aLogManager, // A lot of trust happening in the structure of protocol constructors here. // todo should probably document the many ways this can throw. (IButtplugDeviceProtocol)Activator.CreateInstance(aProtocolType, aLogManager, aDevice), aDevice) { }
public CycloneX10Protocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aDevice) : base(aLogManager, "Vorze Cyclone X10", aDevice) { AddMessageHandler <VorzeA10CycloneCmd>(HandleVorzeA10CycloneCmd); AddMessageHandler <RotateCmd>(HandleRotateCmd, new MessageAttributes() { FeatureCount = 1 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
/// <summary> /// Initializes a new instance of the <see cref="ButtplugDevice"/> class. /// </summary> /// <param name="aLogManager">The log manager.</param> /// <param name="aDevice">The device implementation (Bluetooth, USB, etc).</param> /// <param name="aProtocol">The device protocol (Lovense, Launch, etc).</param> public ButtplugDevice([NotNull] IButtplugLogManager aLogManager, [NotNull] IButtplugDeviceProtocol aProtocol, [NotNull] IButtplugDeviceImpl aDevice) { // Protocol can be null if activator construction from type constructor fails ButtplugUtils.ArgumentNotNull(aProtocol, nameof(aProtocol)); _protocol = aProtocol; _device = aDevice; BpLogger = aLogManager.GetLogger(GetType()); _device.DeviceRemoved += OnDeviceRemoved; }
public VibratissimoProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, $"Vibratissimo Device ({aInterface.Name})", aInterface) { AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes { FeatureCount = 1 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public TestProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, "Test Device", aInterface) { Name = aInterface.Name; AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes() { FeatureCount = 2 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public RealovProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, "Realov Device", aInterface) { AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes() { FeatureCount = 1 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public KiirooGen21Protocol([NotNull] IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, "Kiiroo Onyx2.1", aInterface) { // Setup message function array AddMessageHandler <FleshlightLaunchFW12Cmd>(HandleFleshlightLaunchFW12Cmd); AddMessageHandler <LinearCmd>(HandleLinearCmd, new MessageAttributes() { FeatureCount = 1 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public YoucupsProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, "Youcups Unknown", aInterface) { if (FriendlyNames.ContainsKey(aInterface.Name)) { Name = $"Youcups {FriendlyNames[aInterface.Name]}"; } AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes() { FeatureCount = 1 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public MysteryVibeProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, "MysteryVibe Crescendo", aInterface) { // Create a new timer that wont fire any events just yet _updateValueTimer.Interval = DelayTimeMS; _updateValueTimer.Elapsed += MysteryVibeUpdateHandler; _updateValueTimer.Enabled = false; aInterface.DeviceRemoved += OnDeviceRemoved; AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes { FeatureCount = 6 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public PicobongProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, $"Picobong {aInterface.Name}", aInterface) { if (NameMap.ContainsKey(Name)) { Name = NameMap[Name]; } AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes() { FeatureCount = 1 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public KiirooGen2Protocol([NotNull] IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, "Kiiroo V2 Protocol Device", aInterface) { if (_brandNames.ContainsKey(aInterface.Name)) { Name = $"{_brandNames[aInterface.Name]} {aInterface.Name}"; } // Setup message function array AddMessageHandler <FleshlightLaunchFW12Cmd>(HandleFleshlightLaunchFW12Cmd); AddMessageHandler <LinearCmd>(HandleLinearCmd, new MessageAttributes() { FeatureCount = 1 }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public KiirooGen2VibeProtocol([NotNull] IButtplugLogManager aLogManager, [NotNull] IButtplugDeviceImpl aInterface) : base(aLogManager, "Kiiroo Unknown", aInterface) { if (DevInfos.ContainsKey(aInterface.Name)) { Name = $"{DevInfos[aInterface.Name].Brand} {aInterface.Name}"; _devInfo = DevInfos[aInterface.Name]; } else { BpLogger.Warn($"Cannot identify device {Name}, defaulting to Pearl2 settings."); _devInfo = DevInfos["Unknown"]; } AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes { FeatureCount = _devInfo.VibeCount }); AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); }
public MagicMotionProtocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aInterface) : base(aLogManager, $"Unknown MagicMotion Device ({aInterface.Name})", aInterface) { if (DevInfos.ContainsKey(aInterface.Name)) { _devInfo = DevInfos[aInterface.Name]; Name = $"{_devInfo.Brand} {_devInfo.Name}"; } else { BpLogger.Warn($"Cannot identify device {Name}, defaulting to Smart Mini Vibe settings."); _devInfo = DevInfos["Smart Mini Vibe"]; } AddMessageHandler <SingleMotorVibrateCmd>(HandleSingleMotorVibrateCmd); AddMessageHandler <VibrateCmd>(HandleVibrateCmd, new MessageAttributes { FeatureCount = _devInfo.VibeCount }); AddMessageHandler <StopDeviceCmd>(HandleStopDeviceCmd); }
public ErostekET312Protocol(IButtplugLogManager aLogManager, IButtplugDeviceImpl aDevice) : base(aLogManager, $"Erostek ET312 - {aDevice.Name}", aDevice) { }
private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher aObj, BluetoothLEAdvertisementReceivedEventArgs aEvent) { if (aEvent?.Advertisement == null) { BpLogger.Debug("Null BLE advertisement received: skipping"); return; } var advertName = aEvent.Advertisement.LocalName ?? string.Empty; var advertGUIDs = new List <Guid>(); advertGUIDs.AddRange(aEvent.Advertisement.ServiceUuids ?? new Guid[] { }); var btAddr = aEvent.BluetoothAddress; // BpLogger.Trace($"Got BLE Advertisement for device: {aEvent.Advertisement.LocalName} / {aEvent.BluetoothAddress}"); if (_seenAddresses.Contains(btAddr)) { // BpLogger.Trace($"Ignoring advertisement for already connecting device: // {aEvent.Advertisement.LocalName} / {aEvent.BluetoothAddress}"); return; } BpLogger.Trace("BLE device found: " + advertName); // We always need a name to match against. if (advertName == string.Empty) { return; } // todo Add advertGUIDs back in. Not sure that ever really gets used though. var deviceCriteria = new BluetoothLEProtocolConfiguration(advertName); var deviceFactory = DeviceConfigurationManager.Manager.Find(deviceCriteria); // If we don't have a protocol to match the device, we can't do anything with it. if (deviceFactory == null || !(deviceFactory.Config is BluetoothLEProtocolConfiguration bleConfig)) { BpLogger.Debug($"No usable device factory available for {advertName}."); // If we've got an actual name this time around, and we don't have any factories // available that match the info we have, add to our seen list so we won't keep // rechecking. If a device does have a factory, but doesn't connect, we still want to // try again. _seenAddresses.Add(btAddr); return; } var fromBluetoothAddressAsync = BluetoothLEDevice.FromBluetoothAddressAsync(btAddr); // Can return null if the device no longer exists, for instance if it turned off between // advertising and us getting here. Since we didn't get a chance to try to connect, // remove it from seen devices, since the user may turn it back on during this scanning period. if (fromBluetoothAddressAsync == null) { return; } var dev = await fromBluetoothAddressAsync; // If a device is turned on after scanning has started, windows seems to lose the device // handle the first couple of times it tries to deal with the advertisement. Just log the // error and hope it reconnects on a later retry. IButtplugDeviceImpl bleDevice = null; IButtplugDevice btDevice = null; try { bleDevice = await UWPBluetoothDeviceInterface.Create(LogManager, bleConfig, dev).ConfigureAwait(false); btDevice = await deviceFactory.CreateDevice(LogManager, bleDevice).ConfigureAwait(false); InvokeDeviceAdded(new DeviceAddedEventArgs(btDevice)); } catch (Exception ex) { if (btDevice != null) { btDevice.Disconnect(); } else { bleDevice?.Disconnect(); } BpLogger.Error( $"Cannot connect to device {advertName} {btAddr}: {ex.Message}"); } }
private async void _adapter_DeviceAdvertised(object sender, Plugin.BLE.Abstractions.EventArgs.DeviceEventArgs e) { if (e?.Device == null) { BpLogger.Debug("Null BLE advertisement received: skipping"); return; } string advertName = e.Device.GetPropValue <string>("BluetoothDevice.Name"); var advertGUIDs = new List <Guid>(); advertGUIDs.Add(e.Device.Id); var btAddr = e.Device.GetPropValue <string>("BluetoothDevice.Address"); BpLogger.Trace($"Got BLE Advertisement for device: {advertName} / {btAddr}"); if (_seenAddresses.Contains(btAddr)) { BpLogger.Trace($"Ignoring advertisement for already connecting device: {btAddr}"); return; } _seenAddresses.Add(btAddr); BpLogger.Trace("BLE device found: " + advertName); // We always need a name to match against. if (String.IsNullOrEmpty(advertName)) { return; } // todo Add advertGUIDs back in. Not sure that ever really gets used though. var deviceCriteria = new BluetoothLEProtocolConfiguration(advertName); var deviceFactory = DeviceConfigurationManager.Manager.Find(deviceCriteria); // If we don't have a protocol to match the device, we can't do anything with it. if (deviceFactory == null || !(deviceFactory.Config is BluetoothLEProtocolConfiguration bleConfig)) { BpLogger.Debug($"No usable device factory available for {advertName}."); return; } // If a device is turned on after scanning has started, windows seems to lose the device // handle the first couple of times it tries to deal with the advertisement. Just log the // error and hope it reconnects on a later retry. IButtplugDeviceImpl bleDevice = null; IButtplugDevice btDevice = null; try { await _adapter.ConnectToDeviceAsync(e.Device); bleDevice = await XamarinBluetoothDeviceInterface.Create(LogManager, bleConfig, e.Device).ConfigureAwait(false); btDevice = await deviceFactory.CreateDevice(LogManager, bleDevice).ConfigureAwait(false); InvokeDeviceAdded(new DeviceAddedEventArgs(btDevice)); } catch (Exception ex) { if (btDevice != null) { btDevice.Disconnect(); } else { bleDevice?.Disconnect(); } BpLogger.Error( $"Cannot connect to device {advertName} {btAddr}: {ex.Message}"); } }
public async Task <IButtplugDevice> CreateDevice(IButtplugLogManager aLogManager, IButtplugDeviceImpl aDevice) { var device = new ButtplugDevice(aLogManager, _protocolType, aDevice); // Run initialization now, just to make sure we're ready to go when we hand the device back. // TODO should probably find a better cancellation token for this. Or like, any at all. await device.InitializeAsync(CancellationToken.None).ConfigureAwait(false); return(device); }