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>
</listitem>
<listitem>
<para><emphasis>Allowed product IDs</emphasis></para>
<para><emphasis>Product IDs</emphasis></para>
<para>
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
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.
IDs to be used as pre-probing filters.
</para>
<para>
This additional filter should be used when the plugin is
expected to work only with a given specific product of a given vendor.
If the vendor ID and product ID pair reported by the device via udev is
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>
This filter is specified by the <type>MM_PLUGIN_ALLOWED_PRODUCT_IDS</type>
property in the <structname>MMPlugin</structname> object provided
by the plugin.
If the vendor ID and product ID pair reported by the device via udev is
found in the list of 'forbidden' pairs provided by the plugin, port probing
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>
</listitem>
<listitem>
@@ -280,21 +287,28 @@
</para>
</listitem>
<listitem>
<para><emphasis>Allowed product strings</emphasis></para>
<para><emphasis>Product strings</emphasis></para>
<para>
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
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.
strings to be used as post-probing filters.
</para>
<para>
This additional filter should be used when the plugin is
expected to work only with a given specific product of a given vendor.
If the vendor and product string pair reported by the device via AT
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>
This filter is specified by the <type>MM_PLUGIN_ALLOWED_PRODUCT_STRINGS</type>
property in the <structname>MMPlugin</structname> object provided
by the plugin.
If the vendor and product string pair reported by the device via AT
commands is found in the 'forbidden list provided by the plugin, the
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>
</listitem>
<listitem>

View File

