5 * Copyright (C) 2007-2009 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
32 struct connman_network {
33 struct connman_element element;
34 enum connman_network_type type;
35 enum connman_network_protocol protocol;
36 connman_bool_t connected;
37 connman_bool_t remember;
38 connman_uint8_t strength;
43 struct connman_network_driver *driver;
46 connman_bool_t registered;
48 struct connman_device *device;
59 static DBusMessage *get_properties(DBusConnection *conn,
60 DBusMessage *msg, void *data)
62 struct connman_network *network = data;
64 DBusMessageIter array, dict;
68 reply = dbus_message_new_method_return(msg);
72 dbus_message_iter_init_append(reply, &array);
74 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
75 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
76 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
77 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
79 if (network->device) {
80 const char *path = connman_device_get_path(network->device);
82 connman_dbus_dict_append_variant(&dict, "Device",
83 DBUS_TYPE_OBJECT_PATH, &path);
86 if (network->name != NULL)
87 connman_dbus_dict_append_variant(&dict, "Name",
88 DBUS_TYPE_STRING, &network->name);
90 connman_dbus_dict_append_variant(&dict, "Connected",
91 DBUS_TYPE_BOOLEAN, &network->connected);
93 connman_dbus_dict_append_variant(&dict, "Remember",
94 DBUS_TYPE_BOOLEAN, &network->remember);
96 if (network->strength > 0)
97 connman_dbus_dict_append_variant(&dict, "Strength",
98 DBUS_TYPE_BYTE, &network->strength);
100 if (network->wifi.ssid != NULL && network->wifi.ssid_len > 0)
101 connman_dbus_dict_append_array(&dict, "WiFi.SSID",
102 DBUS_TYPE_BYTE, &network->wifi.ssid,
103 network->wifi.ssid_len);
105 if (network->wifi.mode != NULL)
106 connman_dbus_dict_append_variant(&dict, "WiFi.Mode",
107 DBUS_TYPE_STRING, &network->wifi.mode);
109 if (network->wifi.security != NULL)
110 connman_dbus_dict_append_variant(&dict, "WiFi.Security",
111 DBUS_TYPE_STRING, &network->wifi.security);
113 if (network->wifi.passphrase != NULL)
114 connman_dbus_dict_append_variant(&dict, "WiFi.Passphrase",
115 DBUS_TYPE_STRING, &network->wifi.passphrase);
117 dbus_message_iter_close_container(&array, &dict);
122 static DBusMessage *set_property(DBusConnection *conn,
123 DBusMessage *msg, void *data)
125 struct connman_network *network = data;
126 DBusMessageIter iter, value;
129 DBG("conn %p", conn);
131 if (dbus_message_iter_init(msg, &iter) == FALSE)
132 return __connman_error_invalid_arguments(msg);
134 dbus_message_iter_get_basic(&iter, &name);
135 dbus_message_iter_next(&iter);
136 dbus_message_iter_recurse(&iter, &value);
138 if (__connman_security_check_privileges(msg) < 0)
139 return __connman_error_permission_denied(msg);
141 if (g_str_equal(name, "Remember") == TRUE) {
142 connman_bool_t remember;
144 dbus_message_iter_get_basic(&value, &remember);
146 if (network->remember == remember)
147 return __connman_error_invalid_arguments(msg);
148 } else if (g_str_equal(name, "WiFi.Passphrase") == TRUE) {
149 const char *passphrase;
151 dbus_message_iter_get_basic(&value, &passphrase);
153 g_free(network->wifi.passphrase);
154 network->wifi.passphrase = g_strdup(passphrase);
157 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
160 static DBusMessage *do_connect(DBusConnection *conn,
161 DBusMessage *msg, void *data)
163 struct connman_network *network = data;
166 DBG("conn %p", conn);
168 if (network->driver && network->driver->connect) {
169 err = network->driver->connect(network);
170 if (err < 0 && err != -EINPROGRESS)
171 return __connman_error_failed(msg);
174 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
177 static DBusMessage *do_disconnect(DBusConnection *conn,
178 DBusMessage *msg, void *data)
180 struct connman_network *network = data;
183 DBG("conn %p", conn);
185 if (network->driver && network->driver->disconnect) {
186 err = network->driver->disconnect(network);
187 if (err < 0 && err != -EINPROGRESS)
188 return __connman_error_failed(msg);
191 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
194 static GDBusMethodTable network_methods[] = {
195 { "GetProperties", "", "a{sv}", get_properties },
196 { "SetProperty", "sv", "", set_property },
197 { "Connect", "", "", do_connect },
198 { "Disconnect", "", "", do_disconnect },
202 static GDBusSignalTable network_signals[] = {
203 { "PropertyChanged", "sv" },
207 static DBusConnection *connection;
209 static void emit_networks_signal(void)
213 static int register_interface(struct connman_element *element)
215 struct connman_network *network = element->network;
217 DBG("element %p name %s", element, element->name);
219 if (g_dbus_register_interface(connection, element->path,
220 CONNMAN_NETWORK_INTERFACE,
221 network_methods, network_signals,
222 NULL, network, NULL) == FALSE) {
223 connman_error("Failed to register %s network", element->path);
227 network->registered = TRUE;
229 emit_networks_signal();
234 static void unregister_interface(struct connman_element *element)
236 struct connman_network * network = element->network;
238 DBG("element %p name %s", element, element->name);
240 network->registered = FALSE;
242 emit_networks_signal();
244 g_dbus_unregister_interface(connection, element->path,
245 CONNMAN_NETWORK_INTERFACE);
248 connman_bool_t __connman_network_has_driver(struct connman_network *network)
250 if (network == NULL || network->driver == NULL)
253 return network->registered;
256 static GSList *driver_list = NULL;
258 static gint compare_priority(gconstpointer a, gconstpointer b)
260 const struct connman_network_driver *driver1 = a;
261 const struct connman_network_driver *driver2 = b;
263 return driver2->priority - driver1->priority;
267 * connman_network_driver_register:
268 * @driver: network driver definition
270 * Register a new network driver
272 * Returns: %0 on success
274 int connman_network_driver_register(struct connman_network_driver *driver)
276 DBG("driver %p name %s", driver, driver->name);
278 driver_list = g_slist_insert_sorted(driver_list, driver,
285 * connman_network_driver_unregister:
286 * @driver: network driver definition
288 * Remove a previously registered network driver
290 void connman_network_driver_unregister(struct connman_network_driver *driver)
292 DBG("driver %p name %s", driver, driver->name);
294 driver_list = g_slist_remove(driver_list, driver);
297 static void network_destruct(struct connman_element *element)
299 struct connman_network *network = element->network;
301 DBG("element %p name %s", element, element->name);
303 g_free(network->wifi.ssid);
304 g_free(network->wifi.mode);
305 g_free(network->wifi.security);
306 g_free(network->wifi.passphrase);
308 g_free(network->node);
309 g_free(network->name);
310 g_free(network->identifier);
314 * connman_network_create:
315 * @identifier: network identifier (for example an unqiue name)
317 * Allocate a new network and assign the #identifier to it.
319 * Returns: a newly-allocated #connman_network structure
321 struct connman_network *connman_network_create(const char *identifier,
322 enum connman_network_type type)
324 struct connman_network *network;
326 DBG("identifier %s type %d", identifier, type);
328 network = g_try_new0(struct connman_network, 1);
332 DBG("network %p", network);
334 network->element.refcount = 1;
336 network->element.name = g_strdup(identifier);
337 network->element.type = CONNMAN_ELEMENT_TYPE_NETWORK;
338 network->element.index = -1;
341 case CONNMAN_NETWORK_TYPE_UNKNOWN:
342 case CONNMAN_NETWORK_TYPE_VENDOR:
343 network->element.subtype = CONNMAN_ELEMENT_SUBTYPE_UNKNOWN;
345 case CONNMAN_NETWORK_TYPE_WIFI:
346 network->element.subtype = CONNMAN_ELEMENT_SUBTYPE_WIFI;
348 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
349 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
350 network->element.subtype = CONNMAN_ELEMENT_SUBTYPE_BLUETOOTH;
352 case CONNMAN_NETWORK_TYPE_HSO:
353 network->element.subtype = CONNMAN_ELEMENT_SUBTYPE_CELLULAR;
357 network->element.network = network;
358 network->element.destruct = network_destruct;
360 network->type = type;
361 network->identifier = g_strdup(identifier);
367 * connman_network_ref:
368 * @network: network structure
370 * Increase reference counter of network
372 struct connman_network *connman_network_ref(struct connman_network *network)
374 if (connman_element_ref(&network->element) == NULL)
381 * connman_network_unref:
382 * @network: network structure
384 * Decrease reference counter of network
386 void connman_network_unref(struct connman_network *network)
388 connman_element_unref(&network->element);
392 * connman_network_get_identifier:
393 * @network: network structure
395 * Get identifier of network
397 const char *connman_network_get_identifier(struct connman_network *network)
399 return network->identifier;
403 * connman_network_get_path:
404 * @network: network structure
406 * Get path name of network
408 const char *connman_network_get_path(struct connman_network *network)
410 return network->element.path;
414 * connman_network_set_index:
415 * @network: network structure
416 * @index: index number
418 * Set index number of network
420 void connman_network_set_index(struct connman_network *network, int index)
422 network->element.index = index;
426 * connman_network_get_index:
427 * @network: network structure
429 * Get index number of network
431 int connman_network_get_index(struct connman_network *network)
433 return network->element.index;
437 * connman_network_set_protocol:
438 * @network: network structure
439 * @protocol: network protocol
441 * Change protocol of network
443 void connman_network_set_protocol(struct connman_network *network,
444 enum connman_network_protocol protocol)
446 network->protocol = protocol;
450 * connman_network_set_connected:
451 * @network: network structure
452 * @connected: connected state
454 * Change connected state of network
456 int connman_network_set_connected(struct connman_network *network,
457 connman_bool_t connected)
459 DBG("network %p connected %d", network, connected);
461 if (network->connected == connected)
464 network->connected = connected;
466 if (connected == TRUE) {
467 struct connman_element *element;
468 enum connman_element_type type = CONNMAN_ELEMENT_TYPE_UNKNOWN;
470 switch (network->protocol) {
471 case CONNMAN_NETWORK_PROTOCOL_UNKNOWN:
473 case CONNMAN_NETWORK_PROTOCOL_IP:
474 type = CONNMAN_ELEMENT_TYPE_DHCP;
476 case CONNMAN_NETWORK_PROTOCOL_PPP:
477 type = CONNMAN_ELEMENT_TYPE_PPP;
481 element = connman_element_create(NULL);
482 if (element != NULL) {
483 element->type = type;
484 element->subtype = network->element.subtype;
485 element->index = network->element.index;
487 if (connman_element_register(element,
488 &network->element) < 0)
489 connman_element_unref(element);
492 connman_element_unregister_children(&network->element);
498 * connman_network_set_string:
499 * @network: network structure
500 * @key: unique identifier
501 * @value: string value
503 * Set string value for specific key
505 int connman_network_set_string(struct connman_network *network,
506 const char *key, const char *value)
508 DBG("network %p key %s value %s", network, key, value);
510 if (g_str_equal(key, "Name") == TRUE) {
511 g_free(network->name);
512 network->name = g_strdup(value);
513 } else if (g_str_equal(key, "Node") == TRUE) {
514 g_free(network->node);
515 network->node = g_strdup(value);
516 } else if (g_str_equal(key, "WiFi.Mode") == TRUE) {
517 g_free(network->wifi.mode);
518 network->wifi.mode = g_strdup(value);
519 } else if (g_str_equal(key, "WiFi.Security") == TRUE) {
520 g_free(network->wifi.security);
521 network->wifi.security = g_strdup(value);
528 * connman_network_get_string:
529 * @network: network structure
530 * @key: unique identifier
532 * Get string value for specific key
534 const char *connman_network_get_string(struct connman_network *network,
537 DBG("network %p key %s", network);
539 if (g_str_equal(key, "Name") == TRUE)
540 return network->name;
541 else if (g_str_equal(key, "Node") == TRUE)
542 return network->node;
543 else if (g_str_equal(key, "WiFi.Mode") == TRUE)
544 return network->wifi.mode;
545 else if (g_str_equal(key, "WiFi.Security") == TRUE)
546 return network->wifi.security;
552 * connman_network_set_uint8:
553 * @network: network structure
554 * @key: unique identifier
555 * @value: integer value
557 * Set integer value for specific key
559 int connman_network_set_uint8(struct connman_network *network,
560 const char *key, connman_uint8_t value)
562 DBG("network %p key %s value %d", network, key, value);
564 if (g_str_equal(key, "Strength") == TRUE)
565 network->strength = value;
571 * connman_network_set_blob:
572 * @network: network structure
573 * @key: unique identifier
577 * Set binary blob value for specific key
579 int connman_network_set_blob(struct connman_network *network,
580 const char *key, const void *data, unsigned int size)
582 DBG("network %p key %s size %d", network, key, size);
584 if (g_str_equal(key, "WiFi.SSID") == TRUE) {
585 g_free(network->wifi.ssid);
586 network->wifi.ssid = g_try_malloc(size);
587 if (network->wifi.ssid != NULL) {
588 memcpy(network->wifi.ssid, data, size);
589 network->wifi.ssid_len = size;
591 network->wifi.ssid_len = 0;
597 void __connman_network_set_device(struct connman_network *network,
598 struct connman_device *device)
600 network->device = device;
604 * connman_network_get_device:
605 * @network: network structure
607 * Get parent device of network
609 struct connman_device *connman_network_get_device(struct connman_network *network)
611 return network->device;
615 * connman_network_get_data:
616 * @network: network structure
618 * Get private network data pointer
620 void *connman_network_get_data(struct connman_network *network)
622 return network->driver_data;
626 * connman_network_set_data:
627 * @network: network structure
628 * @data: data pointer
630 * Set private network data pointer
632 void connman_network_set_data(struct connman_network *network, void *data)
634 network->driver_data = data;
637 static gboolean match_driver(struct connman_network *network,
638 struct connman_network_driver *driver)
640 if (network->type == driver->type ||
641 driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
647 static int network_probe(struct connman_element *element)
649 struct connman_network *network = element->network;
653 DBG("element %p name %s", element, element->name);
658 for (list = driver_list; list; list = list->next) {
659 struct connman_network_driver *driver = list->data;
661 if (match_driver(network, driver) == FALSE)
664 DBG("driver %p name %s", driver, driver->name);
666 if (driver->probe(network) == 0) {
667 network->driver = driver;
672 if (network->driver == NULL)
675 err = register_interface(element);
677 if (network->driver->remove)
678 network->driver->remove(network);
685 static void network_remove(struct connman_element *element)
687 struct connman_network *network = element->network;
689 DBG("element %p name %s", element, element->name);
694 if (network->driver == NULL)
697 unregister_interface(element);
699 if (network->driver->remove)
700 network->driver->remove(network);
703 static struct connman_driver network_driver = {
705 .type = CONNMAN_ELEMENT_TYPE_NETWORK,
706 .priority = CONNMAN_DRIVER_PRIORITY_LOW,
707 .probe = network_probe,
708 .remove = network_remove,
711 static int network_load(struct connman_network *network)
713 DBG("network %p", network);
718 static int network_save(struct connman_network *network)
720 DBG("network %p", network);
725 static struct connman_storage network_storage = {
727 .priority = CONNMAN_STORAGE_PRIORITY_LOW,
728 .network_load = network_load,
729 .network_save = network_save,
732 int __connman_network_init(void)
736 connection = connman_dbus_get_connection();
738 if (connman_storage_register(&network_storage) < 0)
739 connman_error("Failed to register network storage");
741 return connman_driver_register(&network_driver);
744 void __connman_network_cleanup(void)
748 connman_driver_unregister(&network_driver);
750 connman_storage_unregister(&network_storage);
752 dbus_connection_unref(connection);