summaryrefslogtreecommitdiff
path: root/src/network.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-12-28 10:14:25 +0100
committerMarcel Holtmann <marcel@holtmann.org>2008-12-28 10:14:25 +0100
commit1c690efa00cb22a07f0472fdd9a93859c2bc18d3 (patch)
treedbcbe5e2b9282ed9c83cce6c1df74e22543a26a7 /src/network.c
parentc93def76c9179707bf020ec023fa010ec706984c (diff)
downloadconnman-1c690efa00cb22a07f0472fdd9a93859c2bc18d3.tar.gz
connman-1c690efa00cb22a07f0472fdd9a93859c2bc18d3.tar.bz2
connman-1c690efa00cb22a07f0472fdd9a93859c2bc18d3.zip
Add network driver matching support
Diffstat (limited to 'src/network.c')
-rw-r--r--src/network.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/network.c b/src/network.c
index cfd30120..3e35a38d 100644
--- a/src/network.c
+++ b/src/network.c
@@ -34,6 +34,47 @@ struct connman_network {
void *driver_data;
};
+static GSList *driver_list = NULL;
+
+static gint compare_priority(gconstpointer a, gconstpointer b)
+{
+ const struct connman_network_driver *driver1 = a;
+ const struct connman_network_driver *driver2 = b;
+
+ return driver2->priority - driver1->priority;
+}
+
+/**
+ * connman_network_driver_register:
+ * @driver: network driver definition
+ *
+ * Register a new network driver
+ *
+ * Returns: %0 on success
+ */
+int connman_network_driver_register(struct connman_network_driver *driver)
+{
+ DBG("driver %p name %s", driver, driver->name);
+
+ driver_list = g_slist_insert_sorted(driver_list, driver,
+ compare_priority);
+
+ return 0;
+}
+
+/**
+ * connman_network_driver_unregister:
+ * @driver: network driver definition
+ *
+ * Remove a previously registered network driver
+ */
+void connman_network_driver_unregister(struct connman_network_driver *driver)
+{
+ DBG("driver %p name %s", driver, driver->name);
+
+ driver_list = g_slist_remove(driver_list, driver);
+}
+
static void network_destruct(struct connman_element *element)
{
struct connman_network *network = element->network;
@@ -138,13 +179,60 @@ void connman_network_set_data(struct connman_network *network, void *data)
network->driver_data = data;
}
+static gboolean match_driver(struct connman_network *network,
+ struct connman_network_driver *driver)
+{
+ if (network->type == driver->type ||
+ driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
+ return TRUE;
+
+ return FALSE;
+}
+
static int network_probe(struct connman_element *element)
{
+ struct connman_network *network = element->network;
+ GSList *list;
+
+ DBG("element %p name %s", element, element->name);
+
+ if (network == NULL)
+ return -ENODEV;
+
+ for (list = driver_list; list; list = list->next) {
+ struct connman_network_driver *driver = list->data;
+
+ if (match_driver(network, driver) == FALSE)
+ continue;
+
+ DBG("driver %p name %s", driver, driver->name);
+
+ if (driver->probe(network) == 0) {
+ network->driver = driver;
+ break;
+ }
+ }
+
+ if (!network->driver)
+ return -ENODEV;
+
return 0;
}
static void network_remove(struct connman_element *element)
{
+ struct connman_network *network = element->network;
+
+ DBG("element %p name %s", element, element->name);
+
+ if (network == NULL)
+ return;
+
+ if (!network->driver)
+ return;
+
+ if (network->driver->remove)
+ network->driver->remove(network);
}
static struct connman_driver network_driver = {