5 * Copyright (C) 2007-2008 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 struct connman_network {
31 struct connman_element element;
32 enum connman_network_type type;
36 struct connman_network_driver *driver;
39 struct connman_device *device;
42 static DBusMessage *get_properties(DBusConnection *conn,
43 DBusMessage *msg, void *data)
45 struct connman_network *network = data;
47 DBusMessageIter array, dict;
51 reply = dbus_message_new_method_return(msg);
55 dbus_message_iter_init_append(reply, &array);
57 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
58 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
59 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
60 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
62 if (network->identifier != NULL)
63 connman_dbus_dict_append_variant(&dict, "Name",
64 DBUS_TYPE_STRING, &network->identifier);
66 dbus_message_iter_close_container(&array, &dict);
71 static DBusMessage *set_property(DBusConnection *conn,
72 DBusMessage *msg, void *data)
74 DBusMessageIter iter, value;
79 if (dbus_message_iter_init(msg, &iter) == FALSE)
80 return __connman_error_invalid_arguments(msg);
82 dbus_message_iter_get_basic(&iter, &name);
83 dbus_message_iter_next(&iter);
84 dbus_message_iter_recurse(&iter, &value);
86 if (__connman_security_check_privileges(msg) < 0)
87 return __connman_error_permission_denied(msg);
89 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
92 static DBusMessage *do_connect(DBusConnection *conn,
93 DBusMessage *msg, void *data)
95 struct connman_network *network = data;
100 if (network->driver && network->driver->connect) {
101 err = network->driver->connect(network);
102 if (err < 0 && err != -EINPROGRESS)
103 return __connman_error_failed(msg);
106 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
109 static DBusMessage *do_disconnect(DBusConnection *conn,
110 DBusMessage *msg, void *data)
112 struct connman_network *network = data;
115 DBG("conn %p", conn);
117 if (network->driver && network->driver->disconnect) {
118 err = network->driver->disconnect(network);
119 if (err < 0 && err != -EINPROGRESS)
120 return __connman_error_failed(msg);
123 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
126 static GDBusMethodTable network_methods[] = {
127 { "GetProperties", "", "a{sv}", get_properties },
128 { "SetProperty", "sv", "", set_property },
129 { "Connect", "", "", do_connect },
130 { "Disconnect", "", "", do_disconnect },
134 static GDBusSignalTable network_signals[] = {
135 { "PropertyChanged", "sv" },
139 static DBusConnection *connection;
141 static void emit_networks_signal(void)
145 static int register_interface(struct connman_element *element)
147 struct connman_network *network = element->network;
149 DBG("element %p name %s", element, element->name);
151 g_dbus_unregister_interface(connection, element->path,
152 CONNMAN_NETWORK_INTERFACE);
154 if (g_dbus_register_interface(connection, element->path,
155 CONNMAN_NETWORK_INTERFACE,
156 network_methods, network_signals,
157 NULL, network, NULL) == FALSE) {
158 connman_error("Failed to register %s network", element->path);
162 emit_networks_signal();
167 static void unregister_interface(struct connman_element *element)
169 DBG("element %p name %s", element, element->name);
171 emit_networks_signal();
173 g_dbus_unregister_interface(connection, element->path,
174 CONNMAN_NETWORK_INTERFACE);
177 static GSList *driver_list = NULL;
179 static gint compare_priority(gconstpointer a, gconstpointer b)
181 const struct connman_network_driver *driver1 = a;
182 const struct connman_network_driver *driver2 = b;
184 return driver2->priority - driver1->priority;
188 * connman_network_driver_register:
189 * @driver: network driver definition
191 * Register a new network driver
193 * Returns: %0 on success
195 int connman_network_driver_register(struct connman_network_driver *driver)
197 DBG("driver %p name %s", driver, driver->name);
199 driver_list = g_slist_insert_sorted(driver_list, driver,
206 * connman_network_driver_unregister:
207 * @driver: network driver definition
209 * Remove a previously registered network driver
211 void connman_network_driver_unregister(struct connman_network_driver *driver)
213 DBG("driver %p name %s", driver, driver->name);
215 driver_list = g_slist_remove(driver_list, driver);
218 static void network_destruct(struct connman_element *element)
220 struct connman_network *network = element->network;
222 DBG("element %p name %s", element, element->name);
224 g_free(network->path);
225 g_free(network->identifier);
229 * connman_network_create:
230 * @identifier: network identifier (for example an unqiue name)
232 * Allocate a new network and assign the #identifier to it.
234 * Returns: a newly-allocated #connman_network structure
236 struct connman_network *connman_network_create(const char *identifier,
237 enum connman_network_type type)
239 struct connman_network *network;
241 DBG("identifier %s type %d", identifier, type);
243 network = g_try_new0(struct connman_network, 1);
247 DBG("network %p", network);
249 network->element.refcount = 1;
251 network->element.name = g_strdup(identifier);
252 network->element.type = CONNMAN_ELEMENT_TYPE_NETWORK;
253 network->element.index = -1;
255 network->element.network = network;
256 network->element.destruct = network_destruct;
258 network->type = type;
259 network->identifier = g_strdup(identifier);
265 * connman_network_ref:
266 * @network: network structure
268 * Increase reference counter of network
270 struct connman_network *connman_network_ref(struct connman_network *network)
272 if (connman_element_ref(&network->element) == NULL)
279 * connman_network_unref:
280 * @network: network structure
282 * Decrease reference counter of network
284 void connman_network_unref(struct connman_network *network)
286 connman_element_unref(&network->element);
290 * connman_network_get_identifier:
291 * @network: network structure
293 * Get identifier of network
295 const char *connman_network_get_identifier(struct connman_network *network)
297 return network->identifier;
301 * connman_network_set_path:
302 * @network: network structure
305 * Set path name of network
307 void connman_network_set_path(struct connman_network *network, const char *path)
309 g_free(network->element.devpath);
310 network->element.devpath = g_strdup(path);
312 g_free(network->path);
313 network->path = g_strdup(path);
317 * connman_network_get_path:
318 * @network: network structure
320 * Get path name of network
322 const char *connman_network_get_path(struct connman_network *network)
324 return network->path;
327 void __connman_network_set_device(struct connman_network *network,
328 struct connman_device *device)
330 network->device = device;
334 * connman_network_get_device:
335 * @network: network structure
337 * Get parent device of network
339 struct connman_device *connman_network_get_device(struct connman_network *network)
341 return network->device;
345 * connman_network_get_data:
346 * @network: network structure
348 * Get private network data pointer
350 void *connman_network_get_data(struct connman_network *network)
352 return network->driver_data;
356 * connman_network_set_data:
357 * @network: network structure
358 * @data: data pointer
360 * Set private network data pointer
362 void connman_network_set_data(struct connman_network *network, void *data)
364 network->driver_data = data;
367 static gboolean match_driver(struct connman_network *network,
368 struct connman_network_driver *driver)
370 if (network->type == driver->type ||
371 driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
377 static int network_probe(struct connman_element *element)
379 struct connman_network *network = element->network;
383 DBG("element %p name %s", element, element->name);
388 for (list = driver_list; list; list = list->next) {
389 struct connman_network_driver *driver = list->data;
391 if (match_driver(network, driver) == FALSE)
394 DBG("driver %p name %s", driver, driver->name);
396 if (driver->probe(network) == 0) {
397 network->driver = driver;
402 if (network->driver == NULL)
405 err = register_interface(element);
407 if (network->driver->remove)
408 network->driver->remove(network);
415 static void network_remove(struct connman_element *element)
417 struct connman_network *network = element->network;
419 DBG("element %p name %s", element, element->name);
424 if (network->driver == NULL)
427 unregister_interface(element);
429 if (network->driver->remove)
430 network->driver->remove(network);
433 static struct connman_driver network_driver = {
435 .type = CONNMAN_ELEMENT_TYPE_NETWORK,
436 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
437 .probe = network_probe,
438 .remove = network_remove,
441 int __connman_network_init(void)
445 connection = connman_dbus_get_connection();
447 return connman_driver_register(&network_driver);
450 void __connman_network_cleanup(void)
454 connman_driver_unregister(&network_driver);
456 dbus_connection_unref(connection);