plugin: new filters for forbidden product IDs/strings

Plugins may specify that specific vendor & product IDs or strings are not
supported. This is useful when plugins need to specify that they support
all devices of a given vendor except for some specific ones.
This commit is contained in:
Aleksander Morgado
2012-07-30 20:25:22 +02:00
parent 4e84cd241b
commit 84d205c9be
3 changed files with 137 additions and 52 deletions

View File

@@ -105,22 +105,29 @@
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para><emphasis>Allowed product IDs</emphasis></para> <para><emphasis>Product IDs</emphasis></para>
<para> <para>
Plugins can provide a list of udev-reported pairs of vendor and product Plugins can provide a list of udev-reported pairs of vendor and product
IDs to be used as pre-probing filters. If the vendor ID and product ID IDs to be used as pre-probing filters.
pair reported by the device via udev is found in the list provided by
the plugin, port probing will be launched as requested by the given
plugin.
</para> </para>
<para> <para>
This additional filter should be used when the plugin is If the vendor ID and product ID pair reported by the device via udev is
expected to work only with a given specific product of a given vendor. found in the list of 'allowed' pairs provided by the plugin, port probing
will be launched as requested by the given plugin. This additional filter
should be used when the plugin is expected to work only with a given
specific product of a given vendor.
</para> </para>
<para> <para>
This filter is specified by the <type>MM_PLUGIN_ALLOWED_PRODUCT_IDS</type> If the vendor ID and product ID pair reported by the device via udev is
property in the <structname>MMPlugin</structname> object provided found in the list of 'forbidden' pairs provided by the plugin, port probing
by the plugin. will not be launched by this plugin. This additional filter
should be used when the plugin supports all devices of a given vendor
except for some specific ones.
</para>
<para>
These filters are specified by the <type>MM_PLUGIN_ALLOWED_PRODUCT_IDS</type>
and <type>MM_PLUGIN_FORBIDDEN_PRODUCT_IDS</type> properties in the
<structname>MMPlugin</structname> object provided by the plugin.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@@ -280,21 +287,28 @@
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para><emphasis>Allowed product strings</emphasis></para> <para><emphasis>Product strings</emphasis></para>
<para> <para>
Plugins can provide a list of pairs of vendor and product Plugins can provide a list of pairs of vendor and product
strings to be used as post-probing filters. If the vendor and product string strings to be used as post-probing filters.
pair reported by the device via AT commands is found in the list provided by
the plugin, the plugin will report that it can handle this modem.
</para> </para>
<para> <para>
This additional filter should be used when the plugin is If the vendor and product string pair reported by the device via AT
expected to work only with a given specific product of a given vendor. commands is found in the 'allowed' list provided by the plugin, the
plugin will report that it can handle this modem. This additional filter
should be used when the plugin is expected to work only with a given
specific product of a given vendor.
</para> </para>
<para> <para>
This filter is specified by the <type>MM_PLUGIN_ALLOWED_PRODUCT_STRINGS</type> If the vendor and product string pair reported by the device via AT
property in the <structname>MMPlugin</structname> object provided commands is found in the 'forbidden list provided by the plugin, the
by the plugin. plugin will report that it cannot handle this modem. This additional filter
should be used when the plugin supports all devices of a given vendor, except for some specific ones.
</para>
<para>
These filters are specified by the <type>MM_PLUGIN_ALLOWED_PRODUCT_STRINGS</type>
and <type>MM_PLUGIN_FORBIDDEN_PRODUCT_STRINGS</type> properties in the
<structname>MMPlugin</structname> object provided by the plugin.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>

View File

