public override async Task InitializeAsync(CancellationToken aToken) { BpLogger.Trace($"Initializing {Name}"); // Subscribing to read updates await Interface.SubscribeToUpdatesAsync().ConfigureAwait(false); Interface.DataReceived += NotifyReceived; // Retrieving device type info for identification. await Interface.WriteValueAsync(Encoding.ASCII.GetBytes("DeviceType;"), new ButtplugDeviceWriteOptions { WriteWithResponse = true }, aToken).ConfigureAwait(false); await Task.WhenAny(_notificationWaiter.Task, Task.Delay(4000, aToken)); var deviceInfoString = _notificationWaiter.Task.Result; BpLogger.Debug($"Received device query return for {Name}"); // Expected Format X:YY:ZZZZZZZZZZZZ X is device type leter YY is firmware version Z is // bluetooth address var deviceInfo = deviceInfoString.Split(':'); // If we don't get back the amount of tokens we expect, identify as unknown, log, bail. if (deviceInfo.Length != 3 || deviceInfo[0].Length != 1) { throw new ButtplugDeviceException(BpLogger, $"Unknown Lovense DeviceType of {deviceInfoString} found. Please report to B******g Developers by filing an issue at https://github.com/buttplugio/b******g/"); } var deviceTypeLetter = deviceInfo[0][0]; if (deviceTypeLetter == 'C') { deviceTypeLetter = 'A'; } int.TryParse(deviceInfo[1], out var deviceVersion); BpLogger.Trace($"Lovense DeviceType Return: {deviceTypeLetter}"); if (!Enum.IsDefined(typeof(LovenseDeviceType), (uint)deviceTypeLetter)) { // If we don't know what device this is, just assume it has a single vibrator, call // it unknown, log something. AddCommonMessages(); throw new ButtplugDeviceException(BpLogger, $"Unknown Lovense Device of Type {deviceTypeLetter} found. Please report to B******g Developers by filing an issue at https://github.com/buttplugio/b******g/"); } Name = $"Lovense {Enum.GetName(typeof(LovenseDeviceType), (uint)deviceTypeLetter)} v{deviceVersion}"; _deviceType = (LovenseDeviceType)deviceTypeLetter; if (_deviceType == LovenseDeviceType.Unknown) { BpLogger.Error("Lovense device type unknown, treating as single vibrator device. Please contact developers for more info."); } switch (_deviceType) { case LovenseDeviceType.Edge: // Edge has 2 vibrators _vibratorCount++; break; case LovenseDeviceType.Nora: // Nora has a rotator AddMessageHandler <RotateCmd>(HandleRotateCmd, new MessageAttributes { FeatureCount = 1 }); break; } // Common messages. AddCommonMessages(); }
public override async Task <ButtplugMessage> Initialize() { BpLogger.Trace($"Initializing {Name}"); // Subscribing to read updates await Interface.SubscribeToUpdates(); Interface.BluetoothNotifyReceived += NotifyReceived; // Retreiving device type info for identification. var writeMsg = await Interface.WriteValue(ButtplugConsts.SystemMsgId, Encoding.ASCII.GetBytes($"DeviceType;"), true); if (writeMsg is Error) { BpLogger.Error($"Error requesting device info from Lovense {Name}"); return(writeMsg); } var(msg, result) = await Interface.ReadValue(ButtplugConsts.SystemMsgId); string deviceInfoString = string.Empty; if (msg is Ok) { deviceInfoString = Encoding.ASCII.GetString(result); } else { // The device info notification isn't available immediately. // TODO Turn this into a task semaphore with cancellation/timeout, let system handle check timing. int timeout = 500; while (timeout > 0) { if (_lastNotifyReceived != string.Empty) { deviceInfoString = _lastNotifyReceived; break; } timeout -= 5; await Task.Delay(5); } } if (deviceInfoString != string.Empty) { BpLogger.Debug($"Received device query return for {Interface.Name}"); // Expected Format X:YY:ZZZZZZZZZZZZ X is device type leter YY is firmware version Z // is bluetooth address var deviceInfo = deviceInfoString.Split(':'); // If we don't get back the amount of tokens we expect, identify as unknown, log, bail. if (deviceInfo.Length != 3 || deviceInfo[0].Length != 1) { return(BpLogger.LogErrorMsg(ButtplugConsts.SystemMsgId, Error.ErrorClass.ERROR_DEVICE, $"Unknown Lovense DeviceType of {deviceInfoString} found. Please report to B******g Developers by filing an issue at https://github.com/metafetish/b******g/")); } var deviceTypeLetter = deviceInfo[0][0]; if (deviceTypeLetter == 'C') { deviceTypeLetter = 'A'; } int.TryParse(deviceInfo[1], out var deviceVersion); BpLogger.Trace($"Lovense DeviceType Return: {deviceTypeLetter}"); if (!Enum.IsDefined(typeof(LovenseDeviceType), (uint)deviceTypeLetter)) { // If we don't know what device this is, just assume it has a single vibrator, // call it unknown, log something. return(BpLogger.LogErrorMsg(ButtplugConsts.SystemMsgId, Error.ErrorClass.ERROR_DEVICE, $"Unknown Lovense Device of Type {deviceTypeLetter} found. Please report to B******g Developers by filing an issue at https://github.com/metafetish/b******g/")); } Name = $"Lovense {Enum.GetName(typeof(LovenseDeviceType), (uint)deviceTypeLetter)} v{deviceVersion}"; _deviceType = (LovenseDeviceType)deviceTypeLetter; } else { // If we for some reason don't get a device info query back, use fallback method. // // TODO Remove this branch at some point? Not sure we'll need it now since device queries seem stable. BpLogger.Warn($"Error retreiving device info from Lovense {Name}, using fallback method"); // Some of the older devices seem to have issues with info lookups? Not sure why, so // for now use fallback method. switch (Interface.Name.Substring(0, 6)) { case "LVS-B0": _deviceType = LovenseDeviceType.Max; break; case "LVS-A0": case "LVS-C0": _deviceType = LovenseDeviceType.Nora; break; case "LVS-L0": _deviceType = LovenseDeviceType.Ambi; break; default: _deviceType = LovenseDeviceType.Unknown; break; } Name = $"Lovense {Enum.GetName(typeof(LovenseDeviceType), (uint)_deviceType)} v{Interface.Name.Substring(Interface.Name.Length - 2)}"; } if (_deviceType == LovenseDeviceType.Unknown) { BpLogger.Error("Lovense device type unknown, treating as single vibrator device. Please contact developers for more info."); } switch (_deviceType) { case LovenseDeviceType.Edge: // Edge has 2 vibrators _vibratorCount++; MsgFuncs.Remove(typeof(VibrateCmd)); MsgFuncs.Add(typeof(VibrateCmd), new ButtplugDeviceWrapper(HandleVibrateCmd, new MessageAttributes() { FeatureCount = _vibratorCount })); break; case LovenseDeviceType.Nora: // Nora has a rotator MsgFuncs.Add(typeof(RotateCmd), new ButtplugDeviceWrapper(HandleRotateCmd, new MessageAttributes() { FeatureCount = 1 })); break; } return(new Ok(ButtplugConsts.SystemMsgId)); }
public override async Task <ButtplugMessage> InitializeAsync(CancellationToken aToken) { BpLogger.Trace($"Initializing {Name}"); // Subscribing to read updates await Interface.SubscribeToUpdatesAsync().ConfigureAwait(false); Interface.BluetoothNotifyReceived += NotifyReceived; // Retreiving device type info for identification. var writeMsg = await Interface.WriteValueAsync(ButtplugConsts.SystemMsgId, Encoding.ASCII.GetBytes("DeviceType;"), true, aToken).ConfigureAwait(false); if (writeMsg is Error) { BpLogger.Error($"Error requesting device info from Lovense {Name}"); return(writeMsg); } var deviceInfoString = string.Empty; try { var(msg, result) = await Interface.ReadValueAsync(ButtplugConsts.SystemMsgId, aToken).ConfigureAwait(false); if (msg is Ok && result.Length > 0) { deviceInfoString = Encoding.ASCII.GetString(result); } } catch (ButtplugDeviceException) { // The device info notification isn't available immediately. // TODO Turn this into a task semaphore with cancellation/timeout, let system handle check timing. int timeout = 1000; while (timeout > 0) { if (_lastNotifyReceived != string.Empty) { deviceInfoString = _lastNotifyReceived; break; } timeout -= 5; await Task.Delay(5).ConfigureAwait(false); } } BpLogger.Debug($"Received device query return for {Interface.Name}"); // Expected Format X:YY:ZZZZZZZZZZZZ X is device type leter YY is firmware version Z is // bluetooth address var deviceInfo = deviceInfoString.Split(':'); // If we don't get back the amount of tokens we expect, identify as unknown, log, bail. if (deviceInfo.Length != 3 || deviceInfo[0].Length != 1) { throw new ButtplugDeviceException(BpLogger, $"Unknown Lovense DeviceType of {deviceInfoString} found. Please report to B******g Developers by filing an issue at https://github.com/buttplugio/b******g/"); } var deviceTypeLetter = deviceInfo[0][0]; if (deviceTypeLetter == 'C') { deviceTypeLetter = 'A'; } int.TryParse(deviceInfo[1], out var deviceVersion); BpLogger.Trace($"Lovense DeviceType Return: {deviceTypeLetter}"); if (!Enum.IsDefined(typeof(LovenseDeviceType), (uint)deviceTypeLetter)) { // If we don't know what device this is, just assume it has a single vibrator, call // it unknown, log something. AddCommonMessages(); throw new ButtplugDeviceException(BpLogger, $"Unknown Lovense Device of Type {deviceTypeLetter} found. Please report to B******g Developers by filing an issue at https://github.com/buttplugio/b******g/"); } Name = $"Lovense {Enum.GetName(typeof(LovenseDeviceType), (uint)deviceTypeLetter)} v{deviceVersion}"; _deviceType = (LovenseDeviceType)deviceTypeLetter; if (_deviceType == LovenseDeviceType.Unknown) { BpLogger.Error("Lovense device type unknown, treating as single vibrator device. Please contact developers for more info."); } switch (_deviceType) { case LovenseDeviceType.Edge: // Edge has 2 vibrators _vibratorCount++; break; case LovenseDeviceType.Nora: // Nora has a rotator AddMessageHandler <RotateCmd>(HandleRotateCmd, new MessageAttributes { FeatureCount = 1 }); break; } // Common messages. AddCommonMessages(); return(new Ok(ButtplugConsts.SystemMsgId)); }