5 * Copyright (C) 2007-2014 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 #include <connman/acd.h>
31 #include "src/shared/arp.h"
34 * How many times to send RS with the purpose of
35 * refreshing RDNSS entries before they actually expire.
36 * With a value of 1, one RS will be sent, with no retries.
38 #define RS_REFRESH_COUNT 1
41 * Value in seconds to wait for RA after RS was sent.
42 * After this time elapsed, we can send another RS.
44 #define RS_REFRESH_TIMEOUT 3
47 * As per RFC 4861, a host should transmit up to MAX_RTR_SOLICITATIONS(3)
48 * Router Solicitation messages, each separated by at least
49 * RTR_SOLICITATION_INTERVAL(4) seconds to obtain RA for IPv6 auto-configuration.
51 #define RTR_SOLICITATION_INTERVAL 4
53 #define DHCP_RETRY_TIMEOUT 10
55 static GSList *network_list = NULL;
56 static GSList *driver_list = NULL;
58 struct connman_network {
60 enum connman_network_type type;
72 int router_solicit_count;
73 int router_solicit_refresh_count;
74 struct acd_host *acd_host;
78 struct connman_network_driver *driver;
84 struct connman_device *device;
90 unsigned short channel;
95 char *anonymous_identity;
99 char *altsubject_match;
100 char *domain_suffix_match;
102 char *client_cert_path;
103 char *private_key_path;
104 char *private_key_passphrase;
107 bool wps_advertizing;
114 static const char *type2string(enum connman_network_type type)
117 case CONNMAN_NETWORK_TYPE_UNKNOWN:
118 case CONNMAN_NETWORK_TYPE_VENDOR:
120 case CONNMAN_NETWORK_TYPE_ETHERNET:
122 case CONNMAN_NETWORK_TYPE_GADGET:
124 case CONNMAN_NETWORK_TYPE_WIFI:
126 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
127 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
129 case CONNMAN_NETWORK_TYPE_CELLULAR:
136 static bool match_driver(struct connman_network *network,
137 struct connman_network_driver *driver)
139 if (network->type == driver->type ||
140 driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN)
146 static void set_configuration(struct connman_network *network,
147 enum connman_ipconfig_type type)
149 struct connman_service *service;
151 DBG("network %p", network);
153 if (!network->device)
156 __connman_device_set_network(network->device, network);
158 service = connman_service_lookup_from_network(network);
159 __connman_service_ipconfig_indicate_state(service,
160 CONNMAN_SERVICE_STATE_CONFIGURATION,
164 void connman_network_append_acddbus(DBusMessageIter *dict,
165 struct connman_network *network)
167 if (!network->acd_host)
170 acd_host_append_dbus_property(network->acd_host, dict);
173 static int start_acd(struct connman_network *network);
175 static void remove_ipv4ll_timeout(struct connman_network *network)
177 if (network->ipv4ll_timeout > 0) {
178 g_source_remove(network->ipv4ll_timeout);
179 network->ipv4ll_timeout = 0;
183 static void acd_host_ipv4_available(struct acd_host *acd, gpointer user_data)
185 struct connman_network *network = user_data;
186 struct connman_service *service;
187 struct connman_ipconfig *ipconfig_ipv4;
193 service = connman_service_lookup_from_network(network);
197 ipconfig_ipv4 = __connman_service_get_ip4config(service);
198 if (!ipconfig_ipv4) {
199 connman_error("Service has no IPv4 configuration");
203 err = __connman_ipconfig_address_add(ipconfig_ipv4);
207 err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
211 __connman_service_save(service);
216 connman_network_set_error(__connman_service_get_network(service),
217 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
220 static int start_ipv4ll(struct connman_network *network)
222 struct connman_service *service;
223 struct connman_ipconfig *ipconfig_ipv4;
227 service = connman_service_lookup_from_network(network);
231 ipconfig_ipv4 = __connman_service_get_ip4config(service);
232 if (!ipconfig_ipv4) {
233 connman_error("Service has no IPv4 configuration");
237 /* Apply random IPv4 address. */
238 addr.s_addr = htonl(arp_random_ip());
239 address = inet_ntoa(addr);
241 connman_error("Could not convert IPv4LL random address %u",
245 __connman_ipconfig_set_local(ipconfig_ipv4, address);
247 connman_info("Probing IPv4LL address %s", address);
248 return start_acd(network);
251 static gboolean start_ipv4ll_ontimeout(gpointer data)
253 struct connman_network *network = data;
258 /* Start IPv4LL ACD. */
259 start_ipv4ll(network);
264 static void acd_host_ipv4_lost(struct acd_host *acd, gpointer user_data)
266 struct connman_network *network = user_data;
267 struct connman_service *service;
268 struct connman_ipconfig *ipconfig_ipv4;
269 enum connman_ipconfig_type type;
270 enum connman_ipconfig_method method;
275 service = connman_service_lookup_from_network(network);
279 ipconfig_ipv4 = __connman_service_get_ip4config(service);
280 if (!ipconfig_ipv4) {
281 connman_error("Service has no IPv4 configuration");
285 type = __connman_ipconfig_get_config_type(ipconfig_ipv4);
286 if (type != CONNMAN_IPCONFIG_TYPE_IPV4)
289 __connman_ipconfig_address_remove(ipconfig_ipv4);
291 method = __connman_ipconfig_get_method(ipconfig_ipv4);
292 if (method == CONNMAN_IPCONFIG_METHOD_DHCP) {
294 * We have one more chance for DHCP. If this fails
295 * acd_host_ipv4_conflict will be called.
297 network = __connman_service_get_network(service);
299 __connman_network_enable_ipconfig(network, ipconfig_ipv4);
301 /* Start IPv4LL ACD. */
302 start_ipv4ll(network);
306 static void acd_host_ipv4_conflict(struct acd_host *acd, gpointer user_data)
308 struct connman_network *network = user_data;
309 struct connman_service *service;
310 struct connman_ipconfig *ipconfig_ipv4;
311 enum connman_ipconfig_method method;
313 service = connman_service_lookup_from_network(network);
317 ipconfig_ipv4 = __connman_service_get_ip4config(service);
318 if (!ipconfig_ipv4) {
319 connman_error("Service has no IPv4 configuration");
323 method = __connman_ipconfig_get_method(ipconfig_ipv4);
324 connman_info("%s conflict counts=%u", __FUNCTION__,
325 acd_host_get_conflicts_count(acd));
327 if (method == CONNMAN_IPCONFIG_METHOD_DHCP &&
328 acd_host_get_conflicts_count(acd) < 2) {
329 connman_info("%s Sending DHCP decline", __FUNCTION__);
330 __connman_dhcp_decline(ipconfig_ipv4);
332 connman_network_set_connected_dhcp_later(network, DHCP_RETRY_TIMEOUT);
333 __connman_ipconfig_set_local(ipconfig_ipv4, NULL);
335 if (method == CONNMAN_IPCONFIG_METHOD_DHCP) {
336 __connman_ipconfig_set_method(ipconfig_ipv4,
337 CONNMAN_IPCONFIG_METHOD_AUTO);
338 __connman_dhcp_decline(ipconfig_ipv4);
340 /* Start IPv4LL ACD. */
341 start_ipv4ll(network);
345 static void acd_host_ipv4_maxconflict(struct acd_host *acd, gpointer user_data)
347 struct connman_network *network = user_data;
349 remove_ipv4ll_timeout(network);
350 connman_info("Had maximum number of conflicts. Next IPv4LL address will be "
351 "tried in %d seconds", RATE_LIMIT_INTERVAL);
352 /* Wait, then start IPv4LL ACD. */
353 network->ipv4ll_timeout =
354 g_timeout_add_seconds_full(G_PRIORITY_HIGH,
356 start_ipv4ll_ontimeout,
361 static int start_acd(struct connman_network *network)
363 struct connman_service *service;
364 struct connman_ipconfig *ipconfig_ipv4;
368 remove_ipv4ll_timeout(network);
370 service = connman_service_lookup_from_network(network);
374 ipconfig_ipv4 = __connman_service_get_ip4config(service);
375 if (!ipconfig_ipv4) {
376 connman_error("Service has no IPv4 configuration");
380 if (!network->acd_host) {
383 index = __connman_ipconfig_get_index(ipconfig_ipv4);
384 network->acd_host = acd_host_new(index,
385 connman_service_get_dbuspath(service));
386 if (!network->acd_host) {
387 connman_error("Could not create ACD data structure");
391 acd_host_register_event(network->acd_host,
392 ACD_HOST_EVENT_IPV4_AVAILABLE,
393 acd_host_ipv4_available, network);
394 acd_host_register_event(network->acd_host,
395 ACD_HOST_EVENT_IPV4_LOST,
396 acd_host_ipv4_lost, network);
397 acd_host_register_event(network->acd_host,
398 ACD_HOST_EVENT_IPV4_CONFLICT,
399 acd_host_ipv4_conflict, network);
400 acd_host_register_event(network->acd_host,
401 ACD_HOST_EVENT_IPV4_MAXCONFLICT,
402 acd_host_ipv4_maxconflict, network);
405 address = __connman_ipconfig_get_local(ipconfig_ipv4);
409 connman_info("Starting ACD for address %s", address);
410 if (inet_pton(AF_INET, address, &addr) != 1)
411 connman_error("Could not convert address %s", address);
413 acd_host_start(network->acd_host, htonl(addr.s_addr));
418 static void dhcp_success(struct connman_network *network)
420 struct connman_service *service;
421 struct connman_ipconfig *ipconfig_ipv4;
424 service = connman_service_lookup_from_network(network);
428 ipconfig_ipv4 = __connman_service_get_ip4config(service);
430 DBG("lease acquired for ipconfig %p", ipconfig_ipv4);
435 if (connman_setting_get_bool("AddressConflictDetection")) {
436 err = start_acd(network);
440 /* On error proceed without ACD. */
443 err = __connman_ipconfig_address_add(ipconfig_ipv4);
447 err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
451 __connman_service_save(service);
456 connman_network_set_error(network,
457 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
460 static void dhcp_failure(struct connman_network *network)
462 struct connman_service *service;
463 struct connman_ipconfig *ipconfig_ipv4;
465 service = connman_service_lookup_from_network(network);
469 ipconfig_ipv4 = __connman_service_get_ip4config(service);
471 DBG("lease lost for ipconfig %p", ipconfig_ipv4);
476 __connman_ipconfig_address_remove(ipconfig_ipv4);
477 __connman_ipconfig_gateway_remove(ipconfig_ipv4);
480 static void dhcp_callback(struct connman_ipconfig *ipconfig,
481 struct connman_network *network,
482 bool success, gpointer data)
484 network->connecting = false;
487 dhcp_success(network);
489 dhcp_failure(network);
492 static int set_connected_manual(struct connman_network *network)
495 struct connman_service *service;
496 struct connman_ipconfig *ipconfig;
498 DBG("network %p", network);
500 network->connecting = false;
502 service = connman_service_lookup_from_network(network);
503 ipconfig = __connman_service_get_ip4config(service);
504 __connman_ipconfig_enable(ipconfig);
506 if (!__connman_ipconfig_get_local(ipconfig))
507 __connman_service_read_ip4config(service);
509 if (connman_setting_get_bool("AddressConflictDetection")) {
510 err = start_acd(network);
514 /* On error proceed without ACD. */
517 err = __connman_ipconfig_address_add(ipconfig);
521 err = __connman_ipconfig_gateway_add(ipconfig);
529 static void remove_dhcp_timeout(struct connman_network *network)
531 if (network->dhcp_timeout > 0) {
532 g_source_remove(network->dhcp_timeout);
533 network->dhcp_timeout = 0;
537 static int set_connected_dhcp(struct connman_network *network)
539 struct connman_service *service;
540 struct connman_ipconfig *ipconfig_ipv4;
543 DBG("network %p", network);
544 remove_dhcp_timeout(network);
546 service = connman_service_lookup_from_network(network);
547 ipconfig_ipv4 = __connman_service_get_ip4config(service);
548 __connman_ipconfig_enable(ipconfig_ipv4);
550 err = __connman_dhcp_start(ipconfig_ipv4, network,
551 dhcp_callback, NULL);
553 connman_error("Can not request DHCP lease");
560 static gboolean set_connected_dhcp_timout(gpointer data)
562 struct connman_network *network = data;
563 struct connman_service *service;
564 struct connman_ipconfig *ipconfig;
565 enum connman_ipconfig_method method;
567 network->dhcp_timeout = 0;
569 service = connman_service_lookup_from_network(network);
573 ipconfig = __connman_service_get_ip4config(service);
577 /* Method is still DHCP? */
578 method = __connman_ipconfig_get_method(ipconfig);
579 if (method == CONNMAN_IPCONFIG_METHOD_DHCP)
580 set_connected_dhcp(network);
585 void connman_network_set_connected_dhcp_later(struct connman_network *network,
588 remove_dhcp_timeout(network);
590 network->dhcp_timeout =
591 g_timeout_add_seconds_full(G_PRIORITY_HIGH,
593 set_connected_dhcp_timout,
598 static int manual_ipv6_set(struct connman_network *network,
599 struct connman_ipconfig *ipconfig_ipv6)
601 struct connman_service *service;
604 DBG("network %p ipv6 %p", network, ipconfig_ipv6);
606 service = connman_service_lookup_from_network(network);
610 if (!__connman_ipconfig_get_local(ipconfig_ipv6))
611 __connman_service_read_ip6config(service);
613 __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
615 err = __connman_ipconfig_address_add(ipconfig_ipv6);
617 connman_network_set_error(network,
618 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
622 err = __connman_ipconfig_gateway_add(ipconfig_ipv6);
626 __connman_device_set_network(network->device, network);
628 connman_network_set_associating(network, false);
630 network->connecting = false;
635 static void stop_dhcpv6(struct connman_network *network)
637 network->connecting = false;
639 __connman_dhcpv6_stop(network);
642 static void dhcpv6_release_callback(struct connman_network *network,
643 enum __connman_dhcpv6_status status,
646 DBG("status %d", status);
648 stop_dhcpv6(network);
651 static void release_dhcpv6(struct connman_network *network)
653 __connman_dhcpv6_start_release(network, dhcpv6_release_callback);
654 stop_dhcpv6(network);
657 static void dhcpv6_info_callback(struct connman_network *network,
658 enum __connman_dhcpv6_status status,
661 DBG("status %d", status);
663 stop_dhcpv6(network);
666 static int dhcpv6_set_addresses(struct connman_network *network)
668 struct connman_service *service;
669 struct connman_ipconfig *ipconfig_ipv6;
672 service = connman_service_lookup_from_network(network);
676 network->connecting = false;
678 ipconfig_ipv6 = __connman_service_get_ip6config(service);
679 err = __connman_ipconfig_address_add(ipconfig_ipv6);
686 connman_network_set_error(network,
687 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
691 static void autoconf_ipv6_set(struct connman_network *network);
692 static void dhcpv6_callback(struct connman_network *network,
693 enum __connman_dhcpv6_status status, gpointer data);
696 * Have a separate callback for renew so that we do not do autoconf
697 * in wrong phase as the dhcpv6_callback() is also called when doing
698 * DHCPv6 solicitation.
700 static void dhcpv6_renew_callback(struct connman_network *network,
701 enum __connman_dhcpv6_status status,
705 case CONNMAN_DHCPV6_STATUS_SUCCEED:
706 dhcpv6_callback(network, status, data);
708 case CONNMAN_DHCPV6_STATUS_FAIL:
709 case CONNMAN_DHCPV6_STATUS_RESTART:
710 stop_dhcpv6(network);
712 /* restart and do solicit again. */
713 autoconf_ipv6_set(network);
718 static void dhcpv6_callback(struct connman_network *network,
719 enum __connman_dhcpv6_status status, gpointer data)
721 DBG("status %d", status);
723 /* Start the renew process if necessary */
724 if (status == CONNMAN_DHCPV6_STATUS_SUCCEED) {
726 if (dhcpv6_set_addresses(network) < 0) {
727 stop_dhcpv6(network);
731 if (__connman_dhcpv6_start_renew(network,
732 dhcpv6_renew_callback) == -ETIMEDOUT)
733 dhcpv6_renew_callback(network,
734 CONNMAN_DHCPV6_STATUS_FAIL,
737 } else if (status == CONNMAN_DHCPV6_STATUS_RESTART) {
738 stop_dhcpv6(network);
739 autoconf_ipv6_set(network);
741 stop_dhcpv6(network);
744 static void check_dhcpv6(struct nd_router_advert *reply,
745 unsigned int length, void *user_data)
747 struct connman_network *network = user_data;
748 struct connman_service *service;
751 DBG("reply %p", reply);
755 * Router solicitation message seem to get lost easily so
756 * try to send it again.
758 if (network->router_solicit_count > 0) {
759 DBG("re-send router solicitation %d",
760 network->router_solicit_count);
761 network->router_solicit_count--;
762 __connman_inet_ipv6_send_rs(network->index, RTR_SOLICITATION_INTERVAL,
763 check_dhcpv6, network);
766 connman_network_unref(network);
770 network->router_solicit_count = 0;
773 * If we were disconnected while waiting router advertisement,
774 * we just quit and do not start DHCPv6
776 if (!network->connected) {
777 connman_network_unref(network);
781 prefixes = __connman_inet_ipv6_get_prefixes(reply, length);
784 * If IPv6 config is missing from service, then create it.
785 * The ipconfig might be missing if we got a rtnl message
786 * that disabled IPv6 config and thus removed it. This
787 * can happen if we are switching from one service to
788 * another in the same interface. The only way to get IPv6
789 * config back is to re-create it here.
791 service = connman_service_lookup_from_network(network);
793 connman_service_create_ip6config(service, network->index);
795 connman_network_set_associating(network, false);
797 __connman_service_ipconfig_indicate_state(service,
798 CONNMAN_SERVICE_STATE_CONFIGURATION,
799 CONNMAN_IPCONFIG_TYPE_IPV6);
803 * We do stateful/stateless DHCPv6 if router advertisement says so.
805 if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) {
806 __connman_dhcpv6_start(network, prefixes, dhcpv6_callback);
808 if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER)
809 __connman_dhcpv6_start_info(network,
810 dhcpv6_info_callback);
812 g_slist_free_full(prefixes, g_free);
813 network->connecting = false;
816 connman_network_unref(network);
819 static void receive_refresh_rs_reply(struct nd_router_advert *reply,
820 unsigned int length, void *user_data)
822 struct connman_network *network = user_data;
824 DBG("reply %p", reply);
828 * Router solicitation message seem to get lost easily so
829 * try to send it again.
831 if (network->router_solicit_refresh_count > 1) {
832 network->router_solicit_refresh_count--;
833 DBG("re-send router solicitation %d",
834 network->router_solicit_refresh_count);
835 __connman_inet_ipv6_send_rs(network->index,
837 receive_refresh_rs_reply,
843 /* RS refresh not in progress anymore */
844 network->router_solicit_refresh_count = 0;
846 connman_network_unref(network);
849 int __connman_network_refresh_rs_ipv6(struct connman_network *network,
854 DBG("network %p index %d", network, index);
856 /* Send only one RS for all RDNSS entries which are about to expire */
857 if (network->router_solicit_refresh_count > 0) {
858 DBG("RS refresh already started");
862 network->router_solicit_refresh_count = RS_REFRESH_COUNT;
864 connman_network_ref(network);
866 ret = __connman_inet_ipv6_send_rs(index, RS_REFRESH_TIMEOUT,
867 receive_refresh_rs_reply, network);
871 static void autoconf_ipv6_set(struct connman_network *network)
873 struct connman_service *service;
874 struct connman_ipconfig *ipconfig;
877 DBG("network %p", network);
879 if (network->router_solicit_count > 0) {
881 * The autoconfiguration is already pending and we have sent
882 * router solicitation messages and are now waiting answers.
883 * There is no need to continue any further.
885 DBG("autoconfiguration already started");
889 __connman_device_set_network(network->device, network);
891 service = connman_service_lookup_from_network(network);
895 ipconfig = __connman_service_get_ip6config(service);
899 __connman_ipconfig_enable(ipconfig);
901 __connman_ipconfig_enable_ipv6(ipconfig);
903 __connman_ipconfig_address_remove(ipconfig);
905 index = __connman_ipconfig_get_index(ipconfig);
907 connman_network_ref(network);
909 /* Try to get stateless DHCPv6 information, RFC 3736 */
910 network->router_solicit_count = 3;
911 __connman_inet_ipv6_send_rs(index, RTR_SOLICITATION_INTERVAL,
912 check_dhcpv6, network);
915 static void set_connected(struct connman_network *network)
917 struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
918 struct connman_service *service;
920 if (network->connected)
923 connman_network_set_associating(network, false);
925 network->connected = true;
927 service = connman_service_lookup_from_network(network);
929 ipconfig_ipv4 = __connman_service_get_ip4config(service);
930 ipconfig_ipv6 = __connman_service_get_ip6config(service);
932 DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
935 __connman_network_enable_ipconfig(network, ipconfig_ipv4);
936 __connman_network_enable_ipconfig(network, ipconfig_ipv6);
939 static void set_disconnected(struct connman_network *network)
941 struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6;
942 enum connman_ipconfig_method ipv4_method, ipv6_method;
943 enum connman_service_state state;
944 struct connman_service *service;
946 service = connman_service_lookup_from_network(network);
948 ipconfig_ipv4 = __connman_service_get_ip4config(service);
949 ipconfig_ipv6 = __connman_service_get_ip6config(service);
951 DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4,
954 ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4);
955 ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6);
957 DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method);
960 * Resetting solicit count here will prevent the RS resend loop
961 * from sending packets in check_dhcpv6()
963 network->router_solicit_count = 0;
965 __connman_device_set_network(network->device, NULL);
967 if (network->connected) {
968 switch (ipv6_method) {
969 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
970 case CONNMAN_IPCONFIG_METHOD_OFF:
971 case CONNMAN_IPCONFIG_METHOD_FIXED:
972 case CONNMAN_IPCONFIG_METHOD_MANUAL:
974 case CONNMAN_IPCONFIG_METHOD_DHCP:
975 case CONNMAN_IPCONFIG_METHOD_AUTO:
976 release_dhcpv6(network);
980 switch (ipv4_method) {
981 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
982 case CONNMAN_IPCONFIG_METHOD_OFF:
983 case CONNMAN_IPCONFIG_METHOD_FIXED:
984 case CONNMAN_IPCONFIG_METHOD_MANUAL:
986 case CONNMAN_IPCONFIG_METHOD_AUTO:
988 * If the current method is AUTO then next time we
989 * try first DHCP. DHCP also needs to be stopped
990 * in this case because if we fell in AUTO means
991 * that DHCP was launched for IPv4 but it failed.
993 __connman_ipconfig_set_method(ipconfig_ipv4,
994 CONNMAN_IPCONFIG_METHOD_DHCP);
995 __connman_service_notify_ipv4_configuration(service);
997 case CONNMAN_IPCONFIG_METHOD_DHCP:
998 remove_dhcp_timeout(network);
999 __connman_dhcp_stop(ipconfig_ipv4);
1005 * We only set the disconnect state if we were not in idle
1006 * or in failure. It does not make sense to go to disconnect
1007 * state if we were not connected.
1009 state = __connman_service_ipconfig_get_state(service,
1010 CONNMAN_IPCONFIG_TYPE_IPV4);
1011 if (state != CONNMAN_SERVICE_STATE_IDLE &&
1012 state != CONNMAN_SERVICE_STATE_FAILURE)
1013 __connman_service_ipconfig_indicate_state(service,
1014 CONNMAN_SERVICE_STATE_DISCONNECT,
1015 CONNMAN_IPCONFIG_TYPE_IPV4);
1017 state = __connman_service_ipconfig_get_state(service,
1018 CONNMAN_IPCONFIG_TYPE_IPV6);
1019 if (state != CONNMAN_SERVICE_STATE_IDLE &&
1020 state != CONNMAN_SERVICE_STATE_FAILURE)
1021 __connman_service_ipconfig_indicate_state(service,
1022 CONNMAN_SERVICE_STATE_DISCONNECT,
1023 CONNMAN_IPCONFIG_TYPE_IPV6);
1025 if (network->connected) {
1026 __connman_connection_gateway_remove(service,
1027 CONNMAN_IPCONFIG_TYPE_ALL);
1029 __connman_ipconfig_address_unset(ipconfig_ipv4);
1030 __connman_ipconfig_address_unset(ipconfig_ipv6);
1033 * Special handling for IPv6 autoconfigured address.
1034 * The simplest way to remove autoconfigured routes is to
1035 * disable IPv6 temporarily so that kernel will do the cleanup
1038 if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) {
1039 __connman_ipconfig_disable_ipv6(ipconfig_ipv6);
1040 __connman_ipconfig_enable_ipv6(ipconfig_ipv6);
1044 __connman_service_ipconfig_indicate_state(service,
1045 CONNMAN_SERVICE_STATE_IDLE,
1046 CONNMAN_IPCONFIG_TYPE_IPV4);
1048 __connman_service_ipconfig_indicate_state(service,
1049 CONNMAN_SERVICE_STATE_IDLE,
1050 CONNMAN_IPCONFIG_TYPE_IPV6);
1052 network->connecting = false;
1053 network->connected = false;
1055 connman_network_set_associating(network, false);
1060 static int network_probe(struct connman_network *network)
1063 struct connman_network_driver *driver = NULL;
1065 DBG("network %p name %s", network, network->name);
1067 if (network->driver)
1070 for (list = driver_list; list; list = list->next) {
1071 driver = list->data;
1073 if (!match_driver(network, driver)) {
1078 DBG("driver %p name %s", driver, driver->name);
1080 if (driver->probe(network) == 0)
1089 if (!network->group)
1092 switch (network->type) {
1093 case CONNMAN_NETWORK_TYPE_UNKNOWN:
1094 case CONNMAN_NETWORK_TYPE_VENDOR:
1096 case CONNMAN_NETWORK_TYPE_ETHERNET:
1097 case CONNMAN_NETWORK_TYPE_GADGET:
1098 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1099 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1100 case CONNMAN_NETWORK_TYPE_CELLULAR:
1101 case CONNMAN_NETWORK_TYPE_WIFI:
1102 network->driver = driver;
1103 if (!__connman_service_create_from_network(network)) {
1104 network->driver = NULL;
1112 static void network_remove(struct connman_network *network)
1114 DBG("network %p name %s", network, network->name);
1116 if (!network->driver)
1119 if (network->connected)
1120 set_disconnected(network);
1122 switch (network->type) {
1123 case CONNMAN_NETWORK_TYPE_UNKNOWN:
1124 case CONNMAN_NETWORK_TYPE_VENDOR:
1126 case CONNMAN_NETWORK_TYPE_ETHERNET:
1127 case CONNMAN_NETWORK_TYPE_GADGET:
1128 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1129 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1130 case CONNMAN_NETWORK_TYPE_CELLULAR:
1131 case CONNMAN_NETWORK_TYPE_WIFI:
1132 if (network->group) {
1133 __connman_service_remove_from_network(network);
1135 g_free(network->group);
1136 network->group = NULL;
1141 if (network->driver->remove)
1142 network->driver->remove(network);
1144 network->driver = NULL;
1147 static void probe_driver(struct connman_network_driver *driver)
1151 DBG("driver %p name %s", driver, driver->name);
1153 for (list = network_list; list; list = list->next) {
1154 struct connman_network *network = list->data;
1156 if (network->driver)
1159 if (driver->type != network->type)
1162 if (driver->probe(network) < 0)
1165 network->driver = driver;
1169 static gint compare_priority(gconstpointer a, gconstpointer b)
1171 const struct connman_network_driver *driver1 = a;
1172 const struct connman_network_driver *driver2 = b;
1174 return driver2->priority - driver1->priority;
1178 * connman_network_driver_register:
1179 * @driver: network driver definition
1181 * Register a new network driver
1183 * Returns: %0 on success
1185 int connman_network_driver_register(struct connman_network_driver *driver)
1187 DBG("driver %p name %s", driver, driver->name);
1189 driver_list = g_slist_insert_sorted(driver_list, driver,
1192 probe_driver(driver);
1198 * connman_network_driver_unregister:
1199 * @driver: network driver definition
1201 * Remove a previously registered network driver
1203 void connman_network_driver_unregister(struct connman_network_driver *driver)
1207 DBG("driver %p name %s", driver, driver->name);
1209 driver_list = g_slist_remove(driver_list, driver);
1211 for (list = network_list; list; list = list->next) {
1212 struct connman_network *network = list->data;
1214 if (network->driver == driver)
1215 network_remove(network);
1219 static void network_destruct(struct connman_network *network)
1221 DBG("network %p name %s", network, network->name);
1223 g_free(network->wifi.ssid);
1224 g_free(network->wifi.mode);
1225 g_free(network->wifi.security);
1226 g_free(network->wifi.passphrase);
1227 g_free(network->wifi.eap);
1228 g_free(network->wifi.identity);
1229 g_free(network->wifi.anonymous_identity);
1230 g_free(network->wifi.agent_identity);
1231 g_free(network->wifi.ca_cert_path);
1232 g_free(network->wifi.subject_match);
1233 g_free(network->wifi.altsubject_match);
1234 g_free(network->wifi.domain_suffix_match);
1235 g_free(network->wifi.domain_match);
1236 g_free(network->wifi.client_cert_path);
1237 g_free(network->wifi.private_key_path);
1238 g_free(network->wifi.private_key_passphrase);
1239 g_free(network->wifi.phase2_auth);
1240 g_free(network->wifi.pin_wps);
1242 g_free(network->path);
1243 g_free(network->group);
1244 g_free(network->node);
1245 g_free(network->name);
1246 g_free(network->identifier);
1247 acd_host_free(network->acd_host);
1249 network->device = NULL;
1255 * connman_network_create:
1256 * @identifier: network identifier (for example an unique name)
1258 * Allocate a new network and assign the #identifier to it.
1260 * Returns: a newly-allocated #connman_network structure
1262 struct connman_network *connman_network_create(const char *identifier,
1263 enum connman_network_type type)
1265 struct connman_network *network;
1268 network = g_try_new0(struct connman_network, 1);
1272 network->refcount = 1;
1274 ident = g_strdup(identifier);
1281 network->type = type;
1282 network->identifier = ident;
1283 network->acd_host = NULL;
1284 network->ipv4ll_timeout = 0;
1286 network_list = g_slist_prepend(network_list, network);
1288 network->dhcp_timeout = 0;
1290 DBG("network %p identifier %s type %s", network, identifier,
1296 * connman_network_ref:
1297 * @network: network structure
1299 * Increase reference counter of network
1301 struct connman_network *
1302 connman_network_ref_debug(struct connman_network *network,
1303 const char *file, int line, const char *caller)
1305 DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
1306 network->refcount + 1, file, line, caller);
1308 __sync_fetch_and_add(&network->refcount, 1);
1314 * connman_network_unref:
1315 * @network: network structure
1317 * Decrease reference counter of network
1319 void connman_network_unref_debug(struct connman_network *network,
1320 const char *file, int line, const char *caller)
1322 DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
1323 network->refcount - 1, file, line, caller);
1325 if (__sync_fetch_and_sub(&network->refcount, 1) != 1)
1328 network_list = g_slist_remove(network_list, network);
1330 network_destruct(network);
1333 const char *__connman_network_get_type(struct connman_network *network)
1335 return type2string(network->type);
1339 * connman_network_get_type:
1340 * @network: network structure
1342 * Get type of network
1344 enum connman_network_type connman_network_get_type(
1345 struct connman_network *network)
1347 return network->type;
1351 * connman_network_get_identifier:
1352 * @network: network structure
1354 * Get identifier of network
1356 const char *connman_network_get_identifier(struct connman_network *network)
1358 return network->identifier;
1362 * connman_network_set_index:
1363 * @network: network structure
1364 * @index: index number
1366 * Set index number of network
1368 void connman_network_set_index(struct connman_network *network, int index)
1370 struct connman_service *service;
1371 struct connman_ipconfig *ipconfig;
1373 service = connman_service_lookup_from_network(network);
1377 ipconfig = __connman_service_get_ip4config(service);
1379 __connman_ipconfig_set_index(ipconfig, index);
1381 DBG("index %d service %p ip4config %p", network->index,
1385 ipconfig = __connman_service_get_ip6config(service);
1387 __connman_ipconfig_set_index(ipconfig, index);
1389 DBG("index %d service %p ip6config %p", network->index,
1394 network->index = index;
1398 * connman_network_get_index:
1399 * @network: network structure
1401 * Get index number of network
1403 int connman_network_get_index(struct connman_network *network)
1405 return network->index;
1409 * connman_network_set_group:
1410 * @network: network structure
1411 * @group: group name
1413 * Set group name for automatic clustering
1415 void connman_network_set_group(struct connman_network *network,
1418 switch (network->type) {
1419 case CONNMAN_NETWORK_TYPE_UNKNOWN:
1420 case CONNMAN_NETWORK_TYPE_VENDOR:
1422 case CONNMAN_NETWORK_TYPE_ETHERNET:
1423 case CONNMAN_NETWORK_TYPE_GADGET:
1424 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1425 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1426 case CONNMAN_NETWORK_TYPE_CELLULAR:
1427 case CONNMAN_NETWORK_TYPE_WIFI:
1431 if (g_strcmp0(network->group, group) == 0) {
1433 __connman_service_update_from_network(network);
1437 if (network->group) {
1438 __connman_service_remove_from_network(network);
1440 g_free(network->group);
1443 network->group = g_strdup(group);
1446 network_probe(network);
1450 * connman_network_get_group:
1451 * @network: network structure
1453 * Get group name for automatic clustering
1455 const char *connman_network_get_group(struct connman_network *network)
1457 return network->group;
1460 const char *__connman_network_get_ident(struct connman_network *network)
1462 if (!network->device)
1465 return connman_device_get_ident(network->device);
1468 bool __connman_network_get_weakness(struct connman_network *network)
1470 switch (network->type) {
1471 case CONNMAN_NETWORK_TYPE_UNKNOWN:
1472 case CONNMAN_NETWORK_TYPE_VENDOR:
1473 case CONNMAN_NETWORK_TYPE_ETHERNET:
1474 case CONNMAN_NETWORK_TYPE_GADGET:
1475 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
1476 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
1477 case CONNMAN_NETWORK_TYPE_CELLULAR:
1479 case CONNMAN_NETWORK_TYPE_WIFI:
1480 if (network->strength > 0 && network->strength < 20)
1488 bool connman_network_get_connecting(struct connman_network *network)
1490 return network->connecting;
1494 * connman_network_set_available:
1495 * @network: network structure
1496 * @available: availability state
1498 * Change availability state of network (in range)
1500 int connman_network_set_available(struct connman_network *network,
1503 DBG("network %p available %d", network, available);
1505 if (network->available == available)
1508 network->available = available;
1514 * connman_network_get_available:
1515 * @network: network structure
1517 * Get network available setting
1519 bool connman_network_get_available(struct connman_network *network)
1521 return network->available;
1525 * connman_network_set_associating:
1526 * @network: network structure
1527 * @associating: associating state
1529 * Change associating state of network
1531 int connman_network_set_associating(struct connman_network *network,
1534 DBG("network %p associating %d", network, associating);
1536 if (network->associating == associating)
1539 network->associating = associating;
1542 struct connman_service *service;
1544 service = connman_service_lookup_from_network(network);
1545 __connman_service_ipconfig_indicate_state(service,
1546 CONNMAN_SERVICE_STATE_ASSOCIATION,
1547 CONNMAN_IPCONFIG_TYPE_IPV4);
1548 __connman_service_ipconfig_indicate_state(service,
1549 CONNMAN_SERVICE_STATE_ASSOCIATION,
1550 CONNMAN_IPCONFIG_TYPE_IPV6);
1556 static void set_associate_error(struct connman_network *network)
1558 struct connman_service *service;
1560 service = connman_service_lookup_from_network(network);
1562 __connman_service_indicate_error(service,
1563 CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1566 static void set_configure_error(struct connman_network *network)
1568 struct connman_service *service;
1570 service = connman_service_lookup_from_network(network);
1572 __connman_service_indicate_error(service,
1573 CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1576 static void set_invalid_key_error(struct connman_network *network)
1578 struct connman_service *service;
1580 service = connman_service_lookup_from_network(network);
1582 __connman_service_indicate_error(service,
1583 CONNMAN_SERVICE_ERROR_INVALID_KEY);
1586 static void set_connect_error(struct connman_network *network)
1588 struct connman_service *service;
1590 service = connman_service_lookup_from_network(network);
1592 __connman_service_indicate_error(service,
1593 CONNMAN_SERVICE_ERROR_CONNECT_FAILED);
1596 static void set_blocked_error(struct connman_network *network)
1598 struct connman_service *service;
1600 service = connman_service_lookup_from_network(network);
1602 __connman_service_indicate_error(service,
1603 CONNMAN_SERVICE_ERROR_BLOCKED);
1606 void connman_network_set_ipv4_method(struct connman_network *network,
1607 enum connman_ipconfig_method method)
1609 struct connman_service *service;
1610 struct connman_ipconfig *ipconfig;
1612 service = connman_service_lookup_from_network(network);
1616 ipconfig = __connman_service_get_ip4config(service);
1620 __connman_ipconfig_set_method(ipconfig, method);
1623 void connman_network_set_ipv6_method(struct connman_network *network,
1624 enum connman_ipconfig_method method)
1626 struct connman_service *service;
1627 struct connman_ipconfig *ipconfig;
1629 service = connman_service_lookup_from_network(network);
1633 ipconfig = __connman_service_get_ip6config(service);
1637 __connman_ipconfig_set_method(ipconfig, method);
1640 void connman_network_set_error(struct connman_network *network,
1641 enum connman_network_error error)
1643 DBG("network %p error %d", network, error);
1646 case CONNMAN_NETWORK_ERROR_UNKNOWN:
1648 case CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL:
1649 set_associate_error(network);
1651 case CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL:
1652 set_configure_error(network);
1654 case CONNMAN_NETWORK_ERROR_INVALID_KEY:
1655 set_invalid_key_error(network);
1657 case CONNMAN_NETWORK_ERROR_CONNECT_FAIL:
1658 set_connect_error(network);
1660 case CONNMAN_NETWORK_ERROR_BLOCKED:
1661 set_blocked_error(network);
1665 __connman_network_disconnect(network);
1669 * connman_network_set_connected:
1670 * @network: network structure
1671 * @connected: connected state
1673 * Change connected state of network
1675 int connman_network_set_connected(struct connman_network *network,
1678 DBG("network %p connected %d/%d connecting %d associating %d",
1679 network, network->connected, connected, network->connecting,
1680 network->associating);
1682 if ((network->connecting || network->associating) &&
1684 connman_network_set_error(network,
1685 CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
1689 if (network->connected == connected)
1693 set_disconnected(network);
1695 set_connected(network);
1701 * connman_network_get_connected:
1702 * @network: network structure
1704 * Get network connection status
1706 bool connman_network_get_connected(struct connman_network *network)
1708 return network->connected;
1712 * connman_network_get_associating:
1713 * @network: network structure
1715 * Get network associating status
1717 bool connman_network_get_associating(struct connman_network *network)
1719 return network->associating;
1722 void connman_network_clear_hidden(void *user_data)
1727 DBG("user_data %p", user_data);
1730 * Hidden service does not have a connect timeout so
1731 * we do not need to remove it. We can just return
1732 * error to the caller telling that we could not find
1733 * any network that we could connect to.
1735 connman_dbus_reply_pending(user_data, EIO, NULL);
1738 int connman_network_connect_hidden(struct connman_network *network,
1739 char *identity, char *passphrase, void *user_data)
1742 struct connman_service *service;
1744 service = connman_service_lookup_from_network(network);
1746 DBG("network %p service %p user_data %p", network, service, user_data);
1752 __connman_service_set_agent_identity(service, identity);
1755 err = __connman_service_set_passphrase(service, passphrase);
1757 if (err == -ENOKEY) {
1758 __connman_service_indicate_error(service,
1759 CONNMAN_SERVICE_ERROR_INVALID_KEY);
1762 __connman_service_set_hidden(service);
1763 __connman_service_set_hidden_data(service, user_data);
1764 return __connman_service_connect(service,
1765 CONNMAN_SERVICE_CONNECT_REASON_USER);
1769 __connman_service_return_error(service, -err, user_data);
1774 * __connman_network_connect:
1775 * @network: network structure
1779 int __connman_network_connect(struct connman_network *network)
1783 DBG("network %p", network);
1785 if (network->connected)
1788 if (network->connecting || network->associating)
1791 if (!network->driver)
1794 if (!network->driver->connect)
1797 if (!network->device)
1800 __connman_device_disconnect(network->device);
1802 network->connecting = true;
1804 err = network->driver->connect(network);
1806 if (err == -EINPROGRESS)
1807 connman_network_set_associating(network, true);
1809 network->connecting = false;
1814 set_connected(network);
1820 * __connman_network_disconnect:
1821 * @network: network structure
1823 * Disconnect network
1825 int __connman_network_disconnect(struct connman_network *network)
1829 DBG("network %p", network);
1831 remove_ipv4ll_timeout(network);
1832 if (network->acd_host)
1833 acd_host_stop(network->acd_host);
1835 if (!network->connected && !network->connecting &&
1836 !network->associating)
1839 if (!network->driver)
1842 network->connecting = false;
1844 if (network->driver->disconnect)
1845 err = network->driver->disconnect(network);
1847 if (err != -EINPROGRESS)
1848 set_disconnected(network);
1853 int __connman_network_clear_ipconfig(struct connman_network *network,
1854 struct connman_ipconfig *ipconfig)
1856 struct connman_service *service;
1857 struct connman_ipconfig *ipconfig_ipv4;
1858 enum connman_ipconfig_method method;
1859 enum connman_ipconfig_type type;
1861 service = connman_service_lookup_from_network(network);
1865 ipconfig_ipv4 = __connman_service_get_ip4config(service);
1866 method = __connman_ipconfig_get_method(ipconfig);
1867 type = __connman_ipconfig_get_config_type(ipconfig);
1870 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1871 case CONNMAN_IPCONFIG_METHOD_OFF:
1872 case CONNMAN_IPCONFIG_METHOD_FIXED:
1874 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1875 __connman_ipconfig_address_remove(ipconfig);
1877 case CONNMAN_IPCONFIG_METHOD_AUTO:
1878 release_dhcpv6(network);
1879 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1882 case CONNMAN_IPCONFIG_METHOD_DHCP:
1883 remove_dhcp_timeout(network);
1884 __connman_dhcp_stop(ipconfig_ipv4);
1888 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1889 __connman_service_ipconfig_indicate_state(service,
1890 CONNMAN_SERVICE_STATE_CONFIGURATION,
1891 CONNMAN_IPCONFIG_TYPE_IPV6);
1892 else if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1893 __connman_service_ipconfig_indicate_state(service,
1894 CONNMAN_SERVICE_STATE_CONFIGURATION,
1895 CONNMAN_IPCONFIG_TYPE_IPV4);
1900 int __connman_network_enable_ipconfig(struct connman_network *network,
1901 struct connman_ipconfig *ipconfig)
1904 enum connman_ipconfig_type type;
1905 enum connman_ipconfig_method method;
1907 if (!network || !ipconfig)
1910 type = __connman_ipconfig_get_config_type(ipconfig);
1913 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1914 case CONNMAN_IPCONFIG_TYPE_ALL:
1917 case CONNMAN_IPCONFIG_TYPE_IPV6:
1918 set_configuration(network, type);
1920 method = __connman_ipconfig_get_method(ipconfig);
1922 DBG("ipv6 ipconfig method %d", method);
1925 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1928 case CONNMAN_IPCONFIG_METHOD_OFF:
1929 __connman_ipconfig_disable_ipv6(ipconfig);
1932 case CONNMAN_IPCONFIG_METHOD_AUTO:
1933 autoconf_ipv6_set(network);
1936 case CONNMAN_IPCONFIG_METHOD_FIXED:
1937 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1938 r = manual_ipv6_set(network, ipconfig);
1941 case CONNMAN_IPCONFIG_METHOD_DHCP:
1948 case CONNMAN_IPCONFIG_TYPE_IPV4:
1949 set_configuration(network, type);
1951 method = __connman_ipconfig_get_method(ipconfig);
1953 DBG("ipv4 ipconfig method %d", method);
1956 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
1957 case CONNMAN_IPCONFIG_METHOD_OFF:
1960 case CONNMAN_IPCONFIG_METHOD_AUTO:
1964 case CONNMAN_IPCONFIG_METHOD_FIXED:
1965 case CONNMAN_IPCONFIG_METHOD_MANUAL:
1966 r = set_connected_manual(network);
1969 case CONNMAN_IPCONFIG_METHOD_DHCP:
1970 r = set_connected_dhcp(network);
1978 connman_network_set_error(network,
1979 CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
1984 int connman_network_set_ipaddress(struct connman_network *network,
1985 struct connman_ipaddress *ipaddress)
1987 struct connman_service *service;
1988 struct connman_ipconfig *ipconfig = NULL;
1990 DBG("network %p", network);
1992 service = connman_service_lookup_from_network(network);
1996 ipconfig = __connman_service_get_ipconfig(service, ipaddress->family);
2000 __connman_ipconfig_set_local(ipconfig, ipaddress->local);
2001 __connman_ipconfig_set_peer(ipconfig, ipaddress->peer);
2002 __connman_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast);
2003 __connman_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen);
2004 __connman_ipconfig_set_gateway(ipconfig, ipaddress->gateway);
2009 int connman_network_set_nameservers(struct connman_network *network,
2010 const char *nameservers)
2012 struct connman_service *service;
2013 char **nameservers_array;
2016 DBG("network %p nameservers %s", network, nameservers);
2018 service = connman_service_lookup_from_network(network);
2022 __connman_service_nameserver_clear(service);
2027 nameservers_array = g_strsplit(nameservers, " ", 0);
2029 for (i = 0; nameservers_array[i]; i++) {
2030 __connman_service_nameserver_append(service,
2031 nameservers_array[i], false);
2034 g_strfreev(nameservers_array);
2039 int connman_network_set_domain(struct connman_network *network,
2042 struct connman_service *service;
2044 DBG("network %p domain %s", network, domain);
2046 service = connman_service_lookup_from_network(network);
2050 __connman_service_set_domainname(service, domain);
2056 * connman_network_set_name:
2057 * @network: network structure
2060 * Set display name value for network
2062 int connman_network_set_name(struct connman_network *network,
2065 DBG("network %p name %s", network, name);
2067 g_free(network->name);
2068 network->name = g_strdup(name);
2074 * connman_network_set_strength:
2075 * @network: network structure
2076 * @strength: strength value
2078 * Set signal strength value for network
2081 int connman_network_set_strength(struct connman_network *network,
2084 network->strength = strength;
2089 uint8_t connman_network_get_strength(struct connman_network *network)
2091 return network->strength;
2094 int connman_network_set_frequency(struct connman_network *network,
2097 network->frequency = frequency;
2102 uint16_t connman_network_get_frequency(struct connman_network *network)
2104 return network->frequency;
2107 int connman_network_set_wifi_channel(struct connman_network *network,
2110 network->wifi.channel = channel;
2115 uint16_t connman_network_get_wifi_channel(struct connman_network *network)
2117 return network->wifi.channel;
2121 * connman_network_set_string:
2122 * @network: network structure
2123 * @key: unique identifier
2124 * @value: string value
2126 * Set string value for specific key
2128 int connman_network_set_string(struct connman_network *network,
2129 const char *key, const char *value)
2131 if (g_strcmp0(key, "Name") == 0)
2132 return connman_network_set_name(network, value);
2134 if (g_str_equal(key, "Path")) {
2135 g_free(network->path);
2136 network->path = g_strdup(value);
2137 } else if (g_str_equal(key, "Node")) {
2138 g_free(network->node);
2139 network->node = g_strdup(value);
2140 } else if (g_str_equal(key, "WiFi.Mode")) {
2141 g_free(network->wifi.mode);
2142 network->wifi.mode = g_strdup(value);
2143 } else if (g_str_equal(key, "WiFi.Security")) {
2144 g_free(network->wifi.security);
2145 network->wifi.security = g_strdup(value);
2146 } else if (g_str_equal(key, "WiFi.Passphrase")) {
2147 g_free(network->wifi.passphrase);
2148 network->wifi.passphrase = g_strdup(value);
2149 } else if (g_str_equal(key, "WiFi.EAP")) {
2150 g_free(network->wifi.eap);
2151 network->wifi.eap = g_strdup(value);
2152 } else if (g_str_equal(key, "WiFi.Identity")) {
2153 g_free(network->wifi.identity);
2154 network->wifi.identity = g_strdup(value);
2155 } else if (g_str_equal(key, "WiFi.AnonymousIdentity")) {
2156 g_free(network->wifi.anonymous_identity);
2157 network->wifi.anonymous_identity = g_strdup(value);
2158 } else if (g_str_equal(key, "WiFi.AgentIdentity")) {
2159 g_free(network->wifi.agent_identity);
2160 network->wifi.agent_identity = g_strdup(value);
2161 } else if (g_str_equal(key, "WiFi.CACertFile")) {
2162 g_free(network->wifi.ca_cert_path);
2163 network->wifi.ca_cert_path = g_strdup(value);
2164 } else if (g_str_equal(key, "WiFi.SubjectMatch")) {
2165 g_free(network->wifi.subject_match);
2166 network->wifi.subject_match = g_strdup(value);
2167 } else if (g_str_equal(key, "WiFi.AltSubjectMatch")) {
2168 g_free(network->wifi.altsubject_match);
2169 network->wifi.altsubject_match = g_strdup(value);
2170 } else if (g_str_equal(key, "WiFi.DomainSuffixMatch")) {
2171 g_free(network->wifi.domain_suffix_match);
2172 network->wifi.domain_suffix_match = g_strdup(value);
2173 } else if (g_str_equal(key, "WiFi.DomainMatch")) {
2174 g_free(network->wifi.domain_match);
2175 network->wifi.domain_match = g_strdup(value);
2176 } else if (g_str_equal(key, "WiFi.ClientCertFile")) {
2177 g_free(network->wifi.client_cert_path);
2178 network->wifi.client_cert_path = g_strdup(value);
2179 } else if (g_str_equal(key, "WiFi.PrivateKeyFile")) {
2180 g_free(network->wifi.private_key_path);
2181 network->wifi.private_key_path = g_strdup(value);
2182 } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase")) {
2183 g_free(network->wifi.private_key_passphrase);
2184 network->wifi.private_key_passphrase = g_strdup(value);
2185 } else if (g_str_equal(key, "WiFi.Phase2")) {
2186 g_free(network->wifi.phase2_auth);
2187 network->wifi.phase2_auth = g_strdup(value);
2188 } else if (g_str_equal(key, "WiFi.PinWPS")) {
2189 g_free(network->wifi.pin_wps);
2190 network->wifi.pin_wps = g_strdup(value);
2199 * connman_network_get_string:
2200 * @network: network structure
2201 * @key: unique identifier
2203 * Get string value for specific key
2205 const char *connman_network_get_string(struct connman_network *network,
2208 if (g_str_equal(key, "Path"))
2209 return network->path;
2210 else if (g_str_equal(key, "Name"))
2211 return network->name;
2212 else if (g_str_equal(key, "Node"))
2213 return network->node;
2214 else if (g_str_equal(key, "WiFi.Mode"))
2215 return network->wifi.mode;
2216 else if (g_str_equal(key, "WiFi.Security"))
2217 return network->wifi.security;
2218 else if (g_str_equal(key, "WiFi.Passphrase"))
2219 return network->wifi.passphrase;
2220 else if (g_str_equal(key, "WiFi.EAP"))
2221 return network->wifi.eap;
2222 else if (g_str_equal(key, "WiFi.Identity"))
2223 return network->wifi.identity;
2224 else if (g_str_equal(key, "WiFi.AnonymousIdentity"))
2225 return network->wifi.anonymous_identity;
2226 else if (g_str_equal(key, "WiFi.AgentIdentity"))
2227 return network->wifi.agent_identity;
2228 else if (g_str_equal(key, "WiFi.CACertFile"))
2229 return network->wifi.ca_cert_path;
2230 else if (g_str_equal(key, "WiFi.SubjectMatch"))
2231 return network->wifi.subject_match;
2232 else if (g_str_equal(key, "WiFi.AltSubjectMatch"))
2233 return network->wifi.altsubject_match;
2234 else if (g_str_equal(key, "WiFi.DomainSuffixMatch"))
2235 return network->wifi.domain_suffix_match;
2236 else if (g_str_equal(key, "WiFi.DomainMatch"))
2237 return network->wifi.domain_match;
2238 else if (g_str_equal(key, "WiFi.ClientCertFile"))
2239 return network->wifi.client_cert_path;
2240 else if (g_str_equal(key, "WiFi.PrivateKeyFile"))
2241 return network->wifi.private_key_path;
2242 else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase"))
2243 return network->wifi.private_key_passphrase;
2244 else if (g_str_equal(key, "WiFi.Phase2"))
2245 return network->wifi.phase2_auth;
2246 else if (g_str_equal(key, "WiFi.PinWPS"))
2247 return network->wifi.pin_wps;
2253 * connman_network_set_bool:
2254 * @network: network structure
2255 * @key: unique identifier
2256 * @value: boolean value
2258 * Set boolean value for specific key
2260 int connman_network_set_bool(struct connman_network *network,
2261 const char *key, bool value)
2263 if (g_strcmp0(key, "Roaming") == 0)
2264 network->roaming = value;
2265 else if (g_strcmp0(key, "WiFi.WPS") == 0)
2266 network->wifi.wps = value;
2267 else if (g_strcmp0(key, "WiFi.WPSAdvertising") == 0)
2268 network->wifi.wps_advertizing = value;
2269 else if (g_strcmp0(key, "WiFi.UseWPS") == 0)
2270 network->wifi.use_wps = value;
2276 * connman_network_get_bool:
2277 * @network: network structure
2278 * @key: unique identifier
2280 * Get boolean value for specific key
2282 bool connman_network_get_bool(struct connman_network *network,
2285 if (g_str_equal(key, "Roaming"))
2286 return network->roaming;
2287 else if (g_str_equal(key, "WiFi.WPS"))
2288 return network->wifi.wps;
2289 else if (g_str_equal(key, "WiFi.WPSAdvertising"))
2290 return network->wifi.wps_advertizing;
2291 else if (g_str_equal(key, "WiFi.UseWPS"))
2292 return network->wifi.use_wps;
2298 * connman_network_set_blob:
2299 * @network: network structure
2300 * @key: unique identifier
2304 * Set binary blob value for specific key
2306 int connman_network_set_blob(struct connman_network *network,
2307 const char *key, const void *data, unsigned int size)
2309 if (g_str_equal(key, "WiFi.SSID")) {
2310 g_free(network->wifi.ssid);
2311 network->wifi.ssid = g_try_malloc(size);
2312 if (network->wifi.ssid) {
2313 memcpy(network->wifi.ssid, data, size);
2314 network->wifi.ssid_len = size;
2316 network->wifi.ssid_len = 0;
2325 * connman_network_get_blob:
2326 * @network: network structure
2327 * @key: unique identifier
2328 * @size: pointer to blob size
2330 * Get binary blob value for specific key
2332 const void *connman_network_get_blob(struct connman_network *network,
2333 const char *key, unsigned int *size)
2335 if (g_str_equal(key, "WiFi.SSID")) {
2337 *size = network->wifi.ssid_len;
2338 return network->wifi.ssid;
2344 void __connman_network_set_device(struct connman_network *network,
2345 struct connman_device *device)
2347 if (network->device == device)
2350 if (network->device)
2351 network_remove(network);
2353 network->device = device;
2355 if (network->device)
2356 network_probe(network);
2360 * connman_network_get_device:
2361 * @network: network structure
2363 * Get parent device of network
2365 struct connman_device *connman_network_get_device(struct connman_network *network)
2367 return network->device;
2371 * connman_network_get_data:
2372 * @network: network structure
2374 * Get private network data pointer
2376 void *connman_network_get_data(struct connman_network *network)
2378 return network->driver_data;
2382 * connman_network_set_data:
2383 * @network: network structure
2384 * @data: data pointer
2386 * Set private network data pointer
2388 void connman_network_set_data(struct connman_network *network, void *data)
2390 network->driver_data = data;
2393 void connman_network_update(struct connman_network *network)
2395 switch (network->type) {
2396 case CONNMAN_NETWORK_TYPE_UNKNOWN:
2397 case CONNMAN_NETWORK_TYPE_VENDOR:
2399 case CONNMAN_NETWORK_TYPE_ETHERNET:
2400 case CONNMAN_NETWORK_TYPE_GADGET:
2401 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
2402 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
2403 case CONNMAN_NETWORK_TYPE_CELLULAR:
2404 case CONNMAN_NETWORK_TYPE_WIFI:
2409 __connman_service_update_from_network(network);
2412 int __connman_network_init(void)
2419 void __connman_network_cleanup(void)