diff options
-rw-r--r-- | data/tests/meson.build | 7 | ||||
-rw-r--r-- | data/tests/org.freedesktop.ModemManager1.service.in | 2 | ||||
-rw-r--r-- | meson.build | 5 | ||||
-rw-r--r-- | meson_options.txt | 2 | ||||
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/meson.build | 26 | ||||
-rw-r--r-- | src/mm-base-manager.c | 22 | ||||
-rw-r--r-- | src/mm-base-manager.h | 2 | ||||
-rw-r--r-- | src/mm-context.c | 6 | ||||
-rw-r--r-- | src/mm-context.h | 2 | ||||
-rw-r--r-- | src/mm-plugin-manager.c | 271 | ||||
-rw-r--r-- | src/mm-plugin-manager.h | 10 | ||||
-rw-r--r-- | src/plugins/meson.build | 52 | ||||
-rw-r--r-- | src/plugins/mm-builtin-plugins.c | 273 | ||||
-rw-r--r-- | src/plugins/mm-builtin-plugins.h | 28 | ||||
-rw-r--r-- | src/plugins/mm-plugin-common.h | 25 | ||||
-rw-r--r-- | src/plugins/mm-shared-common.h | 6 |
17 files changed, 594 insertions, 147 deletions
diff --git a/data/tests/meson.build b/data/tests/meson.build index 1cc0826b..3b3ee790 100644 --- a/data/tests/meson.build +++ b/data/tests/meson.build @@ -1,9 +1,14 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2022 Aleksander Morgado <aleksander@aleksander.es> +test_plugin_dir = '' +if not enable_builtin_plugins + test_plugin_dir = '--test-plugin-dir="' + build_root + '/src/plugins"' +endif + test_conf = { 'abs_top_builddir': build_root, - 'PLUGIN_BUILD_SUBDIR': 'src/plugins/', + 'test_plugin_dir': test_plugin_dir, } configure_file( diff --git a/data/tests/org.freedesktop.ModemManager1.service.in b/data/tests/org.freedesktop.ModemManager1.service.in index d8a751b4..15fe3c7b 100644 --- a/data/tests/org.freedesktop.ModemManager1.service.in +++ b/data/tests/org.freedesktop.ModemManager1.service.in @@ -2,4 +2,4 @@ [D-BUS Service] Name=org.freedesktop.ModemManager1 -Exec=@abs_top_builddir@/src/ModemManager --test-session --no-auto-scan --test-enable --test-plugin-dir="@abs_top_builddir@/@PLUGIN_BUILD_SUBDIR@" --debug +Exec=@abs_top_builddir@/src/ModemManager --test-session --no-auto-scan --test-enable @test_plugin_dir@ --debug diff --git a/meson.build b/meson.build index cc2191fe..e3550a4d 100644 --- a/meson.build +++ b/meson.build @@ -242,6 +242,10 @@ config_h.set('WITH_POLKIT', enable_polkit) enable_at_command_via_dbus = get_option('at_command_via_dbus') config_h.set('WITH_AT_COMMAND_VIA_DBUS', enable_at_command_via_dbus) +# Builtin plugin support (disabled by default) +enable_builtin_plugins = get_option('builtin_plugins') +config_h.set('WITH_BUILTIN_PLUGINS', enable_builtin_plugins) + # MBIM support (enabled by default) enable_mbim = get_option('mbim') if enable_mbim @@ -444,6 +448,7 @@ summary({ 'powerd suspend/resume': enable_powerd_suspend_resume, 'systemd journal': enable_systemd_journal, 'at command via dbus': enable_at_command_via_dbus, + 'builtin plugins': enable_builtin_plugins, }, section: 'Features') summary(plugins_shared, section: 'Shared utils') diff --git a/meson_options.txt b/meson_options.txt index da105e1d..c560a234 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -17,6 +17,8 @@ option('polkit', type: 'combo', choices: ['strict', 'permissive', 'no'], value: option('at_command_via_dbus', type: 'boolean', value: false, description: 'enable at commands vida d-bus') +option('builtin_plugins', type: 'boolean', value: false, description: 'integrate all built plugins within the daemon binary') + option('mbim', type: 'boolean', value: true, description: 'enable MBIM support') option('qmi', type: 'boolean', value: true, description: 'enable QMI support') option('qrtr', type: 'boolean', value: true, description: 'enable QRTR support') @@ -93,7 +93,9 @@ bus_acquired_cb (GDBusConnection *connection, /* Create Manager object */ g_assert (!manager); manager = mm_base_manager_new (connection, +#if !defined WITH_BUILTIN_PLUGINS mm_context_get_test_plugin_dir (), +#endif !mm_context_get_no_auto_scan (), mm_context_get_filter_policy (), mm_context_get_initial_kernel_events (), diff --git a/src/meson.build b/src/meson.build index 3a7228b8..3b6f7a71 100644 --- a/src/meson.build +++ b/src/meson.build @@ -4,6 +4,7 @@ # helpers library src_inc = include_directories('.') kerneldevice_inc = include_directories('kerneldevice') +plugins_inc = include_directories('plugins') headers = files( 'mm-modem-helpers.h', @@ -177,6 +178,9 @@ libport_dep = declare_dependency( link_with: libport, ) +# Additional vendor plugins +subdir('plugins') + # ModemManager daemon headers = files( 'mm-base-bearer.h', @@ -229,15 +233,14 @@ sources = files( enums_types = 'mm-daemon-enums-types' -daemon_enums_sources = [] -daemon_enums_sources += gnome.mkenums( +sources += gnome.mkenums( enums_types + '.c', sources: headers, c_template: build_aux_dir / enums_types + '.c.template', fhead: '#include "mm-daemon-enums-types.h"', ) -daemon_enums_sources += gnome.mkenums( +sources += gnome.mkenums( enums_types + '.h', sources: headers, h_template: build_aux_dir / enums_types + '.h.template', @@ -309,20 +312,13 @@ if enable_mbim ) endif -# Daemon related variables before processing plugins -daemon_sources = sources + daemon_enums_sources -daemon_deps = deps -daemon_c_args = c_args - -# Additional vendor plugins -subdir('plugins') - executable( 'ModemManager', - sources: daemon_sources, - include_directories: top_inc, - dependencies: daemon_deps, - c_args: daemon_c_args, + sources: [sources, builtin_sources], + include_directories: [ top_inc, plugins_inc ], + dependencies: deps, + c_args: c_args, + link_whole: builtin_plugins, install: true, install_dir: mm_sbindir, ) diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c index 6cdc4ae3..63ca6899 100644 --- a/src/mm-base-manager.c +++ b/src/mm-base-manager.c @@ -68,7 +68,9 @@ enum { PROP_CONNECTION, PROP_AUTO_SCAN, PROP_FILTER_POLICY, +#if !defined WITH_BUILTIN_PLUGINS PROP_PLUGIN_DIR, +#endif PROP_INITIAL_KERNEL_EVENTS, #if defined WITH_TESTS PROP_ENABLE_TEST, @@ -83,8 +85,10 @@ struct _MMBaseManagerPrivate { gboolean auto_scan; /* Filter policy (mask of enabled rules) */ MMFilterRule filter_policy; +#if !defined WITH_BUILTIN_PLUGINS /* Path to look for plugins */ gchar *plugin_dir; +#endif /* Path to the list of initial kernel events */ gchar *initial_kernel_events; /* The authorization provider */ @@ -1380,7 +1384,9 @@ log_object_build_id (MMLogObject *_self) MMBaseManager * mm_base_manager_new (GDBusConnection *connection, +#if !defined WITH_BUILTIN_PLUGINS const gchar *plugin_dir, +#endif gboolean auto_scan, MMFilterRule filter_policy, const gchar *initial_kernel_events, @@ -1395,7 +1401,9 @@ mm_base_manager_new (GDBusConnection *connection, NULL, /* cancellable */ error, MM_BASE_MANAGER_CONNECTION, connection, +#if !defined WITH_BUILTIN_PLUGINS MM_BASE_MANAGER_PLUGIN_DIR, plugin_dir, +#endif MM_BASE_MANAGER_AUTO_SCAN, auto_scan, MM_BASE_MANAGER_FILTER_POLICY, filter_policy, MM_BASE_MANAGER_INITIAL_KERNEL_EVENTS, initial_kernel_events, @@ -1445,10 +1453,12 @@ set_property (GObject *object, case PROP_FILTER_POLICY: self->priv->filter_policy = g_value_get_flags (value); break; +#if !defined WITH_BUILTIN_PLUGINS case PROP_PLUGIN_DIR: g_free (self->priv->plugin_dir); self->priv->plugin_dir = g_value_dup_string (value); break; +#endif case PROP_INITIAL_KERNEL_EVENTS: g_free (self->priv->initial_kernel_events); self->priv->initial_kernel_events = g_value_dup_string (value); @@ -1482,9 +1492,11 @@ get_property (GObject *object, case PROP_FILTER_POLICY: g_value_set_flags (value, self->priv->filter_policy); break; +#if !defined WITH_BUILTIN_PLUGINS case PROP_PLUGIN_DIR: g_value_set_string (value, self->priv->plugin_dir); break; +#endif case PROP_INITIAL_KERNEL_EVENTS: g_value_set_string (value, self->priv->initial_kernel_events); break; @@ -1548,7 +1560,11 @@ initable_init (GInitable *initable, return FALSE; /* Create plugin manager */ - self->priv->plugin_manager = mm_plugin_manager_new (self->priv->plugin_dir, self->priv->filter, error); + self->priv->plugin_manager = mm_plugin_manager_new (self->priv->filter, +#if !defined WITH_BUILTIN_PLUGINS + self->priv->plugin_dir, +#endif + error); if (!self->priv->plugin_manager) return FALSE; @@ -1613,7 +1629,9 @@ finalize (GObject *object) MMBaseManager *self = MM_BASE_MANAGER (object); g_free (self->priv->initial_kernel_events); +#if !defined WITH_BUILTIN_PLUGINS g_free (self->priv->plugin_dir); +#endif g_hash_table_destroy (self->priv->inhibited_devices); g_hash_table_destroy (self->priv->devices); @@ -1704,6 +1722,7 @@ mm_base_manager_class_init (MMBaseManagerClass *manager_class) MM_FILTER_RULE_NONE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +#if !defined WITH_BUILTIN_PLUGINS g_object_class_install_property (object_class, PROP_PLUGIN_DIR, g_param_spec_string (MM_BASE_MANAGER_PLUGIN_DIR, @@ -1711,6 +1730,7 @@ mm_base_manager_class_init (MMBaseManagerClass *manager_class) "Where to look for plugins", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +#endif g_object_class_install_property (object_class, PROP_INITIAL_KERNEL_EVENTS, diff --git a/src/mm-base-manager.h b/src/mm-base-manager.h index 881555c6..47f9d333 100644 --- a/src/mm-base-manager.h +++ b/src/mm-base-manager.h @@ -57,7 +57,9 @@ GType mm_base_manager_get_type (void); G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMBaseManager, g_object_unref) MMBaseManager *mm_base_manager_new (GDBusConnection *bus, +#if !defined WITH_BUILTIN_PLUGINS const gchar *plugin_dir, +#endif gboolean auto_scan, MMFilterRule filter_policy, const gchar *initial_kernel_events, diff --git a/src/mm-context.c b/src/mm-context.c index 883fc2a1..9deeb312 100644 --- a/src/mm-context.c +++ b/src/mm-context.c @@ -229,7 +229,9 @@ static gboolean test_session; #if defined WITH_TESTS static gboolean test_enable; #endif +#if !defined WITH_BUILTIN_PLUGINS static gchar *test_plugin_dir; +#endif #if defined WITH_UDEV static gboolean test_no_udev; #endif @@ -258,11 +260,13 @@ static const GOptionEntry test_entries[] = { NULL }, #endif +#if !defined WITH_BUILTIN_PLUGINS { "test-plugin-dir", 0, 0, G_OPTION_ARG_FILENAME, &test_plugin_dir, "Path to look for plugins", "[PATH]" }, +#endif #if defined WITH_UDEV { "test-no-udev", 0, 0, G_OPTION_ARG_NONE, &test_no_udev, @@ -332,11 +336,13 @@ mm_context_get_test_enable (void) } #endif +#if !defined WITH_BUILTIN_PLUGINS const gchar * mm_context_get_test_plugin_dir (void) { return test_plugin_dir ? test_plugin_dir : PLUGINDIR; } +#endif #if defined WITH_UDEV gboolean diff --git a/src/mm-context.h b/src/mm-context.h index fcca1f65..7ca2b7f4 100644 --- a/src/mm-context.h +++ b/src/mm-context.h @@ -48,7 +48,9 @@ gboolean mm_context_get_test_session (void); #if defined WITH_TESTS gboolean mm_context_get_test_enable (void); #endif +#if !defined WITH_BUILTIN_PLUGINS const gchar *mm_context_get_test_plugin_dir (void); +#endif #if defined WITH_UDEV gboolean mm_context_get_test_no_udev (void); #endif diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c index 2c22ab23..72127296 100644 --- a/src/mm-plugin-manager.c +++ b/src/mm-plugin-manager.c @@ -33,8 +33,12 @@ #include "mm-utils.h" #include "mm-log-object.h" -#define SHARED_PREFIX "libmm-shared" -#define PLUGIN_PREFIX "libmm-plugin" +#if defined WITH_BUILTIN_PLUGINS +# include "mm-builtin-plugins.h" +#else +# define SHARED_PREFIX "libmm-shared" +# define PLUGIN_PREFIX "libmm-plugin" +#endif static void initable_iface_init (GInitableIface *iface); static void log_object_iface_init (MMLogObjectInterface *iface); @@ -45,14 +49,19 @@ G_DEFINE_TYPE_EXTENDED (MMPluginManager, mm_plugin_manager, G_TYPE_OBJECT, 0, enum { PROP_0, +#if !defined WITH_BUILTIN_PLUGINS PROP_PLUGIN_DIR, +#endif PROP_FILTER, LAST_PROP }; struct _MMPluginManagerPrivate { +#if !defined WITH_BUILTIN_PLUGINS /* Path to look for plugins */ gchar *plugin_dir; +#endif + /* Device filter */ MMFilter *filter; @@ -1681,9 +1690,90 @@ register_plugin_allowlist_subsystem_vendor_ids (MMPluginManager *self, mm_filter_register_plugin_allowlist_subsystem_vendor_id (self->priv->filter, subsystem_vendor_ids[i].l, subsystem_vendor_ids[i].r); } +static gboolean +track_plugin (MMPluginManager *self, + MMPlugin *plugin, + GPtrArray **subsystems, + GError **error) +{ + const gchar **plugin_subsystems; + guint i; + + /* Ignore plugins that don't specify subsystems */ + plugin_subsystems = mm_plugin_get_allowed_subsystems (plugin); + if (!plugin_subsystems) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Allowed subsystems not specified"); + return FALSE; + } + + /* Process generic plugin */ + if (mm_plugin_is_generic (plugin)) { + if (self->priv->generic) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Another generic plugin already registered"); + return FALSE; + } + self->priv->generic = g_object_ref (plugin); + } else + self->priv->plugins = g_list_append (self->priv->plugins, g_object_ref (plugin)); + + /* Track required subsystems, avoiding duplicates in the list */ + for (i = 0; plugin_subsystems[i]; i++) { + if (!g_ptr_array_find_with_equal_func (*subsystems, plugin_subsystems[i], g_str_equal, NULL)) + g_ptr_array_add (*subsystems, g_strdup (plugin_subsystems[i])); + } + + /* Register plugin allowlist rules in filter, if any */ + register_plugin_allowlist_tags (self, plugin); + register_plugin_allowlist_vendor_ids (self, plugin); + register_plugin_allowlist_product_ids (self, plugin); + register_plugin_allowlist_subsystem_vendor_ids (self, plugin); + + return TRUE; +} + +static gboolean +validate_tracked_plugins (MMPluginManager *self, + GPtrArray *subsystems_take, + GError **error) +{ + g_autofree gchar *subsystems_str = NULL; + + /* Check the generic plugin once all looped */ + if (!self->priv->generic) + mm_obj_dbg (self, "generic plugin not loaded"); + + /* Treat as error if we don't find any plugin */ + if (!self->priv->plugins && !self->priv->generic) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NO_PLUGINS, "no plugins found"); + return FALSE; + } + + /* Validate required subsystems */ + if (!subsystems_take->len) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NO_PLUGINS, + "empty list of subsystems required by plugins"); + return FALSE; + } + + /* Add trailing NULL and store as GStrv */ + g_ptr_array_add (subsystems_take, NULL); + self->priv->subsystems = (gchar **) g_ptr_array_free (subsystems_take, FALSE); + subsystems_str = g_strjoinv (", ", self->priv->subsystems); + + mm_obj_dbg (self, "successfully loaded %u plugins registering %u subsystems: %s", + g_list_length (self->priv->plugins) + !!self->priv->generic, + g_strv_length (self->priv->subsystems), subsystems_str); + + return TRUE; +} + +#if !defined WITH_BUILTIN_PLUGINS + static MMPlugin * -load_plugin (MMPluginManager *self, - const gchar *path) +load_external_plugin (MMPluginManager *self, + const gchar *path) { MMPlugin *plugin = NULL; GModule *module; @@ -1729,10 +1819,9 @@ load_plugin (MMPluginManager *self, } plugin = (*plugin_create_func) (); - if (plugin) { + if (plugin) mm_obj_dbg (self, "loaded plugin '%s' from '%s'", mm_plugin_get_name (plugin), path_display); - g_object_weak_ref (G_OBJECT (plugin), (GWeakNotify) g_module_close, module); - } else + else mm_obj_warn (self, "could not load plugin '%s': initialization failed", path_display); out: @@ -1745,8 +1834,8 @@ out: } static void -load_shared (MMPluginManager *self, - const gchar *path) +load_external_shared (MMPluginManager *self, + const gchar *path) { GModule *module; gchar *path_display; @@ -1802,8 +1891,8 @@ out: } static gboolean -load_plugins (MMPluginManager *self, - GError **error) +load_external_plugins (MMPluginManager *self, + GError **error) { GDir *dir = NULL; const gchar *fname; @@ -1811,8 +1900,8 @@ load_plugins (MMPluginManager *self, GList *plugin_paths = NULL; GList *l; GPtrArray *subsystems = NULL; - g_autofree gchar *subsystems_str = NULL; g_autofree gchar *plugindir_display = NULL; + gboolean valid_plugins = FALSE; if (!g_module_supported ()) { g_set_error (error, @@ -1828,11 +1917,8 @@ load_plugins (MMPluginManager *self, mm_obj_dbg (self, "looking for plugins in '%s'", plugindir_display); dir = g_dir_open (self->priv->plugin_dir, 0, NULL); if (!dir) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_NO_PLUGINS, - "plugin directory '%s' not found", - plugindir_display); + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NO_PLUGINS, + "plugin directory '%s' not found", plugindir_display); goto out; } @@ -1847,81 +1933,23 @@ load_plugins (MMPluginManager *self, /* Load all shared utils */ for (l = shared_paths; l; l = g_list_next (l)) - load_shared (self, (const gchar *)(l->data)); + load_external_shared (self, (const gchar *)(l->data)); /* Load all plugins */ subsystems = g_ptr_array_new (); for (l = plugin_paths; l; l = g_list_next (l)) { - MMPlugin *plugin; - const gchar **plugin_subsystems; - guint i; + g_autoptr(MMPlugin) plugin = NULL; + g_autoptr(GError) inner_error = NULL; - plugin = load_plugin (self, (const gchar *)(l->data)); + plugin = load_external_plugin (self, (const gchar *)(l->data)); if (!plugin) continue; - /* Ignore plugins that don't specify subsystems */ - plugin_subsystems = mm_plugin_get_allowed_subsystems (plugin); - if (!plugin_subsystems) { - mm_obj_warn (self, "plugin '%s' doesn't specify allowed subsystems: ignored", - mm_plugin_get_name (plugin)); - continue; - } - - /* Process generic plugin */ - if (mm_plugin_is_generic (plugin)) { - if (self->priv->generic) { - mm_obj_warn (self, "plugin '%s' is generic and another one is already registered: ignored", - mm_plugin_get_name (plugin)); - continue; - } - self->priv->generic = plugin; - } else - self->priv->plugins = g_list_append (self->priv->plugins, plugin); - - /* Track required subsystems, avoiding duplicates in the list */ - for (i = 0; plugin_subsystems[i]; i++) { - if (!g_ptr_array_find_with_equal_func (subsystems, plugin_subsystems[i], g_str_equal, NULL)) - g_ptr_array_add (subsystems, g_strdup (plugin_subsystems[i])); - } - - /* Register plugin allowlist rules in filter, if any */ - register_plugin_allowlist_tags (self, plugin); - register_plugin_allowlist_vendor_ids (self, plugin); - register_plugin_allowlist_product_ids (self, plugin); - register_plugin_allowlist_subsystem_vendor_ids (self, plugin); + if (!track_plugin (self, plugin, &subsystems, &inner_error)) + mm_obj_warn (self, "ignored plugin '%s': %s", mm_plugin_get_name (plugin), inner_error->message); } - /* Check the generic plugin once all looped */ - if (!self->priv->generic) - mm_obj_dbg (self, "generic plugin not loaded"); - - /* Treat as error if we don't find any plugin */ - if (!self->priv->plugins && !self->priv->generic) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_NO_PLUGINS, - "no plugins found in plugin directory '%s'", - plugindir_display); - goto out; - } - - /* Validate required subsystems */ - if (!subsystems->len) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_NO_PLUGINS, - "empty list of subsystems required by plugins"); - goto out; - } - /* Add trailing NULL and store as GStrv */ - g_ptr_array_add (subsystems, NULL); - self->priv->subsystems = (gchar **) g_ptr_array_free (subsystems, FALSE); - subsystems_str = g_strjoinv (", ", self->priv->subsystems); - - mm_obj_dbg (self, "successfully loaded %u plugins registering %u subsystems: %s", - g_list_length (self->priv->plugins) + !!self->priv->generic, - g_strv_length (self->priv->subsystems), subsystems_str); + valid_plugins = validate_tracked_plugins (self, subsystems, error); out: g_list_free_full (shared_paths, g_free); @@ -1929,10 +1957,38 @@ out: if (dir) g_dir_close (dir); - /* Return TRUE if at least one plugin found */ - return (self->priv->plugins || self->priv->generic); + return valid_plugins; +} + +#else + +static gboolean +load_builtin_plugins (MMPluginManager *self, + GError **error) +{ + GList *builtin_plugins; + GList *l; + GPtrArray *subsystems = NULL; + + subsystems = g_ptr_array_new (); + + builtin_plugins = mm_builtin_plugins_load (); + for (l = builtin_plugins; l; l = g_list_next (l)) { + gboolean tracked; + MMPlugin *plugin; + + plugin = MM_PLUGIN (l->data); + mm_obj_dbg (self, "loaded builtin plugin '%s'", mm_plugin_get_name (plugin)); + tracked = track_plugin (self, plugin, &subsystems, NULL); + g_assert (tracked); + } + g_list_free_full (builtin_plugins, (GDestroyNotify)g_object_unref); + + return validate_tracked_plugins (self, subsystems, error); } +#endif /* !WITH_BUILTIN_PLUGINS */ + /*****************************************************************************/ static gchar * @@ -1944,15 +2000,19 @@ log_object_build_id (MMLogObject *_self) /*****************************************************************************/ MMPluginManager * -mm_plugin_manager_new (const gchar *plugin_dir, - MMFilter *filter, +mm_plugin_manager_new (MMFilter *filter, +#if !defined WITH_BUILTIN_PLUGINS + const gchar *plugin_dir, +#endif GError **error) { return g_initable_new (MM_TYPE_PLUGIN_MANAGER, NULL, error, + MM_PLUGIN_MANAGER_FILTER, filter, +#if !defined WITH_BUILTIN_PLUGINS MM_PLUGIN_MANAGER_PLUGIN_DIR, plugin_dir, - MM_PLUGIN_MANAGER_FILTER, filter, +#endif NULL); } @@ -1966,18 +2026,20 @@ mm_plugin_manager_init (MMPluginManager *self) } static void -set_property (GObject *object, - guint prop_id, +set_property (GObject *object, + guint prop_id, const GValue *value, - GParamSpec *pspec) + GParamSpec *pspec) { MMPluginManagerPrivate *priv = MM_PLUGIN_MANAGER (object)->priv; switch (prop_id) { +#if !defined WITH_BUILTIN_PLUGINS case PROP_PLUGIN_DIR: g_free (priv->plugin_dir); priv->plugin_dir = g_value_dup_string (value); break; +#endif case PROP_FILTER: priv->filter = g_value_dup_object (value); break; @@ -1988,17 +2050,19 @@ set_property (GObject *object, } static void -get_property (GObject *object, - guint prop_id, - GValue *value, +get_property (GObject *object, + guint prop_id, + GValue *value, GParamSpec *pspec) { MMPluginManagerPrivate *priv = MM_PLUGIN_MANAGER (object)->priv; switch (prop_id) { +#if !defined WITH_BUILTIN_PLUGINS case PROP_PLUGIN_DIR: g_value_set_string (value, priv->plugin_dir); break; +#endif case PROP_FILTER: g_value_set_object (value, priv->filter); break; @@ -2009,12 +2073,16 @@ get_property (GObject *object, } static gboolean -initable_init (GInitable *initable, - GCancellable *cancellable, - GError **error) +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) { - /* Load the list of plugins */ - return load_plugins (MM_PLUGIN_MANAGER (initable), error); +#if defined WITH_BUILTIN_PLUGINS + return load_builtin_plugins (MM_PLUGIN_MANAGER (initable), error); +#else + /* Load the list of plugins from the filesystem*/ + return load_external_plugins (MM_PLUGIN_MANAGER (initable), error); +#endif } static void @@ -2024,9 +2092,11 @@ dispose (GObject *object) g_list_free_full (g_steal_pointer (&self->priv->plugins), g_object_unref); g_clear_object (&self->priv->generic); - g_clear_pointer (&self->priv->plugin_dir, g_free); g_clear_object (&self->priv->filter); g_clear_pointer (&self->priv->subsystems, g_strfreev); +#if !defined WITH_BUILTIN_PLUGINS + g_clear_pointer (&self->priv->plugin_dir, g_free); +#endif G_OBJECT_CLASS (mm_plugin_manager_parent_class)->dispose (object); } @@ -2056,6 +2126,7 @@ mm_plugin_manager_class_init (MMPluginManagerClass *manager_class) object_class->get_property = get_property; /* Properties */ +#if !defined WITH_BUILTIN_PLUGINS g_object_class_install_property (object_class, PROP_PLUGIN_DIR, g_param_spec_string (MM_PLUGIN_MANAGER_PLUGIN_DIR, @@ -2063,6 +2134,8 @@ mm_plugin_manager_class_init (MMPluginManagerClass *manager_class) "Where to look for plugins", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +#endif + g_object_class_install_property (object_class, PROP_FILTER, g_param_spec_object (MM_PLUGIN_MANAGER_FILTER, diff --git a/src/mm-plugin-manager.h b/src/mm-plugin-manager.h index 79e7c1a1..f1ddcc29 100644 --- a/src/mm-plugin-manager.h +++ b/src/mm-plugin-manager.h @@ -32,7 +32,9 @@ #define MM_IS_PLUGIN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), MM_TYPE_PLUGIN_MANAGER)) #define MM_PLUGIN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_MANAGER, MMPluginManagerClass)) -#define MM_PLUGIN_MANAGER_PLUGIN_DIR "plugin-dir" /* Construct-only */ +#if !defined WITH_BUILTIN_PLUGINS +# define MM_PLUGIN_MANAGER_PLUGIN_DIR "plugin-dir" /* Construct-only */ +#endif #define MM_PLUGIN_MANAGER_FILTER "filter" /* Construct-only */ typedef struct _MMPluginManager MMPluginManager; @@ -51,8 +53,10 @@ struct _MMPluginManagerClass { GType mm_plugin_manager_get_type (void); G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMPluginManager, g_object_unref) -MMPluginManager *mm_plugin_manager_new (const gchar *plugindir, - MMFilter *filter, +MMPluginManager *mm_plugin_manager_new (MMFilter *filter, +#if !defined WITH_BUILTIN_PLUGINS + const gchar *plugindir, +#endif GError **error); void mm_plugin_manager_device_support_check (MMPluginManager *self, MMDevice *device, diff --git a/src/plugins/meson.build b/src/plugins/meson.build index bf670864..78adb873 100644 --- a/src/plugins/meson.build +++ b/src/plugins/meson.build @@ -1,8 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Copyright (C) 2021 IƱigo Martinez <inigomartinez@gmail.com> -symbol_map = plugins_dir / 'symbol.map' -ldflags = cc.get_supported_link_arguments('-Wl,--version-script,@0@'.format(symbol_map)) +if not enable_builtin_plugins + symbol_map = plugins_dir / 'symbol.map' + ldflags = cc.get_supported_link_arguments('-Wl,--version-script,@0@'.format(symbol_map)) +endif # common service test support plugins_common_test_dep = [] @@ -36,7 +38,6 @@ if enable_tests endif # plugins -plugins_inc = include_directories('.') plugins = {} plugins_data = [] plugins_udev_rules = [] @@ -958,6 +959,13 @@ if plugins_options['zte'] plugins_udev_rules += files('zte/77-mm-zte-port-types.rules') endif +builtin_sources = [] +builtin_plugins = [] + +if enable_builtin_plugins + builtin_sources += files('mm-builtin-plugins.c') +endif + foreach plugin_name, plugin_data: plugins libpluginhelpers = [] if plugin_data.has_key('helper') @@ -969,21 +977,31 @@ foreach plugin_name, plugin_data: plugins endif module_args = plugin_data['module'] - if plugin_data['plugin'] - module_args += { - 'link_args': ldflags, - 'link_depends': symbol_map, - } - endif + if not enable_builtin_plugins + if plugin_data['plugin'] + module_args += { + 'link_args': ldflags, + 'link_depends': symbol_map, + } + endif - shared_module( - 'mm-' + plugin_name, - dependencies: plugins_deps, - link_with: libpluginhelpers, - kwargs: module_args, - install: true, - install_dir: mm_pkglibdir, - ) + shared_module( + 'mm-' + plugin_name, + dependencies: plugins_deps, + link_with: libpluginhelpers, + kwargs: module_args, + install: true, + install_dir: mm_pkglibdir, + ) + else + libplugin = static_library( + 'mm-' + plugin_name, + dependencies: plugins_deps, + link_with: libpluginhelpers, + kwargs: module_args, + ) + builtin_plugins += libplugin + endif if enable_tests if plugin_data.has_key('test') diff --git a/src/plugins/mm-builtin-plugins.c b/src/plugins/mm-builtin-plugins.c new file mode 100644 index 00000000..378a7cba --- /dev/null +++ b/src/plugins/mm-builtin-plugins.c @@ -0,0 +1,273 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2022 Google Inc. + */ + +#include <config.h> +#include <glib.h> + +#include "mm-plugin.h" +#include "mm-builtin-plugins.h" + +#if defined ENABLE_PLUGIN_ALTAIR_LTE +MMPlugin *mm_plugin_create_altair_lte (void); +#endif +#if defined ENABLE_PLUGIN_ANYDATA +MMPlugin *mm_plugin_create_anydata (void); +#endif +#if defined ENABLE_PLUGIN_BROADMOBI +MMPlugin *mm_plugin_create_broadmobi (void); +#endif +#if defined ENABLE_PLUGIN_CINTERION +MMPlugin *mm_plugin_create_cinterion (void); +#endif +#if defined ENABLE_PLUGIN_DELL +MMPlugin *mm_plugin_create_dell (void); +#endif +#if defined ENABLE_PLUGIN_DLINK +MMPlugin *mm_plugin_create_dlink (void); +#endif +#if defined ENABLE_PLUGIN_FIBOCOM +MMPlugin *mm_plugin_create_fibocom (void); +#endif +#if defined ENABLE_PLUGIN_FOXCONN +MMPlugin *mm_plugin_create_foxconn (void); +#endif +#if defined ENABLE_PLUGIN_GENERIC +MMPlugin *mm_plugin_create_generic (void); +#endif +#if defined ENABLE_PLUGIN_GOSUNCN +MMPlugin *mm_plugin_create_gosuncn (void); +#endif +#if defined ENABLE_PLUGIN_HAIER +MMPlugin *mm_plugin_create_haier (void); +#endif +#if defined ENABLE_PLUGIN_HUAWEI +MMPlugin *mm_plugin_create_huawei (void); +#endif +#if defined ENABLE_PLUGIN_INTEL +MMPlugin *mm_plugin_create_intel (void); +#endif +#if defined ENABLE_PLUGIN_IRIDIUM +MMPlugin *mm_plugin_create_iridium (void); +#endif +#if defined ENABLE_PLUGIN_LINKTOP +MMPlugin *mm_plugin_create_linktop (void); +#endif +#if defined ENABLE_PLUGIN_LONGCHEER +MMPlugin *mm_plugin_create_longcheer (void); +#endif +#if defined ENABLE_PLUGIN_MBM +MMPlugin *mm_plugin_create_mbm (void); +#endif +#if defined ENABLE_PLUGIN_MOTOROLA +MMPlugin *mm_plugin_create_motorola (void); +#endif +#if defined ENABLE_PLUGIN_MTK +MMPlugin *mm_plugin_create_mtk (void); +#endif +#if defined ENABLE_PLUGIN_NOKIA +MMPlugin *mm_plugin_create_nokia (void); +#endif +#if defined ENABLE_PLUGIN_NOKIA_ICERA +MMPlugin *mm_plugin_create_nokia_icera (void); +#endif +#if defined ENABLE_PLUGIN_NOVATEL +MMPlugin *mm_plugin_create_novatel (void); +#endif +#if defined ENABLE_PLUGIN_NOVATEL_LTE +MMPlugin *mm_plugin_create_novatel_lte (void); +#endif +#if defined ENABLE_PLUGIN_OPTION +MMPlugin *mm_plugin_create_option (void); +#endif +#if defined ENABLE_PLUGIN_OPTION_HSO +MMPlugin *mm_plugin_create_hso (void); +#endif +#if defined ENABLE_PLUGIN_PANTECH +MMPlugin *mm_plugin_create_pantech (void); +#endif +#if defined ENABLE_PLUGIN_QCOM_SOC +MMPlugin *mm_plugin_create_qcom_soc (void); +#endif +#if defined ENABLE_PLUGIN_QUECTEL +MMPlugin *mm_plugin_create_quectel (void); +#endif +#if defined ENABLE_PLUGIN_SAMSUNG +MMPlugin *mm_plugin_create_samsung (void); +#endif +#if defined ENABLE_PLUGIN_SIERRA +MMPlugin *mm_plugin_create_sierra (void); +#endif +#if defined ENABLE_PLUGIN_SIERRA_LEGACY +MMPlugin *mm_plugin_create_sierra_legacy (void); +#endif +#if defined ENABLE_PLUGIN_SIMTECH +MMPlugin *mm_plugin_create_simtech (void); +#endif +#if defined ENABLE_PLUGIN_TELIT +MMPlugin *mm_plugin_create_telit (void); +#endif +#if defined ENABLE_PLUGIN_THURAYA +MMPlugin *mm_plugin_create_thuraya (void); +#endif +#if defined ENABLE_PLUGIN_TPLINK +MMPlugin *mm_plugin_create_tplink (void); +#endif +#if defined ENABLE_PLUGIN_UBLOX +MMPlugin *mm_plugin_create_ublox (void); +#endif +#if defined ENABLE_PLUGIN_VIA +MMPlugin *mm_plugin_create_via (void); +#endif +#if defined ENABLE_PLUGIN_WAVECOM +MMPlugin *mm_plugin_create_wavecom (void); +#endif +#if defined ENABLE_PLUGIN_X22X +MMPlugin *mm_plugin_create_x22x (void); +#endif +#if defined ENABLE_PLUGIN_ZTE +MMPlugin *mm_plugin_create_zte (void); +#endif + +GList * +mm_builtin_plugins_load (void) +{ + GList *builtin_plugins = NULL; + +#define PREPEND_PLUGIN(my_plugin) \ + builtin_plugins = g_list_prepend (builtin_plugins, mm_plugin_create_##my_plugin ()) + +#if defined ENABLE_PLUGIN_ALTAIR_LTE + PREPEND_PLUGIN (altair_lte); +#endif +#if defined ENABLE_PLUGIN_ANYDATA + PREPEND_PLUGIN (anydata); +#endif +#if defined ENABLE_PLUGIN_BROADMOBI + PREPEND_PLUGIN (broadmobi); +#endif +#if defined ENABLE_PLUGIN_CINTERION + PREPEND_PLUGIN (cinterion); +#endif +#if defined ENABLE_PLUGIN_DELL + PREPEND_PLUGIN (dell); +#endif +#if defined ENABLE_PLUGIN_DLINK + PREPEND_PLUGIN (dlink); +#endif +#if defined ENABLE_PLUGIN_FIBOCOM + PREPEND_PLUGIN (fibocom); +#endif +#if defined ENABLE_PLUGIN_FOXCONN + PREPEND_PLUGIN (foxconn); +#endif +#if defined ENABLE_PLUGIN_GENERIC + PREPEND_PLUGIN (generic); +#endif +#if defined ENABLE_PLUGIN_GOSUNCN + PREPEND_PLUGIN (gosuncn); +#endif +#if defined ENABLE_PLUGIN_HAIER + PREPEND_PLUGIN (haier); +#endif +#if defined ENABLE_PLUGIN_HUAWEI + PREPEND_PLUGIN (huawei); +#endif +#if defined ENABLE_PLUGIN_INTEL + PREPEND_PLUGIN (intel); +#endif +#if defined ENABLE_PLUGIN_IRIDIUM + PREPEND_PLUGIN (iridium); +#endif +#if defined ENABLE_PLUGIN_LINKTOP + PREPEND_PLUGIN (linktop); +#endif +#if defined ENABLE_PLUGIN_LONGCHEER + PREPEND_PLUGIN (longcheer); +#endif +#if defined ENABLE_PLUGIN_MBM + PREPEND_PLUGIN (mbm); +#endif +#if defined ENABLE_PLUGIN_MOTOROLA + PREPEND_PLUGIN (motorola); +#endif +#if defined ENABLE_PLUGIN_MTK + PREPEND_PLUGIN (mtk); +#endif +#if defined ENABLE_PLUGIN_NOKIA + PREPEND_PLUGIN (nokia); +#endif +#if defined ENABLE_PLUGIN_NOKIA_ICERA + PREPEND_PLUGIN (nokia_icera); +#endif +#if defined ENABLE_PLUGIN_NOVATEL + PREPEND_PLUGIN (novatel); +#endif +#if defined ENABLE_PLUGIN_NOVATEL_LTE + PREPEND_PLUGIN (novatel_lte); +#endif +#if defined ENABLE_PLUGIN_OPTION + PREPEND_PLUGIN (option); +#endif +#if defined ENABLE_PLUGIN_OPTION_HSO + PREPEND_PLUGIN (hso); +#endif +#if defined ENABLE_PLUGIN_PANTECH + PREPEND_PLUGIN (pantech); +#endif +#if defined ENABLE_PLUGIN_QCOM_SOC + PREPEND_PLUGIN (qcom_soc); +#endif +#if defined ENABLE_PLUGIN_QUECTEL + PREPEND_PLUGIN (quectel); +#endif +#if defined ENABLE_PLUGIN_SAMSUNG + PREPEND_PLUGIN (samsung); +#endif +#if defined ENABLE_PLUGIN_SIERRA + PREPEND_PLUGIN (sierra); +#endif +#if defined ENABLE_PLUGIN_SIERRA_LEGACY + PREPEND_PLUGIN (sierra_legacy); +#endif +#if defined ENABLE_PLUGIN_SIMTECH + PREPEND_PLUGIN (simtech); +#endif +#if defined ENABLE_PLUGIN_TELIT + PREPEND_PLUGIN (telit); +#endif +#if defined ENABLE_PLUGIN_THURAYA + PREPEND_PLUGIN (thuraya); +#endif +#if defined ENABLE_PLUGIN_TPLINK + PREPEND_PLUGIN (tplink); +#endif +#if defined ENABLE_PLUGIN_UBLOX + PREPEND_PLUGIN (ublox); +#endif +#if defined ENABLE_PLUGIN_VIA + PREPEND_PLUGIN (via); +#endif +#if defined ENABLE_PLUGIN_WAVECOM + PREPEND_PLUGIN (wavecom); +#endif +#if defined ENABLE_PLUGIN_X22X + PREPEND_PLUGIN (x22x); +#endif +#if defined ENABLE_PLUGIN_ZTE + PREPEND_PLUGIN (zte); +#endif +#undef PREPEND_PLUGIN + return builtin_plugins; +} diff --git a/src/plugins/mm-builtin-plugins.h b/src/plugins/mm-builtin-plugins.h new file mode 100644 index 00000000..dac9c3b2 --- /dev/null +++ b/src/plugins/mm-builtin-plugins.h @@ -0,0 +1,28 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2022 Google Inc. + */ + +#ifndef MM_BUILTIN_PLUGINS_H +#define MM_BUILTIN_PLUGINS_H + +#include <config.h> +#include <glib.h> + +#if !defined WITH_BUILTIN_PLUGINS +# error Build with builtin plugins was not enabled +#endif + +GList *mm_builtin_plugins_load (void); + +#endif /* MM_BUILTIN_PLUGINS_H */ diff --git a/src/plugins/mm-plugin-common.h b/src/plugins/mm-plugin-common.h index 607d24db..55e06d7e 100644 --- a/src/plugins/mm-plugin-common.h +++ b/src/plugins/mm-plugin-common.h @@ -26,20 +26,28 @@ #include "mm-plugin.h" -#define MM_PLUGIN_NAMED_CREATOR_SCOPE static +#if defined (G_HAVE_GNUC_VISIBILITY) +# define MM_VISIBILITY __attribute__((visibility("protected"))) +#else +# define MM_VISIBILITY +#endif -#define MM_PLUGIN_CREATOR(my_plugin) \ +#if defined WITH_BUILTIN_PLUGINS +# define MM_PLUGIN_VERSION +# define MM_PLUGIN_NAMED_CREATOR_SCOPE +# define MM_PLUGIN_CREATOR(unused) +#else +# define MM_PLUGIN_VERSION \ + MM_VISIBILITY int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION; \ + MM_VISIBILITY int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION; +# define MM_PLUGIN_NAMED_CREATOR_SCOPE static +# define MM_PLUGIN_CREATOR(my_plugin) \ G_MODULE_EXPORT MMPlugin *mm_plugin_create (void); \ G_MODULE_EXPORT MMPlugin * \ mm_plugin_create (void) \ { \ return mm_plugin_create_##my_plugin (); \ } - -#if defined (G_HAVE_GNUC_VISIBILITY) -# define MM_VISIBILITY __attribute__((visibility("protected"))) -#else -# define MM_VISIBILITY #endif #define MM_DEFINE_PLUGIN(MY_PLUGIN, my_plugin, MyPlugin) \ @@ -49,8 +57,7 @@ }; \ G_DEFINE_TYPE (MMPlugin##MyPlugin, mm_plugin_##my_plugin, MM_TYPE_PLUGIN) \ \ - MM_VISIBILITY int mm_plugin_major_version = MM_PLUGIN_MAJOR_VERSION; \ - MM_VISIBILITY int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION; \ + MM_PLUGIN_VERSION \ \ MM_PLUGIN_NAMED_CREATOR_SCOPE MMPlugin *mm_plugin_create_##my_plugin (void); \ MM_PLUGIN_CREATOR(my_plugin) diff --git a/src/plugins/mm-shared-common.h b/src/plugins/mm-shared-common.h index a9183ee6..d795624f 100644 --- a/src/plugins/mm-shared-common.h +++ b/src/plugins/mm-shared-common.h @@ -33,9 +33,13 @@ #define MM_VISIBILITY #endif -#define MM_DEFINE_SHARED(MyShared) \ +#if defined WITH_BUILTIN_PLUGINS +# define MM_DEFINE_SHARED(unused) +#else +# define MM_DEFINE_SHARED(MyShared) \ MM_VISIBILITY int mm_shared_major_version = MM_SHARED_MAJOR_VERSION; \ MM_VISIBILITY int mm_shared_minor_version = MM_SHARED_MINOR_VERSION; \ MM_VISIBILITY const char *mm_shared_name = #MyShared; +#endif #endif /* MM_SHARED_COMMON_H */ |