1f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann/*
2f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *
3f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  BlueZ - Bluetooth protocol stack for Linux
4f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *
59184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
6f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *
7f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *
8f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  This program is free software; you can redistribute it and/or modify
9f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  it under the terms of the GNU General Public License as published by
10f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  the Free Software Foundation; either version 2 of the License, or
11f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  (at your option) any later version.
12f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *
13f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  This program is distributed in the hope that it will be useful,
14f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  GNU General Public License for more details.
17f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *
18f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  You should have received a copy of the GNU General Public License
19f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  along with this program; if not, write to the Free Software
20f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann *
22f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann */
23f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann
24f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann#ifdef HAVE_CONFIG_H
25f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann#include <config.h>
26f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann#endif
27f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann
2853df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann#include <errno.h>
2953df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann#include <dlfcn.h>
30e213b1b8cc0043c971196c0646f3dbaf9344958fLuiz Augusto von Dentz#include <string.h>
31e213b1b8cc0043c971196c0646f3dbaf9344958fLuiz Augusto von Dentz#include <sys/stat.h>
32e17ea9f35ae810afd33b332978d5882953696cfdClaudio Takahasi
33db1ade6349ae3e3f1e5849abb6af604cd9ff26aaMarcel Holtmann#include <bluetooth/bluetooth.h>
34db1ade6349ae3e3f1e5849abb6af604cd9ff26aaMarcel Holtmann
3553df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann#include <glib.h>
369491a544f622e40453265c30f24ce44a61440cc1Claudio Takahasi
37f891d23d47274a8788ccdd738ee160f27fb0935bMarcel Holtmann#include "plugin.h"
38e891f7df6225c758da0d95f7554c6cc67f72f31eGustavo F. Padovan#include "log.h"
39db1ade6349ae3e3f1e5849abb6af604cd9ff26aaMarcel Holtmann#include "hcid.h"
4056fe087dfc68f56d84ac41ca390c8a0dc7438e2dLuiz Augusto von Dentz#include "btio.h"
41d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
42d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmannstatic GSList *plugins = NULL;
43d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
44d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmannstruct bluetooth_plugin {
4553df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann	void *handle;
462f28c39a63e19e41598af8088c5677859364bc04Alok Barsode	gboolean active;
47d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	struct bluetooth_plugin_desc *desc;
48d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann};
49d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
502f28c39a63e19e41598af8088c5677859364bc04Alok Barsodestatic gint compare_priority(gconstpointer a, gconstpointer b)
512f28c39a63e19e41598af8088c5677859364bc04Alok Barsode{
522f28c39a63e19e41598af8088c5677859364bc04Alok Barsode	const struct bluetooth_plugin *plugin1 = a;
532f28c39a63e19e41598af8088c5677859364bc04Alok Barsode	const struct bluetooth_plugin *plugin2 = b;
542f28c39a63e19e41598af8088c5677859364bc04Alok Barsode
552f28c39a63e19e41598af8088c5677859364bc04Alok Barsode	return plugin2->desc->priority - plugin1->desc->priority;
562f28c39a63e19e41598af8088c5677859364bc04Alok Barsode}
572f28c39a63e19e41598af8088c5677859364bc04Alok Barsode
5853df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmannstatic gboolean add_plugin(void *handle, struct bluetooth_plugin_desc *desc)
59d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann{
60d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	struct bluetooth_plugin *plugin;
61d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
6253df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann	if (desc->init == NULL)
630d2ed5bfcb127e68bc695eeeadd8751f7f8a4d7aLuiz Augusto von Dentz		return FALSE;
640d2ed5bfcb127e68bc695eeeadd8751f7f8a4d7aLuiz Augusto von Dentz
65bf6a4a577408aa6192c40f9a789788badb1a386aAlok Barsode	if (g_str_equal(desc->version, VERSION) == FALSE) {
661ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann		error("Version mismatch for %s", desc->name);
67bf6a4a577408aa6192c40f9a789788badb1a386aAlok Barsode		return FALSE;
68bf6a4a577408aa6192c40f9a789788badb1a386aAlok Barsode	}
69bf6a4a577408aa6192c40f9a789788badb1a386aAlok Barsode
708e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("Loading %s plugin", desc->name);
711ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann
72d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	plugin = g_try_new0(struct bluetooth_plugin, 1);
73d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	if (plugin == NULL)
74d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann		return FALSE;
75d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
7653df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann	plugin->handle = handle;
772f28c39a63e19e41598af8088c5677859364bc04Alok Barsode	plugin->active = FALSE;
78d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	plugin->desc = desc;
79d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
802f28c39a63e19e41598af8088c5677859364bc04Alok Barsode	plugins = g_slist_insert_sorted(plugins, plugin, compare_priority);
81d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
82d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	return TRUE;
83d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann}
84f891d23d47274a8788ccdd738ee160f27fb0935bMarcel Holtmann
852f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedbergstatic gboolean enable_plugin(const char *name, char **conf_disable,
862f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg					char **cli_enable, char **cli_disable)
877c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg{
882f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	if (conf_disable) {
892f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		for (; *conf_disable; conf_disable++)
902f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			if (g_pattern_match_simple(*conf_disable, name))
912f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg				break;
922f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		if (*conf_disable) {
932f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			info("Excluding (conf) %s", name);
942f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			return FALSE;
952f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		}
962f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	}
977c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg
982f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	if (cli_disable) {
992f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		for (; *cli_disable; cli_disable++)
1002f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			if (g_pattern_match_simple(*cli_disable, name))
1012f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg				break;
1022f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		if (*cli_disable) {
1032f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			info("Excluding (cli) %s", name);
1042f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			return FALSE;
1052f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		}
1062f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	}
1077c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg
1082f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	if (cli_enable) {
1092f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		for (; *cli_enable; cli_enable++)
1102f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			if (g_pattern_match_simple(*cli_enable, name))
1112f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg				break;
1122f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		if (!*cli_enable) {
1132f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			info("Ignoring (cli) %s", name);
1142f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			return FALSE;
1152f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		}
1167c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg	}
1177c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg
1182f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	return TRUE;
1197c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg}
1207c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg
1211ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann#include "builtin.h"
1221ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann
1232f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberggboolean plugin_init(GKeyFile *config, const char *enable, const char *disable)
124f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann{
1252f28c39a63e19e41598af8088c5677859364bc04Alok Barsode	GSList *list;
126d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	GDir *dir;
127d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	const gchar *file;
1282f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	char **conf_disabled, **cli_disabled, **cli_enabled;
1291ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann	unsigned int i;
1307c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg
13156fe087dfc68f56d84ac41ca390c8a0dc7438e2dLuiz Augusto von Dentz	/* Make a call to BtIO API so its symbols got resolved before the
13256fe087dfc68f56d84ac41ca390c8a0dc7438e2dLuiz Augusto von Dentz	 * plugins are loaded. */
13356fe087dfc68f56d84ac41ca390c8a0dc7438e2dLuiz Augusto von Dentz	bt_io_error_quark();
13456fe087dfc68f56d84ac41ca390c8a0dc7438e2dLuiz Augusto von Dentz
1357c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg	if (config)
1362f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		conf_disabled = g_key_file_get_string_list(config, "General",
1377c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg							"DisablePlugins",
1387c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg							NULL, NULL);
1397c67f70b684870920af46c1561eedc475c4ad31fJohan Hedberg	else
1402f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		conf_disabled = NULL;
1412f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg
1422f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	if (enable)
1432f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		cli_enabled = g_strsplit_set(enable, ", ", -1);
1442f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	else
1452f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		cli_enabled = NULL;
1462f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg
1472f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	if (disable)
1482f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		cli_disabled = g_strsplit_set(disable, ", ", -1);
1492f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	else
1502f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		cli_disabled = NULL;
151d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
1528e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("Loading builtin plugins");
1531ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann
1541ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann	for (i = 0; __bluetooth_builtin[i]; i++) {
1552f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		if (!enable_plugin(__bluetooth_builtin[i]->name, conf_disabled,
1562f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg						cli_enabled, cli_disabled))
1571ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann			continue;
1581ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann
1591ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann		add_plugin(NULL,  __bluetooth_builtin[i]);
1601ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann	}
1611ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann
1622f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	if (strlen(PLUGINDIR) == 0)
163d015dc8986f8548653160bc9ee6c8fef126dd8e8Marcel Holtmann		goto start;
164f21f133fe7684161d8ac76a183f8dee2766e2a33Marcel Holtmann
1658e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("Loading plugins %s", PLUGINDIR);
166d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
167d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	dir = g_dir_open(PLUGINDIR, 0, NULL);
1682f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	if (!dir)
169f28b8226e3c0adcc88c0e9a5a01529c02ad814a1Marcel Holtmann		goto start;
170d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
1710d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz	while ((file = g_dir_read_name(dir)) != NULL) {
1720d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz		struct bluetooth_plugin_desc *desc;
17353df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann		void *handle;
1740d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz		gchar *filename;
175d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
176a22a088109b664efdee397affed55b039cb0999bMarcel Holtmann		if (g_str_has_prefix(file, "lib") == TRUE ||
177e213b1b8cc0043c971196c0646f3dbaf9344958fLuiz Augusto von Dentz				g_str_has_suffix(file, ".so") == FALSE)
1780d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz			continue;
179d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
1800d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz		filename = g_build_filename(PLUGINDIR, file, NULL);
181d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
18253df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann		handle = dlopen(filename, RTLD_NOW);
18353df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann		if (handle == NULL) {
18453df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann			error("Can't load plugin %s: %s", filename,
18553df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann								dlerror());
1869513c9f152909755d080f2ca65b8a7a109a9e946Luiz Augusto von Dentz			g_free(filename);
1870d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz			continue;
1880d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz		}
189d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
1909513c9f152909755d080f2ca65b8a7a109a9e946Luiz Augusto von Dentz		g_free(filename);
1919513c9f152909755d080f2ca65b8a7a109a9e946Luiz Augusto von Dentz
19253df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann		desc = dlsym(handle, "bluetooth_plugin_desc");
19353df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann		if (desc == NULL) {
19453df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann			error("Can't load plugin description: %s", dlerror());
19553df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann			dlclose(handle);
1960d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz			continue;
1970d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz		}
198d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
1992f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		if (!enable_plugin(desc->name, conf_disabled,
2002f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg						cli_enabled, cli_disabled)) {
2012f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			dlclose(handle);
2022f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg			continue;
2032f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg		}
2042f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg
20553df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann		if (add_plugin(handle, desc) == FALSE)
20653df62e6f94e30bc8f099af7c858d38a94fddf4bMarcel Holtmann			dlclose(handle);
207d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	}
208d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
2090d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz	g_dir_close(dir);
2100d34aea6ba9d77a06b8d7a80550c63287b0bbd60Luiz Augusto von Dentz
211f28b8226e3c0adcc88c0e9a5a01529c02ad814a1Marcel Holtmannstart:
2122f28c39a63e19e41598af8088c5677859364bc04Alok Barsode	for (list = plugins; list; list = list->next) {
2132f28c39a63e19e41598af8088c5677859364bc04Alok Barsode		struct bluetooth_plugin *plugin = list->data;
2142f28c39a63e19e41598af8088c5677859364bc04Alok Barsode
215319344bb0a81db7538d6de258046a64855fc2938Marcel Holtmann		if (plugin->desc->init() < 0) {
216319344bb0a81db7538d6de258046a64855fc2938Marcel Holtmann			error("Failed to init %s plugin", plugin->desc->name);
2172f28c39a63e19e41598af8088c5677859364bc04Alok Barsode			continue;
218319344bb0a81db7538d6de258046a64855fc2938Marcel Holtmann		}
2192f28c39a63e19e41598af8088c5677859364bc04Alok Barsode
2202f28c39a63e19e41598af8088c5677859364bc04Alok Barsode		plugin->active = TRUE;
2212f28c39a63e19e41598af8088c5677859364bc04Alok Barsode	}
2222f28c39a63e19e41598af8088c5677859364bc04Alok Barsode
2232f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	g_strfreev(conf_disabled);
2242f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	g_strfreev(cli_enabled);
2252f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg	g_strfreev(cli_disabled);
2262f1d6986e5f2bc8539bb056e8c608061c191a79bJohan Hedberg
227d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	return TRUE;
228f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann}
229f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann
230f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmannvoid plugin_cleanup(void)
231f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann{
232d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	GSList *list;
233d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
2348e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan	DBG("Cleanup plugins");
235d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
236d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	for (list = plugins; list; list = list->next) {
237d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann		struct bluetooth_plugin *plugin = list->data;
238d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
2392f28c39a63e19e41598af8088c5677859364bc04Alok Barsode		if (plugin->active == TRUE && plugin->desc->exit)
240d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann			plugin->desc->exit();
241d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
2421ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann		if (plugin->handle != NULL)
2431ab388feb37980f1afc940c7cf530b9baadeabb1Marcel Holtmann			dlclose(plugin->handle);
244d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
245d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann		g_free(plugin);
246d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	}
247d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann
248d95d0269d8276d311650e1726aceeafbd8116c34Marcel Holtmann	g_slist_free(plugins);
249f5b7c429b4d9fe8e83bf2e598e72084c83f77a0fMarcel Holtmann}
250