@@ -55,8 +55,10 @@ struct _MMPluginPrivate {
gchar **forbidden_drivers; gchar **forbidden_drivers;
guint16 *vendor_ids; guint16 *vendor_ids;
mm_uint16_pair *product_ids; mm_uint16_pair *product_ids;
mm_uint16_pair *forbidden_product_ids;
gchar **vendor_strings; gchar **vendor_strings;
mm_str_pair *product_strings; mm_str_pair *product_strings;
mm_str_pair *forbidden_product_strings;
gchar **udev_tags; gchar **udev_tags;
gboolean at; gboolean at;
gboolean single_at; gboolean single_at;
@@ -77,8 +79,10 @@ enum {
PROP_FORBIDDEN_DRIVERS, PROP_FORBIDDEN_DRIVERS,
PROP_ALLOWED_VENDOR_IDS, PROP_ALLOWED_VENDOR_IDS,
PROP_ALLOWED_PRODUCT_IDS, PROP_ALLOWED_PRODUCT_IDS,
PROP_FORBIDDEN_PRODUCT_IDS,
PROP_ALLOWED_VENDOR_STRINGS, PROP_ALLOWED_VENDOR_STRINGS,
PROP_ALLOWED_PRODUCT_STRINGS, PROP_ALLOWED_PRODUCT_STRINGS,
PROP_FORBIDDEN_PRODUCT_STRINGS,
PROP_ALLOWED_UDEV_TAGS, PROP_ALLOWED_UDEV_TAGS,
PROP_ALLOWED_AT, PROP_ALLOWED_AT,
PROP_ALLOWED_SINGLE_AT, PROP_ALLOWED_SINGLE_AT,
@@ -107,7 +111,9 @@ mm_plugin_cmp (const MMPlugin *plugin_a,
const MMPlugin *plugin_b) const MMPlugin *plugin_b)
{ {
/* If we have any post-probing filter, we need to sort the plugin last */ /* If we have any post-probing filter, we need to sort the plugin last */
#define SORT_LAST(self) (self->priv->vendor_strings || self->priv->product_strings) #define SORT_LAST(self) (self->priv->vendor_strings || \
self->priv->product_strings || \
self->priv->forbidden_product_strings)
/* The order of the plugins in the list is the same order used to check /* The order of the plugins in the list is the same order used to check
* whether the plugin can manage a given modem: * whether the plugin can manage a given modem:
@@ -267,14 +273,24 @@ apply_pre_probing_filters (MMPlugin *self,
* or product strings to compare with: unsupported */ * or product strings to compare with: unsupported */
if ((vendor_filtered || product_filtered) && if ((vendor_filtered || product_filtered) &&
!self->priv->vendor_strings && !self->priv->vendor_strings &&
!self->priv->product_strings) !self->priv->product_strings &&
!self->priv->forbidden_product_strings)
return TRUE; return TRUE;
/* The plugin may specify that some product IDs are not supported. If
* that is the case, filter by forbidden vendor+product ID pair */
if (self->priv->forbidden_product_ids && product && vendor)
for (i = 0; self->priv->forbidden_product_ids[i].l; i++)
if (vendor == self->priv->forbidden_product_ids[i].l &&
product == self->priv->forbidden_product_ids[i].r)
return TRUE;
/* If we need to filter by vendor/product strings, need to probe for both. /* If we need to filter by vendor/product strings, need to probe for both.
* This covers the case where a RS232 modem is connected via a USB<->RS232 * This covers the case where a RS232 modem is connected via a USB<->RS232
* adaptor, and we get in udev the vendor ID of the adaptor */ * adaptor, and we get in udev the vendor ID of the adaptor */
if (self->priv->product_strings) { if (self->priv->product_strings ||
self->priv->forbidden_product_strings) {
*need_vendor_probing = TRUE; *need_vendor_probing = TRUE;
*need_product_probing = TRUE; *need_product_probing = TRUE;
} else if (self->priv->vendor_strings) } else if (self->priv->vendor_strings)
@@ -342,19 +358,44 @@ apply_post_probing_filters (MMPlugin *self,
} }
/* The plugin may specify that only some vendor+product string pairs are /* The plugin may specify that only some vendor+product string pairs are
* supported. If that is the case, filter by product string */ * supported or unsupported. If that is the case, filter by product
if (self->priv->product_strings) { * string */
if (self->priv->product_strings ||
self->priv->forbidden_product_strings) {
const gchar *vendor; const gchar *vendor;
const gchar *product; const gchar *product;
vendor = mm_port_probe_get_vendor (probe); vendor = mm_port_probe_get_vendor (probe);
product = mm_port_probe_get_product (probe); product = mm_port_probe_get_product (probe);
/* If we didn't get any vendor or product: filtered */ if (self->priv->product_strings) {
if (!vendor || !product) /* If we didn't get any vendor or product: filtered */
return TRUE; if (!vendor || !product)
else { return TRUE;
for (i = 0; self->priv->product_strings[i].l; i++) { else {
for (i = 0; self->priv->product_strings[i].l; i++) {
gboolean found;
gchar *casefolded_vendor;
gchar *casefolded_product;
casefolded_vendor = g_utf8_casefold (self->priv->product_strings[i].l, -1);
casefolded_product = g_utf8_casefold (self->priv->product_strings[i].r, -1);
found = (!!strstr (vendor, casefolded_vendor) &&
!!strstr (product, casefolded_product));
g_free (casefolded_vendor);
g_free (casefolded_product);
if (found)
break;
}
/* If we didn't match any product: unsupported */
if (!self->priv->product_strings[i].l)
return TRUE;
}
}
if (self->priv->forbidden_product_strings && vendor && product) {
for (i = 0; self->priv->forbidden_product_strings[i].l; i++) {
gboolean found; gboolean found;
gchar *casefolded_vendor; gchar *casefolded_vendor;
gchar *casefolded_product; gchar *casefolded_product;
@@ -366,12 +407,9 @@ apply_post_probing_filters (MMPlugin *self,
g_free (casefolded_vendor); g_free (casefolded_vendor);
g_free (casefolded_product); g_free (casefolded_product);
if (found) if (found)
break; /* If we match a forbidden product: unsupported */
return TRUE;
} }
/* If we didn't match any product: unsupported */
if (!self->priv->product_strings[i].l)
return TRUE;
} }
/* Keep on with next filters */ /* Keep on with next filters */
@@ -714,6 +752,10 @@ set_property (GObject *object,
/* Construct only */ /* Construct only */
self->priv->product_ids = g_value_dup_boxed (value); self->priv->product_ids = g_value_dup_boxed (value);
break; break;
case PROP_FORBIDDEN_PRODUCT_IDS:
/* Construct only */
self->priv->forbidden_product_ids = g_value_dup_boxed (value);
break;
case PROP_ALLOWED_VENDOR_STRINGS: case PROP_ALLOWED_VENDOR_STRINGS:
/* Construct only */ /* Construct only */
self->priv->vendor_strings = g_value_dup_boxed (value); self->priv->vendor_strings = g_value_dup_boxed (value);
@@ -722,6 +764,10 @@ set_property (GObject *object,
/* Construct only */ /* Construct only */
self->priv->product_strings = g_value_dup_boxed (value); self->priv->product_strings = g_value_dup_boxed (value);
break; break;
case PROP_FORBIDDEN_PRODUCT_STRINGS:
/* Construct only */
self->priv->forbidden_product_strings = g_value_dup_boxed (value);
break;
case PROP_ALLOWED_UDEV_TAGS: case PROP_ALLOWED_UDEV_TAGS:
/* Construct only */ /* Construct only */
self->priv->udev_tags = g_value_dup_boxed (value); self->priv->udev_tags = g_value_dup_boxed (value);
@@ -795,12 +841,18 @@ get_property (GObject *object,
case PROP_ALLOWED_PRODUCT_IDS: case PROP_ALLOWED_PRODUCT_IDS:
g_value_set_boxed (value, self->priv->product_ids); g_value_set_boxed (value, self->priv->product_ids);
break; break;
case PROP_FORBIDDEN_PRODUCT_IDS:
g_value_set_boxed (value, self->priv->forbidden_product_ids);
break;
case PROP_ALLOWED_VENDOR_STRINGS: case PROP_ALLOWED_VENDOR_STRINGS:
g_value_set_boxed (value, self->priv->vendor_strings); g_value_set_boxed (value, self->priv->vendor_strings);
break; break;
case PROP_ALLOWED_PRODUCT_STRINGS: case PROP_ALLOWED_PRODUCT_STRINGS:
g_value_set_boxed (value, self->priv->product_strings); g_value_set_boxed (value, self->priv->product_strings);
break; break;
case PROP_FORBIDDEN_PRODUCT_STRINGS:
g_value_set_boxed (value, self->priv->forbidden_product_strings);
break;
case PROP_ALLOWED_AT: case PROP_ALLOWED_AT:
g_value_set_boolean (value, self->priv->at); g_value_set_boolean (value, self->priv->at);
break; break;
@@ -912,6 +964,14 @@ mm_plugin_class_init (MMPluginClass *klass)
MM_TYPE_UINT16_PAIR_ARRAY, MM_TYPE_UINT16_PAIR_ARRAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
(object_class, PROP_FORBIDDEN_PRODUCT_IDS,
g_param_spec_boxed (MM_PLUGIN_FORBIDDEN_PRODUCT_IDS,
"Forbidden product IDs",
"List of vendor+product ID pairs this plugin cannot support, "
"should be an array of mm_uint16_pair finished with '0,0'",
MM_TYPE_UINT16_PAIR_ARRAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property g_object_class_install_property
(object_class, PROP_ALLOWED_VENDOR_STRINGS, (object_class, PROP_ALLOWED_VENDOR_STRINGS,
@@ -931,6 +991,15 @@ mm_plugin_class_init (MMPluginClass *klass)
MM_TYPE_STR_PAIR_ARRAY, MM_TYPE_STR_PAIR_ARRAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
(object_class, PROP_FORBIDDEN_PRODUCT_STRINGS,
g_param_spec_boxed (MM_PLUGIN_FORBIDDEN_PRODUCT_STRINGS,
"Forbidden product strings",
"List of vendor+product string pairs this plugin cannot support, "
"should be an array of mm_str_pair finished with 'NULL,NULL'",
MM_TYPE_STR_PAIR_ARRAY,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property g_object_class_install_property
(object_class, PROP_ALLOWED_UDEV_TAGS, (object_class, PROP_ALLOWED_UDEV_TAGS,
g_param_spec_boxed (MM_PLUGIN_ALLOWED_UDEV_TAGS, g_param_spec_boxed (MM_PLUGIN_ALLOWED_UDEV_TAGS,

View File

@@ -38,24 +38,26 @@
#define MM_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PLUGIN)) #define MM_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PLUGIN))
#define MM_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN, MMPluginClass)) #define MM_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN, MMPluginClass))
#define MM_PLUGIN_NAME "name" #define MM_PLUGIN_NAME "name"
#define MM_PLUGIN_ALLOWED_SUBSYSTEMS "allowed-subsystems" #define MM_PLUGIN_ALLOWED_SUBSYSTEMS "allowed-subsystems"
#define MM_PLUGIN_ALLOWED_DRIVERS "allowed-drivers" #define MM_PLUGIN_ALLOWED_DRIVERS "allowed-drivers"
#define MM_PLUGIN_FORBIDDEN_DRIVERS "forbidden-drivers" #define MM_PLUGIN_FORBIDDEN_DRIVERS "forbidden-drivers"
#define MM_PLUGIN_ALLOWED_VENDOR_IDS "allowed-vendor-ids" #define MM_PLUGIN_ALLOWED_VENDOR_IDS "allowed-vendor-ids"
#define MM_PLUGIN_ALLOWED_PRODUCT_IDS "allowed-product-ids" #define MM_PLUGIN_ALLOWED_PRODUCT_IDS "allowed-product-ids"
#define MM_PLUGIN_ALLOWED_VENDOR_STRINGS "allowed-vendor-strings" #define MM_PLUGIN_FORBIDDEN_PRODUCT_IDS "forbidden-product-ids"
#define MM_PLUGIN_ALLOWED_PRODUCT_STRINGS "allowed-product-strings" #define MM_PLUGIN_ALLOWED_VENDOR_STRINGS "allowed-vendor-strings"
#define MM_PLUGIN_ALLOWED_UDEV_TAGS "allowed-udev-tags" #define MM_PLUGIN_ALLOWED_PRODUCT_STRINGS "allowed-product-strings"
#define MM_PLUGIN_ALLOWED_AT "allowed-at" #define MM_PLUGIN_FORBIDDEN_PRODUCT_STRINGS "forbidden-product-strings"
#define MM_PLUGIN_ALLOWED_SINGLE_AT "allowed-single-at" #define MM_PLUGIN_ALLOWED_UDEV_TAGS "allowed-udev-tags"
#define MM_PLUGIN_ALLOWED_QCDM "allowed-qcdm" #define MM_PLUGIN_ALLOWED_AT "allowed-at"
#define MM_PLUGIN_ICERA_PROBE "icera-probe" #define MM_PLUGIN_ALLOWED_SINGLE_AT "allowed-single-at"
#define MM_PLUGIN_ALLOWED_ICERA "allowed-icera" #define MM_PLUGIN_ALLOWED_QCDM "allowed-qcdm"
#define MM_PLUGIN_FORBIDDEN_ICERA "forbidden-icera" #define MM_PLUGIN_ICERA_PROBE "icera-probe"
#define MM_PLUGIN_CUSTOM_INIT "custom-init" #define MM_PLUGIN_ALLOWED_ICERA "allowed-icera"
#define MM_PLUGIN_CUSTOM_AT_PROBE "custom-at-probe" #define MM_PLUGIN_FORBIDDEN_ICERA "forbidden-icera"
#define MM_PLUGIN_SEND_DELAY "send-delay" #define MM_PLUGIN_CUSTOM_INIT "custom-init"
#define MM_PLUGIN_CUSTOM_AT_PROBE "custom-at-probe"
#define MM_PLUGIN_SEND_DELAY "send-delay"
typedef enum { typedef enum {
MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED = 0x0, MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED = 0x0,