@@ -55,8 +55,10 @@ struct _MMPluginPrivate {
gchar **forbidden_drivers;
guint16 *vendor_ids;
mm_uint16_pair *product_ids;
mm_uint16_pair *forbidden_product_ids;
gchar **vendor_strings;
mm_str_pair *product_strings;
mm_str_pair *forbidden_product_strings;
gchar **udev_tags;
gboolean at;
gboolean single_at;
@@ -77,8 +79,10 @@ enum {
PROP_FORBIDDEN_DRIVERS,
PROP_ALLOWED_VENDOR_IDS,
PROP_ALLOWED_PRODUCT_IDS,
PROP_FORBIDDEN_PRODUCT_IDS,
PROP_ALLOWED_VENDOR_STRINGS,
PROP_ALLOWED_PRODUCT_STRINGS,
PROP_FORBIDDEN_PRODUCT_STRINGS,
PROP_ALLOWED_UDEV_TAGS,
PROP_ALLOWED_AT,
PROP_ALLOWED_SINGLE_AT,
@@ -107,7 +111,9 @@ mm_plugin_cmp (const MMPlugin *plugin_a,
const MMPlugin *plugin_b)
{
/* 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
* 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 */
if ((vendor_filtered || product_filtered) &&
!self->priv->vendor_strings &&
!self->priv->product_strings)
!self->priv->product_strings &&
!self->priv->forbidden_product_strings)
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.
* 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 */
if (self->priv->product_strings) {
if (self->priv->product_strings ||
self->priv->forbidden_product_strings) {
*need_vendor_probing = TRUE;
*need_product_probing = TRUE;
} 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
* supported. If that is the case, filter by product string */
if (self->priv->product_strings) {
* supported or unsupported. If that is the case, filter by product
* string */
if (self->priv->product_strings ||
self->priv->forbidden_product_strings) {
const gchar *vendor;
const gchar *product;
vendor = mm_port_probe_get_vendor (probe);
product = mm_port_probe_get_product (probe);
/* If we didn't get any vendor or product: filtered */
if (!vendor || !product)
return TRUE;
else {
for (i = 0; self->priv->product_strings[i].l; i++) {
if (self->priv->product_strings) {
/* If we didn't get any vendor or product: filtered */
if (!vendor || !product)
return TRUE;
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;
gchar *casefolded_vendor;
gchar *casefolded_product;
@@ -366,12 +407,9 @@ apply_post_probing_filters (MMPlugin *self,
g_free (casefolded_vendor);
g_free (casefolded_product);
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 */
@@ -714,6 +752,10 @@ set_property (GObject *object,
/* Construct only */
self->priv->product_ids = g_value_dup_boxed (value);
break;
case PROP_FORBIDDEN_PRODUCT_IDS:
/* Construct only */
self->priv->forbidden_product_ids = g_value_dup_boxed (value);
break;
case PROP_ALLOWED_VENDOR_STRINGS:
/* Construct only */
self->priv->vendor_strings = g_value_dup_boxed (value);
@@ -722,6 +764,10 @@ set_property (GObject *object,
/* Construct only */
self->priv->product_strings = g_value_dup_boxed (value);
break;
case PROP_FORBIDDEN_PRODUCT_STRINGS:
/* Construct only */
self->priv->forbidden_product_strings = g_value_dup_boxed (value);
break;
case PROP_ALLOWED_UDEV_TAGS:
/* Construct only */
self->priv->udev_tags = g_value_dup_boxed (value);
@@ -795,12 +841,18 @@ get_property (GObject *object,
case PROP_ALLOWED_PRODUCT_IDS:
g_value_set_boxed (value, self->priv->product_ids);
break;
case PROP_FORBIDDEN_PRODUCT_IDS:
g_value_set_boxed (value, self->priv->forbidden_product_ids);
break;
case PROP_ALLOWED_VENDOR_STRINGS:
g_value_set_boxed (value, self->priv->vendor_strings);
break;
case PROP_ALLOWED_PRODUCT_STRINGS:
g_value_set_boxed (value, self->priv->product_strings);
break;
case PROP_FORBIDDEN_PRODUCT_STRINGS:
g_value_set_boxed (value, self->priv->forbidden_product_strings);
break;
case PROP_ALLOWED_AT:
g_value_set_boolean (value, self->priv->at);
break;
@@ -912,6 +964,14 @@ mm_plugin_class_init (MMPluginClass *klass)
MM_TYPE_UINT16_PAIR_ARRAY,
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
(object_class, PROP_ALLOWED_VENDOR_STRINGS,
@@ -931,6 +991,15 @@ mm_plugin_class_init (MMPluginClass *klass)
MM_TYPE_STR_PAIR_ARRAY,
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
(object_class, PROP_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_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN, MMPluginClass))
#define MM_PLUGIN_NAME "name"
#define MM_PLUGIN_ALLOWED_SUBSYSTEMS "allowed-subsystems"
#define MM_PLUGIN_ALLOWED_DRIVERS "allowed-drivers"
#define MM_PLUGIN_FORBIDDEN_DRIVERS "forbidden-drivers"
#define MM_PLUGIN_ALLOWED_VENDOR_IDS "allowed-vendor-ids"
#define MM_PLUGIN_ALLOWED_PRODUCT_IDS "allowed-product-ids"
#define MM_PLUGIN_ALLOWED_VENDOR_STRINGS "allowed-vendor-strings"
#define MM_PLUGIN_ALLOWED_PRODUCT_STRINGS "allowed-product-strings"
#define MM_PLUGIN_ALLOWED_UDEV_TAGS "allowed-udev-tags"
#define MM_PLUGIN_ALLOWED_AT "allowed-at"
#define MM_PLUGIN_ALLOWED_SINGLE_AT "allowed-single-at"
#define MM_PLUGIN_ALLOWED_QCDM "allowed-qcdm"
#define MM_PLUGIN_ICERA_PROBE "icera-probe"
#define MM_PLUGIN_ALLOWED_ICERA "allowed-icera"
#define MM_PLUGIN_FORBIDDEN_ICERA "forbidden-icera"
#define MM_PLUGIN_CUSTOM_INIT "custom-init"
#define MM_PLUGIN_CUSTOM_AT_PROBE "custom-at-probe"
#define MM_PLUGIN_SEND_DELAY "send-delay"
#define MM_PLUGIN_NAME "name"
#define MM_PLUGIN_ALLOWED_SUBSYSTEMS "allowed-subsystems"
#define MM_PLUGIN_ALLOWED_DRIVERS "allowed-drivers"
#define MM_PLUGIN_FORBIDDEN_DRIVERS "forbidden-drivers"
#define MM_PLUGIN_ALLOWED_VENDOR_IDS "allowed-vendor-ids"
#define MM_PLUGIN_ALLOWED_PRODUCT_IDS "allowed-product-ids"
#define MM_PLUGIN_FORBIDDEN_PRODUCT_IDS "forbidden-product-ids"
#define MM_PLUGIN_ALLOWED_VENDOR_STRINGS "allowed-vendor-strings"
#define MM_PLUGIN_ALLOWED_PRODUCT_STRINGS "allowed-product-strings"
#define MM_PLUGIN_FORBIDDEN_PRODUCT_STRINGS "forbidden-product-strings"
#define MM_PLUGIN_ALLOWED_UDEV_TAGS "allowed-udev-tags"
#define MM_PLUGIN_ALLOWED_AT "allowed-at"
#define MM_PLUGIN_ALLOWED_SINGLE_AT "allowed-single-at"
#define MM_PLUGIN_ALLOWED_QCDM "allowed-qcdm"
#define MM_PLUGIN_ICERA_PROBE "icera-probe"
#define MM_PLUGIN_ALLOWED_ICERA "allowed-icera"
#define MM_PLUGIN_FORBIDDEN_ICERA "forbidden-icera"
#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 {
MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED = 0x0,