plugin-manager,plugin: run pre-probing filters early

For each port, we will construct the list of plugins to test with. In that list
we will include those plugins which are likely to handle a given port, so we
will skip all those which aren't.

To see if a plugin is likely or not, we will run the pre-probing filters before
adding them to the list, with the new `mm_plugin_discard_port_early()'. This
method will return one of these hints:

 * UNSUPPORTED: The plugin will not be able to handle this port.
 * MAYBE: The plugin may handle this port.
 * LIKELY: The plugin may (very likely) handle this port.
 * SUPPORTED: If any plugin should support the port, this is it.

Plugins reported to be 'likely' supporting the port will be probed before the
ones reported just as 'maybe'.

If a plugin reports 'supported' only that one and the fallback generic ones will
be tried.
This commit is contained in:
Aleksander Morgado
2012-10-26 13:41:27 +02:00
parent e5b4b4d0e5
commit 0ca6ae1b4b
3 changed files with 152 additions and 64 deletions

View File

@@ -43,31 +43,48 @@ G_DEFINE_TYPE (MMPlugin, mm_plugin, G_TYPE_OBJECT)
/* Virtual port corresponding to the embeded modem */
static gchar *virtual_port[] = {"smd0", NULL};
#define HAS_POST_PROBING_FILTERS(self) \
(self->priv->vendor_strings || \
self->priv->product_strings || \
self->priv->forbidden_product_strings || \
self->priv->allowed_icera || \
self->priv->forbidden_icera || \
self->priv->custom_init)
struct _MMPluginPrivate {
gchar *name;
GHashTable *tasks;
/* Plugin-specific setups */
/* Pre-probing filters */
gchar **subsystems;
gchar **drivers;
gchar **forbidden_drivers;
guint16 *vendor_ids;
mm_uint16_pair *product_ids;
mm_uint16_pair *forbidden_product_ids;
gchar **udev_tags;
/* Post probing filters */
gchar **vendor_strings;
mm_str_pair *product_strings;
mm_str_pair *forbidden_product_strings;
gchar **udev_tags;
gboolean allowed_icera;
gboolean forbidden_icera;
/* Probing setup */
gboolean at;
gboolean single_at;
gboolean qcdm;
gboolean icera_probe;
gboolean allowed_icera;
gboolean forbidden_icera;
MMPortProbeAtCommand *custom_at_probe;
MMAsyncMethod *custom_init;
guint64 send_delay;
gboolean remove_echo;
/* Probing setup and/or post-probing filter.
* Plugins may use this method to decide whether they support a given
* port or not, so should also be considered kind of post-probing filter. */
MMAsyncMethod *custom_init;
};
enum {
@@ -106,30 +123,6 @@ mm_plugin_get_name (MMPlugin *self)
/*****************************************************************************/
gint
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 || \
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:
* - First, modems that will check vendor ID from udev.
* - Then, modems that report to be sorted last (those which will check
* vendor ID also from the probed ones..
*/
if (SORT_LAST (plugin_a) && !SORT_LAST (plugin_b))
return 1;
if (!SORT_LAST (plugin_a) && SORT_LAST (plugin_b))
return -1;
return 0;
}
/*****************************************************************************/
static gboolean
device_file_exists (const char *name)
{
@@ -747,6 +740,37 @@ out:
/*****************************************************************************/
MMPluginSupportsHint
mm_plugin_discard_port_early (MMPlugin *self,
MMDevice *device,
GUdevDevice *port)
{
gboolean need_vendor_probing = FALSE;
gboolean need_product_probing = FALSE;
/* If fully filtered by pre-probing filters, port unsupported */
if (apply_pre_probing_filters (self,
device,
port,
&need_vendor_probing,
&need_product_probing))
return MM_PLUGIN_SUPPORTS_HINT_UNSUPPORTED;
/* If there are no post-probing filters, this plugin is the only one (except
* for the generic one) which will grab the port */
if (!HAS_POST_PROBING_FILTERS (self))
return MM_PLUGIN_SUPPORTS_HINT_SUPPORTED;
/* If no vendor/product probing needed, plugin is likely supported */
if (!need_vendor_probing && !need_product_probing)
return MM_PLUGIN_SUPPORTS_HINT_LIKELY;
/* If vendor/product probing is needed, plugin may be supported */
return MM_PLUGIN_SUPPORTS_HINT_MAYBE;
}
/*****************************************************************************/
MMBaseModem *
mm_plugin_create_modem (MMPlugin *self,
MMDevice *device,