public bool Matches(IProtocolConfiguration aConfig)
        {
            if (!(aConfig is BluetoothLEProtocolConfiguration btleConfig))
            {
                return(false);
            }

            // Right now we only support asterisk as a final character, and treat this as a "starts
            // with" check.
            foreach (var name in Names)
            {
                if (btleConfig.Names.Contains(name))
                {
                    return(true);
                }

                if (!name.EndsWith("*"))
                {
                    continue;
                }

                var tempName = name.Substring(0, name.Length - 1);
                foreach (var otherName in btleConfig.Names)
                {
                    if (!string.IsNullOrEmpty(otherName) && otherName.StartsWith(tempName))
                    {
                        return(true);
                    }
                }
            }

            // TODO Put in advertised service checking, but that hasn't really been needed so far.
            return(false);
        }
        public void Merge(IProtocolConfiguration aConfig)
        {
            if (!(aConfig is BluetoothLEProtocolConfiguration bleConfig))
            {
                throw new ArgumentException();
            }

            if (bleConfig.Names != null)
            {
                var overlap = bleConfig.Names.Intersect(Names);
                if (overlap.Any())
                {
                    throw new ButtplugDeviceException($"User and Device configs have repeated BLE names: {overlap}");
                }

                Names = Names.Union(bleConfig.Names).ToList();
            }

            if (bleConfig.Services != null)
            {
                foreach (var service in bleConfig.Services)
                {
                    if (Services.ContainsKey(service.Key))
                    {
                        throw new ButtplugDeviceException($"User and Device configs have repeated BLE services: {service.Key}");
                    }

                    Services.Add(service.Key, service.Value);
                }
            }
        }
        public ButtplugDeviceFactory Find(IProtocolConfiguration aConfig)
        {
            if (_whiteList.Any())
            {
                var found = false;
                foreach (var config in _whiteList)
                {
                    if (!aConfig.Matches(config))
                    {
                        continue;
                    }

                    found = true;
                    break;
                }

                // If we found a whitelisted device, continue on to figure out its type.
                if (!found)
                {
                    return(null);
                }
            }

            if (_blackList.Any())
            {
                foreach (var config in _blackList)
                {
                    if (aConfig.Matches(config))
                    {
                        return(null);
                    }
                }
            }

            foreach (var config in _protocolConfigs)
            {
                foreach (var deviceConfig in config.Value)
                {
                    if (!deviceConfig.Matches(aConfig))
                    {
                        continue;
                    }

                    if (!_protocolTypes.ContainsKey(config.Key))
                    {
                        // Todo This means we found a device we have config but no protocol for. We should log here and return null.
                        return(null);
                    }

                    // We can't create the device just yet, as we need to let the subtype manager try
                    // to connect to the device and set it up appropriately. Return a device factory
                    // to let the subtype manager do that.
                    return(new ButtplugDeviceFactory(deviceConfig, _protocolTypes[config.Key]));
                }
            }

            return(null);
        }
        public void Merge(IProtocolConfiguration aConfig)
        {
            if (!(aConfig is SerialProtocolConfiguration serialConfig))
            {
                throw new ArgumentException();
            }

            // Only allow override of ports for the moment.
            Ports = serialConfig.Ports ?? Ports;
        }
        private void LoadOrAppendConfigurationObject(string aConfigString, bool aCanAddProtocols = true)
        {
            var configObj = JObject.Parse(aConfigString);

            foreach (var jsonObj in ((JObject)configObj["protocols"]).Properties())
            {
                var protocolName = jsonObj.Name;

                if (!aCanAddProtocols && !_protocolConfigs.ContainsKey(protocolName))
                {
                    throw new ButtplugDeviceException("Cannot add protocols in user configuration files.");
                }

                // We sometimes have null protocols, like "xinput". Just skip.
                if (!jsonObj.Value.HasValues)
                {
                    continue;
                }

                foreach (var busObj in ((JObject)jsonObj.Value).Properties())
                {
                    IProtocolConfiguration config = null;
                    switch (busObj.Name)
                    {
                    case "btle":
                        config = busObj.Value.ToObject <BluetoothLEProtocolConfiguration>(_serializer);
                        break;

                    case "usb":
                        config = busObj.Value.ToObject <USBProtocolConfiguration>(_serializer);
                        break;

                    case "hid":
                        config = busObj.Value.ToObject <HIDProtocolConfiguration>(_serializer);
                        break;

                    case "serial":
                        config = busObj.Value.ToObject <SerialProtocolConfiguration>(_serializer);
                        break;

                    default:
                        // TODO Throw an error message here?
                        break;
                    }

                    if (config == null)
                    {
                        continue;
                    }

                    AddProtocolConfig(protocolName, config);
                }
            }
        }
        public void AddProtocolConfig(string aProtocolName, IProtocolConfiguration aConfiguration)
        {
            if (!_protocolConfigs.ContainsKey(aProtocolName))
            {
                _protocolConfigs.Add(aProtocolName, new List <IProtocolConfiguration>());
            }

            if (_protocolConfigs[aProtocolName].Any())
            {
                var config = _protocolConfigs[aProtocolName].Find(aX => aX.GetType() == aConfiguration.GetType());
                config?.Merge(aConfiguration);
            }

            _protocolConfigs[aProtocolName].Add(aConfiguration);
        }
 public bool Matches(IProtocolConfiguration aConfig)
 {
     // If our config and their config have the same ports, call it good.
     return(aConfig is SerialProtocolConfiguration serialConfig && serialConfig.Ports.Intersect(Ports).Any());
 }
 public void AddBlacklist(IProtocolConfiguration aConfiguration)
 {
     _blackList.Add(aConfiguration);
 }
 public void AddWhitelist(IProtocolConfiguration aConfiguration)
 {
     _whiteList.Add(aConfiguration);
 }
Example #10
0
 public void Merge(IProtocolConfiguration aConfig)
 {
     throw new NotImplementedException("No valid implementation of configuration merging for HID");
 }
Example #11
0
 public bool Matches(IProtocolConfiguration aConfig)
 {
     return(aConfig is HIDProtocolConfiguration hidConfig && hidConfig.ProductId == ProductId && hidConfig.VendorId == VendorId);
 }
 public bool Matches(IProtocolConfiguration aConfig)
 {
     return(aConfig is USBProtocolConfiguration usbConfig && usbConfig.ProductId == ProductId && usbConfig.VendorId == VendorId);
 }
 public ButtplugDeviceFactory(IProtocolConfiguration aConfig, Type aProtocolType)
 {
     Config        = aConfig;
     _protocolType = aProtocolType;
 }