@@ -725,7 +725,8 @@ src_ofonod_SOURCES = $(builtin_sources) $(gatchat_sources) src/ofono.ver \
src/handsfree-audio.c src/bluetooth.h \
src/hfp.h src/siri.c \
src/netmon.c src/lte.c src/ims.c \
- src/netmonagent.c src/netmonagent.h
+ src/netmonagent.c src/netmonagent.h \
+ src/module.c
src_ofonod_LDADD = gdbus/libgdbus-internal.la $(builtin_libadd) $(ell_ldadd) \
@GLIB_LIBS@ @DBUS_LIBS@ -ldl
@@ -274,12 +274,10 @@ int main(int argc, char **argv)
__ofono_dbus_init(conn);
- __ofono_modemwatch_init();
-
- __ofono_manager_init();
+ if (__ofono_modules_init() < 0)
+ goto fail_module_init;
__ofono_plugin_init(option_plugin, option_noplugin);
-
g_free(option_plugin);
g_free(option_noplugin);
@@ -287,10 +285,9 @@ int main(int argc, char **argv)
__ofono_plugin_cleanup();
- __ofono_manager_cleanup();
-
- __ofono_modemwatch_cleanup();
+ __ofono_modules_cleanup();
+fail_module_init:
__ofono_dbus_cleanup();
dbus_connection_unref(conn);
@@ -95,7 +95,7 @@ static const GDBusSignalTable manager_signals[] = {
{ }
};
-int __ofono_manager_init(void)
+static int manager_init(void)
{
DBusConnection *conn = ofono_dbus_get_connection();
gboolean ret;
@@ -111,10 +111,12 @@ int __ofono_manager_init(void)
return 0;
}
-void __ofono_manager_cleanup(void)
+static void manager_cleanup(void)
{
DBusConnection *conn = ofono_dbus_get_connection();
g_dbus_unregister_interface(conn, OFONO_MANAGER_PATH,
OFONO_MANAGER_INTERFACE);
}
+
+OFONO_MODULE(manager, manager_init, manager_cleanup)
@@ -1918,12 +1918,13 @@ static void sim_watch(struct ofono_atom *atom,
modem, NULL);
}
-void __ofono_modemwatch_init(void)
+static int modemwatch_init(void)
{
g_modemwatches = __ofono_watchlist_new(g_free);
+ return 0;
}
-void __ofono_modemwatch_cleanup(void)
+static void modemwatch_cleanup(void)
{
__ofono_watchlist_free(g_modemwatches);
}
@@ -2319,3 +2320,5 @@ void __ofono_modem_dec_emergency_mode(struct ofono_modem *modem)
out:
modem->emergency--;
}
+
+OFONO_MODULE(modemwatch, modemwatch_init, modemwatch_cleanup)
new file mode 100644
@@ -0,0 +1,55 @@
+/*
+ * oFono - Open Source Telephony
+ * Copyright (C) 2023 Cruise, LLC
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <ell/ell.h>
+
+#include "ofono.h"
+
+extern struct ofono_module_desc __start___ofono_module[];
+extern struct ofono_module_desc __stop___ofono_module[];
+
+int __ofono_modules_init(void)
+{
+ struct ofono_module_desc *desc;
+ size_t i;
+ int r;
+ size_t n_modules = __stop___ofono_module - __start___ofono_module;
+
+ DBG("");
+
+ for (i = 0; i < n_modules; i++) {
+ desc = __start___ofono_module + i;
+ r = desc->init();
+
+ if (r < 0) {
+ ofono_error("Module %s failed to start: %s(%d)",
+ desc->name, strerror(-r), -r);
+ return r;
+ }
+ }
+
+ return 0;
+}
+
+void __ofono_modules_cleanup(void)
+{
+ struct ofono_module_desc *desc;
+ size_t i;
+ size_t n_modules = __stop___ofono_module - __start___ofono_module;
+
+ l_debug("");
+
+ for (i = n_modules; i > 0; i--) {
+ desc = __start___ofono_module + i - 1;
+ desc->exit();
+ }
+}
@@ -28,9 +28,6 @@
void __ofono_exit(void);
-int __ofono_manager_init(void);
-void __ofono_manager_cleanup(void);
-
int __ofono_handsfree_audio_manager_init(void);
void __ofono_handsfree_audio_manager_cleanup(void);
@@ -97,6 +94,25 @@ gboolean __ofono_watchlist_remove_item(struct ofono_watchlist *watchlist,
unsigned int id);
void __ofono_watchlist_free(struct ofono_watchlist *watchlist);
+struct ofono_module_desc {
+ const char *name;
+ int (*init)(void);
+ void (*exit)(void);
+} __attribute__((aligned(8)));
+
+#define OFONO_MODULE(name, init, exit) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wattributes\"") \
+ static struct ofono_module_desc __ofono_module_ ## name \
+ __attribute__((used, retain, section("__ofono_module"), \
+ aligned(8))) = { \
+ #name, init, exit \
+ }; \
+ _Pragma("GCC diagnostic pop")
+
+int __ofono_modules_init(void);
+void __ofono_modules_cleanup(void);
+
#include <ofono/plugin.h>
int __ofono_plugin_init(const char *pattern, const char *exclude);