Add support for multiple potential adapter_ops implementations

This patch changes the adapter_ops registration procedure to simply add
the callback struct into a list. The actual adapter_ops implementation
that gets used gets chosen in the adapter_ops_setup function.
This commit is contained in:
Johan Hedberg 2010-10-27 11:07:36 -04:00
parent f92841301d
commit d300441574
3 changed files with 32 additions and 13 deletions

View File

@ -2341,7 +2341,7 @@ static struct btd_adapter_ops hci_ops = {
static int hciops_init(void)
{
return btd_register_adapter_ops(&hci_ops);
return btd_register_adapter_ops(&hci_ops, FALSE);
}
static void hciops_exit(void)
{

View File

@ -72,6 +72,8 @@
static DBusConnection *connection = NULL;
static GSList *adapter_drivers = NULL;
static GSList *ops_candidates = NULL;
const struct btd_adapter_ops *adapter_ops = NULL;
struct session_req {
@ -3574,31 +3576,48 @@ int btd_adapter_switch_offline(struct btd_adapter *adapter)
return adapter_ops->set_powered(adapter->dev_id, FALSE);
}
int btd_register_adapter_ops(struct btd_adapter_ops *btd_adapter_ops)
int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority)
{
/* Already registered */
if (adapter_ops)
return -EALREADY;
if (btd_adapter_ops->setup == NULL)
if (ops->setup == NULL)
return -EINVAL;
adapter_ops = btd_adapter_ops;
if (priority)
ops_candidates = g_slist_prepend(ops_candidates, ops);
else
ops_candidates = g_slist_append(ops_candidates, ops);
return 0;
}
void btd_adapter_cleanup_ops(struct btd_adapter_ops *btd_adapter_ops)
void btd_adapter_cleanup_ops(struct btd_adapter_ops *ops)
{
adapter_ops->cleanup();
ops_candidates = g_slist_remove(ops_candidates, ops);
ops->cleanup();
if (adapter_ops == ops)
adapter_ops = NULL;
}
int adapter_ops_setup(void)
{
if (!adapter_ops)
GSList *l;
int ret;
if (!ops_candidates)
return -EINVAL;
return adapter_ops->setup();
for (l = ops_candidates; l != NULL; l = g_slist_next(l)) {
struct btd_adapter_ops *ops = l->data;
ret = ops->setup();
if (ret < 0)
continue;
adapter_ops = ops;
break;
}
return ret;
}
void btd_adapter_register_powered_callback(struct btd_adapter *adapter,

View File

@ -233,7 +233,7 @@ struct btd_adapter_ops {
gpointer user_data);
};
int btd_register_adapter_ops(struct btd_adapter_ops *btd_adapter_ops);
int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority);
void btd_adapter_cleanup_ops(struct btd_adapter_ops *btd_adapter_ops);
int adapter_ops_setup(void);