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
36 #include <connman/storage.h>
37 #include <connman/setting.h>
38 #include <connman/agent.h>
42 #define CONNECT_TIMEOUT 120
45 #define USER_NONE (uid_t)-1
48 #define WIFI_BSSID_STR_LEN 18
51 static DBusConnection *connection = NULL;
53 static GList *service_list = NULL;
54 static GHashTable *service_hash = NULL;
55 static GSList *counter_list = NULL;
56 static unsigned int autoconnect_timeout = 0;
57 static unsigned int vpn_autoconnect_timeout = 0;
58 static struct connman_service *current_default = NULL;
59 static bool services_dirty = false;
61 struct connman_stats {
64 struct connman_stats_data data_last;
65 struct connman_stats_data data;
69 struct connman_stats_counter {
71 struct connman_stats stats;
72 struct connman_stats stats_roaming;
75 struct connman_service_user {
80 struct connman_service {
84 enum connman_service_type type;
85 enum connman_service_security security;
86 enum connman_service_state state;
87 enum connman_service_state state_ipv4;
88 enum connman_service_state state_ipv6;
89 enum connman_service_error error;
90 enum connman_service_connect_reason connect_reason;
102 bool request_passphrase_input;
103 struct connman_service_user user;
104 struct connman_ipconfig *ipconfig_ipv4;
105 struct connman_ipconfig *ipconfig_ipv6;
106 struct connman_network *network;
107 struct connman_provider *provider;
109 char **nameservers_config;
110 char **nameservers_auto;
115 char **timeservers_config;
116 /* 802.1x settings from the config files */
119 char *agent_identity;
121 char *client_cert_file;
122 char *private_key_file;
123 char *private_key_passphrase;
125 DBusMessage *pending;
126 DBusMessage *provider_pending;
128 struct connman_stats stats;
129 struct connman_stats stats_roaming;
130 GHashTable *counter_table;
131 enum connman_service_proxy_method proxy;
132 enum connman_service_proxy_method proxy_config;
137 int online_check_count;
138 bool do_split_routing;
143 #if defined TIZEN_EXT
145 * Description: TIZEN implements system global connection management.
146 * It's only for PDP (cellular) bearer. Wi-Fi is managed
147 * by ConnMan automatically. Reference count can help to
148 * manage open/close connection requests by each application.
150 int user_pdn_connection_refcount;
153 * Description: In case of EAP security type,
154 * user can select the keymgmt type for roaming(802.11r).
155 * - FT, CCKM, OKC, ...
158 int disconnect_reason;
161 enum connman_dnsconfig_method dns_config_method_ipv4;
162 enum connman_dnsconfig_method dns_config_method_ipv6;
166 static bool allow_property_changed(struct connman_service *service);
168 static struct connman_ipconfig *create_ip4config(struct connman_service *service,
169 int index, enum connman_ipconfig_method method);
170 static struct connman_ipconfig *create_ip6config(struct connman_service *service,
176 struct connman_service *service;
179 #if defined TIZEN_EXT
181 * Public APIs to use user_pdn_connection_refcount
183 void connman_service_user_pdn_connection_ref(struct connman_service *service)
185 __sync_fetch_and_add(&service->user_pdn_connection_refcount, 1);
187 DBG("User made PDN connection referenced: %d",
188 service->user_pdn_connection_refcount);
191 gboolean connman_service_user_pdn_connection_unref_and_test(
192 struct connman_service *service)
194 __sync_synchronize();
196 DBG("User made PDN connection referenced: %d, which will be decreased",
197 service->user_pdn_connection_refcount);
199 if (service->user_pdn_connection_refcount < 1)
202 if (__sync_sub_and_fetch(&service->user_pdn_connection_refcount, 1) == 0)
208 gboolean connman_service_is_no_ref_user_pdn_connection(
209 struct connman_service *cellular)
211 if (cellular == NULL)
214 __sync_synchronize();
215 if (cellular->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
216 cellular->user_pdn_connection_refcount == 0)
223 static void compare_path(gpointer value, gpointer user_data)
225 struct connman_service *service = value;
226 struct find_data *data = user_data;
231 if (g_strcmp0(service->path, data->path) == 0)
232 data->service = service;
235 static struct connman_service *find_service(const char *path)
237 struct find_data data = { .path = path, .service = NULL };
239 DBG("path %s", path);
241 g_list_foreach(service_list, compare_path, &data);
246 static const char *reason2string(enum connman_service_connect_reason reason)
250 case CONNMAN_SERVICE_CONNECT_REASON_NONE:
252 case CONNMAN_SERVICE_CONNECT_REASON_USER:
254 case CONNMAN_SERVICE_CONNECT_REASON_AUTO:
256 case CONNMAN_SERVICE_CONNECT_REASON_SESSION:
263 const char *__connman_service_type2string(enum connman_service_type type)
266 case CONNMAN_SERVICE_TYPE_UNKNOWN:
268 case CONNMAN_SERVICE_TYPE_SYSTEM:
270 case CONNMAN_SERVICE_TYPE_ETHERNET:
272 case CONNMAN_SERVICE_TYPE_WIFI:
274 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
276 case CONNMAN_SERVICE_TYPE_CELLULAR:
278 case CONNMAN_SERVICE_TYPE_GPS:
280 case CONNMAN_SERVICE_TYPE_VPN:
282 case CONNMAN_SERVICE_TYPE_GADGET:
284 case CONNMAN_SERVICE_TYPE_P2P:
291 enum connman_service_type __connman_service_string2type(const char *str)
294 return CONNMAN_SERVICE_TYPE_UNKNOWN;
296 if (strcmp(str, "ethernet") == 0)
297 return CONNMAN_SERVICE_TYPE_ETHERNET;
298 if (strcmp(str, "gadget") == 0)
299 return CONNMAN_SERVICE_TYPE_GADGET;
300 if (strcmp(str, "wifi") == 0)
301 return CONNMAN_SERVICE_TYPE_WIFI;
302 if (strcmp(str, "cellular") == 0)
303 return CONNMAN_SERVICE_TYPE_CELLULAR;
304 if (strcmp(str, "bluetooth") == 0)
305 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
306 if (strcmp(str, "vpn") == 0)
307 return CONNMAN_SERVICE_TYPE_VPN;
308 if (strcmp(str, "gps") == 0)
309 return CONNMAN_SERVICE_TYPE_GPS;
310 if (strcmp(str, "system") == 0)
311 return CONNMAN_SERVICE_TYPE_SYSTEM;
312 if (strcmp(str, "p2p") == 0)
313 return CONNMAN_SERVICE_TYPE_P2P;
315 return CONNMAN_SERVICE_TYPE_UNKNOWN;
318 enum connman_service_security __connman_service_string2security(const char *str)
321 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
323 if (!strcmp(str, "psk"))
324 return CONNMAN_SERVICE_SECURITY_PSK;
325 if (!strcmp(str, "ieee8021x"))
326 return CONNMAN_SERVICE_SECURITY_8021X;
327 if (!strcmp(str, "none"))
328 return CONNMAN_SERVICE_SECURITY_NONE;
329 if (!strcmp(str, "wep"))
330 return CONNMAN_SERVICE_SECURITY_WEP;
331 #if defined TIZEN_EXT
332 if (!strcmp(str, "rsn"))
333 return CONNMAN_SERVICE_SECURITY_RSN;
336 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
339 static const char *security2string(enum connman_service_security security)
342 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
344 case CONNMAN_SERVICE_SECURITY_NONE:
346 case CONNMAN_SERVICE_SECURITY_WEP:
348 case CONNMAN_SERVICE_SECURITY_PSK:
349 case CONNMAN_SERVICE_SECURITY_WPA:
350 #if defined TIZEN_EXT
352 case CONNMAN_SERVICE_SECURITY_RSN:
355 case CONNMAN_SERVICE_SECURITY_RSN:
358 case CONNMAN_SERVICE_SECURITY_8021X:
365 static const char *state2string(enum connman_service_state state)
368 case CONNMAN_SERVICE_STATE_UNKNOWN:
370 case CONNMAN_SERVICE_STATE_IDLE:
372 case CONNMAN_SERVICE_STATE_ASSOCIATION:
373 return "association";
374 case CONNMAN_SERVICE_STATE_CONFIGURATION:
375 return "configuration";
376 case CONNMAN_SERVICE_STATE_READY:
378 case CONNMAN_SERVICE_STATE_ONLINE:
380 case CONNMAN_SERVICE_STATE_DISCONNECT:
382 case CONNMAN_SERVICE_STATE_FAILURE:
389 static const char *error2string(enum connman_service_error error)
392 case CONNMAN_SERVICE_ERROR_UNKNOWN:
394 case CONNMAN_SERVICE_ERROR_OUT_OF_RANGE:
395 return "out-of-range";
396 case CONNMAN_SERVICE_ERROR_PIN_MISSING:
397 return "pin-missing";
398 case CONNMAN_SERVICE_ERROR_DHCP_FAILED:
399 return "dhcp-failed";
400 case CONNMAN_SERVICE_ERROR_CONNECT_FAILED:
401 return "connect-failed";
402 case CONNMAN_SERVICE_ERROR_LOGIN_FAILED:
403 return "login-failed";
404 case CONNMAN_SERVICE_ERROR_AUTH_FAILED:
405 return "auth-failed";
406 case CONNMAN_SERVICE_ERROR_INVALID_KEY:
407 return "invalid-key";
408 case CONNMAN_SERVICE_ERROR_BLOCKED:
415 static const char *proxymethod2string(enum connman_service_proxy_method method)
418 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
420 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
422 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
424 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
431 static enum connman_service_proxy_method string2proxymethod(const char *method)
433 if (g_strcmp0(method, "direct") == 0)
434 return CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
435 else if (g_strcmp0(method, "auto") == 0)
436 return CONNMAN_SERVICE_PROXY_METHOD_AUTO;
437 else if (g_strcmp0(method, "manual") == 0)
438 return CONNMAN_SERVICE_PROXY_METHOD_MANUAL;
440 return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
444 static const char *__connman_dnsconfig_method2string(enum connman_dnsconfig_method method)
447 case CONNMAN_DNSCONFIG_METHOD_UNKNOWN:
449 case CONNMAN_DNSCONFIG_METHOD_MANUAL:
451 case CONNMAN_DNSCONFIG_METHOD_DHCP:
458 static enum connman_dnsconfig_method __connman_dnsconfig_string2method(
461 if (g_strcmp0(method, "manual") == 0)
462 return CONNMAN_DNSCONFIG_METHOD_MANUAL;
463 else if (g_strcmp0(method, "dhcp") == 0)
464 return CONNMAN_DNSCONFIG_METHOD_DHCP;
466 return CONNMAN_DNSCONFIG_METHOD_UNKNOWN;
471 connman_service_is_user_allowed(struct connman_service *service, uid_t uid)
473 uid_t favorite_user = service->user.favorite_user;
474 uid_t current_user = uid;
476 DBG("Service favorite UID: %d, current UID: %d", favorite_user, current_user);
477 if (favorite_user == USER_NONE || current_user == USER_ROOT)
480 if (favorite_user != current_user || current_user == USER_NONE) {
481 DBG("Current user is not a favorite user to this service!");
488 #if !defined TIZEN_EXT
489 static GList *connman_service_get_login_users()
493 GList *user_list = NULL;
497 while ((utmp = getutxent()) != NULL) {
498 DBG("User Name: %s", utmp->ut_user);
500 pwd = getpwnam(utmp->ut_user);
502 if (!g_list_find(user_list, GUINT_TO_POINTER(pwd->pw_uid)))
503 user_list = g_list_append(user_list,
504 GUINT_TO_POINTER(pwd->pw_uid));
506 DBG("User Name: %s, UID: %d", utmp->ut_user, pwd->pw_uid);
516 static bool is_service_owner_user_login(struct connman_service *service)
518 #if defined TIZEN_EXT
521 GList *list, *user_list;
524 /* Here we only care about wifi service */
525 if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
528 DBG("service favorite user id is: %d", service->user.favorite_user);
530 user_list = connman_service_get_login_users();
531 if (user_list == NULL) {
532 DBG("Can not get any logged in user info.");
536 for (list = user_list; list; list = list->next) {
537 uid_t uid = GPOINTER_TO_UINT(list->data);
539 DBG("login user id is %d", uid);
541 if (service->user.favorite_user == uid) {
547 g_list_free(user_list);
553 int __connman_service_load_modifiable(struct connman_service *service)
556 GError *error = NULL;
560 DBG("service %p", service);
562 keyfile = connman_storage_load_service(service->identifier);
566 switch (service->type) {
567 case CONNMAN_SERVICE_TYPE_UNKNOWN:
568 case CONNMAN_SERVICE_TYPE_SYSTEM:
569 case CONNMAN_SERVICE_TYPE_GPS:
570 case CONNMAN_SERVICE_TYPE_P2P:
572 case CONNMAN_SERVICE_TYPE_VPN:
573 service->do_split_routing = g_key_file_get_boolean(keyfile,
574 service->identifier, "SplitRouting", NULL);
576 case CONNMAN_SERVICE_TYPE_WIFI:
577 case CONNMAN_SERVICE_TYPE_GADGET:
578 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
579 case CONNMAN_SERVICE_TYPE_CELLULAR:
580 case CONNMAN_SERVICE_TYPE_ETHERNET:
581 autoconnect = g_key_file_get_boolean(keyfile,
582 service->identifier, "AutoConnect", &error);
584 service->autoconnect = autoconnect;
585 g_clear_error(&error);
589 str = g_key_file_get_string(keyfile,
590 service->identifier, "Modified", NULL);
592 g_time_val_from_iso8601(str, &service->modified);
596 g_key_file_free(keyfile);
601 static int service_load_passphrase(struct connman_service *service)
606 keyfile = connman_storage_load_service(service->identifier);
610 str = g_key_file_get_string(keyfile,
611 service->identifier, "Passphrase", NULL);
613 service->passphrase = str;
615 g_key_file_free(keyfile);
620 static int service_load(struct connman_service *service)
623 GError *error = NULL;
627 unsigned int ssid_len;
630 DBG("service %p", service);
632 keyfile = connman_storage_load_service(service->identifier);
634 service->new_service = true;
637 service->new_service = false;
639 switch (service->type) {
640 case CONNMAN_SERVICE_TYPE_UNKNOWN:
641 case CONNMAN_SERVICE_TYPE_SYSTEM:
642 case CONNMAN_SERVICE_TYPE_GPS:
643 case CONNMAN_SERVICE_TYPE_P2P:
645 case CONNMAN_SERVICE_TYPE_VPN:
646 service->do_split_routing = g_key_file_get_boolean(keyfile,
647 service->identifier, "SplitRouting", NULL);
648 autoconnect = g_key_file_get_boolean(keyfile,
649 service->identifier, "AutoConnect", &error);
651 service->autoconnect = autoconnect;
652 g_clear_error(&error);
654 case CONNMAN_SERVICE_TYPE_WIFI:
655 if (!service->name) {
658 name = g_key_file_get_string(keyfile,
659 service->identifier, "Name", NULL);
661 g_free(service->name);
662 service->name = name;
665 if (service->network)
666 connman_network_set_name(service->network,
670 if (service->network &&
671 !connman_network_get_blob(service->network,
672 "WiFi.SSID", &ssid_len)) {
675 hex_ssid = g_key_file_get_string(keyfile,
681 unsigned int i, j = 0, hex;
682 size_t hex_ssid_len = strlen(hex_ssid);
684 ssid = g_try_malloc0(hex_ssid_len / 2);
691 for (i = 0; i < hex_ssid_len; i += 2) {
692 sscanf(hex_ssid + i, "%02x", &hex);
696 connman_network_set_blob(service->network,
697 "WiFi.SSID", ssid, hex_ssid_len / 2);
706 case CONNMAN_SERVICE_TYPE_GADGET:
707 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
708 case CONNMAN_SERVICE_TYPE_CELLULAR:
709 service->favorite = g_key_file_get_boolean(keyfile,
710 service->identifier, "Favorite", NULL);
714 case CONNMAN_SERVICE_TYPE_ETHERNET:
715 autoconnect = g_key_file_get_boolean(keyfile,
716 service->identifier, "AutoConnect", &error);
718 service->autoconnect = autoconnect;
719 g_clear_error(&error);
723 str = g_key_file_get_string(keyfile,
724 service->identifier, "Modified", NULL);
726 g_time_val_from_iso8601(str, &service->modified);
730 str = g_key_file_get_string(keyfile,
731 service->identifier, "Passphrase", NULL);
733 g_free(service->passphrase);
734 service->passphrase = str;
737 if (service->ipconfig_ipv4)
738 __connman_ipconfig_load(service->ipconfig_ipv4, keyfile,
739 service->identifier, "IPv4.");
741 if (service->ipconfig_ipv6)
742 __connman_ipconfig_load(service->ipconfig_ipv6, keyfile,
743 service->identifier, "IPv6.");
745 service->nameservers_config = g_key_file_get_string_list(keyfile,
746 service->identifier, "Nameservers", &length, NULL);
747 if (service->nameservers_config && length == 0) {
748 g_strfreev(service->nameservers_config);
749 service->nameservers_config = NULL;
755 dns_method = g_key_file_get_string(keyfile, service->identifier,
756 "Nameservers.IPv4method", NULL);
757 service->dns_config_method_ipv4 = __connman_dnsconfig_string2method(dns_method);
759 dns_method = g_key_file_get_string(keyfile, service->identifier,
760 "Nameservers.IPv6method", NULL);
761 service->dns_config_method_ipv6 = __connman_dnsconfig_string2method(dns_method);
764 service->timeservers_config = g_key_file_get_string_list(keyfile,
765 service->identifier, "Timeservers", &length, NULL);
766 if (service->timeservers_config && length == 0) {
767 g_strfreev(service->timeservers_config);
768 service->timeservers_config = NULL;
771 service->domains = g_key_file_get_string_list(keyfile,
772 service->identifier, "Domains", &length, NULL);
773 if (service->domains && length == 0) {
774 g_strfreev(service->domains);
775 service->domains = NULL;
778 str = g_key_file_get_string(keyfile,
779 service->identifier, "Proxy.Method", NULL);
781 service->proxy_config = string2proxymethod(str);
785 service->proxies = g_key_file_get_string_list(keyfile,
786 service->identifier, "Proxy.Servers", &length, NULL);
787 if (service->proxies && length == 0) {
788 g_strfreev(service->proxies);
789 service->proxies = NULL;
792 service->excludes = g_key_file_get_string_list(keyfile,
793 service->identifier, "Proxy.Excludes", &length, NULL);
794 if (service->excludes && length == 0) {
795 g_strfreev(service->excludes);
796 service->excludes = NULL;
799 str = g_key_file_get_string(keyfile,
800 service->identifier, "Proxy.URL", NULL);
802 g_free(service->pac);
806 service->hidden_service = g_key_file_get_boolean(keyfile,
807 service->identifier, "Hidden", NULL);
809 #if defined TIZEN_EXT
810 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
811 service->security == CONNMAN_SERVICE_SECURITY_8021X) {
812 str = g_key_file_get_string(keyfile,
813 service->identifier, "EAP", NULL);
815 g_free(service->eap);
819 str = g_key_file_get_string(keyfile,
820 service->identifier, "Phase2", NULL);
822 g_free(service->phase2);
823 service->phase2 = str;
826 str = g_key_file_get_string(keyfile,
827 service->identifier, "Identity", NULL);
829 g_free(service->identity);
830 service->identity = str;
833 str = g_key_file_get_string(keyfile,
834 service->identifier, "CACertFile", NULL);
836 g_free(service->ca_cert_file);
837 service->ca_cert_file = str;
840 str = g_key_file_get_string(keyfile,
841 service->identifier, "ClientCertFile", NULL);
843 g_free(service->client_cert_file);
844 service->client_cert_file = str;
847 str = g_key_file_get_string(keyfile,
848 service->identifier, "PrivateKeyFile", NULL);
850 g_free(service->private_key_file);
851 service->private_key_file = str;
854 str = g_key_file_get_string(keyfile,
855 service->identifier, "PrivateKeyPassphrase", NULL);
857 g_free(service->private_key_passphrase);
858 service->private_key_passphrase = str;
863 if (g_key_file_has_key(keyfile, service->identifier, "UID", NULL))
864 service->user.favorite_user = g_key_file_get_integer(keyfile,
865 service->identifier, "UID", NULL);
867 g_key_file_free(keyfile);
872 static int service_save(struct connman_service *service)
877 const char *cst_str = NULL;
880 DBG("service %p new %d", service, service->new_service);
882 if (service->new_service)
885 keyfile = __connman_storage_open_service(service->identifier);
890 g_key_file_set_string(keyfile, service->identifier,
891 "Name", service->name);
893 switch (service->type) {
894 case CONNMAN_SERVICE_TYPE_UNKNOWN:
895 case CONNMAN_SERVICE_TYPE_SYSTEM:
896 case CONNMAN_SERVICE_TYPE_GPS:
897 case CONNMAN_SERVICE_TYPE_P2P:
899 case CONNMAN_SERVICE_TYPE_VPN:
900 g_key_file_set_boolean(keyfile, service->identifier,
901 "SplitRouting", service->do_split_routing);
902 if (service->favorite)
903 g_key_file_set_boolean(keyfile, service->identifier,
904 "AutoConnect", service->autoconnect);
906 case CONNMAN_SERVICE_TYPE_WIFI:
907 if (service->network) {
908 const unsigned char *ssid;
909 unsigned int ssid_len = 0;
911 if (service->user.favorite_user == USER_NONE)
912 g_key_file_remove_key(keyfile, service->identifier,
915 g_key_file_set_integer(keyfile, service->identifier,
916 "UID", service->user.favorite_user);
918 ssid = connman_network_get_blob(service->network,
919 "WiFi.SSID", &ssid_len);
921 if (ssid && ssid_len > 0 && ssid[0] != '\0') {
922 char *identifier = service->identifier;
926 ssid_str = g_string_sized_new(ssid_len * 2);
932 for (i = 0; i < ssid_len; i++)
933 g_string_append_printf(ssid_str,
936 g_key_file_set_string(keyfile, identifier,
937 "SSID", ssid_str->str);
939 g_string_free(ssid_str, TRUE);
942 freq = connman_network_get_frequency(service->network);
943 g_key_file_set_integer(keyfile, service->identifier,
948 case CONNMAN_SERVICE_TYPE_GADGET:
949 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
950 case CONNMAN_SERVICE_TYPE_CELLULAR:
951 g_key_file_set_boolean(keyfile, service->identifier,
952 "Favorite", service->favorite);
954 g_key_file_remove_key(keyfile, service->identifier,
959 case CONNMAN_SERVICE_TYPE_ETHERNET:
960 if (service->favorite)
961 g_key_file_set_boolean(keyfile, service->identifier,
962 "AutoConnect", service->autoconnect);
966 str = g_time_val_to_iso8601(&service->modified);
968 g_key_file_set_string(keyfile, service->identifier,
973 if (service->user.current_user == service->user.favorite_user) {
974 if (service->passphrase && strlen(service->passphrase) > 0)
975 g_key_file_set_string(keyfile, service->identifier,
976 "Passphrase", service->passphrase);
978 g_key_file_remove_key(keyfile, service->identifier,
982 if (service->ipconfig_ipv4)
983 __connman_ipconfig_save(service->ipconfig_ipv4, keyfile,
984 service->identifier, "IPv4.");
986 if (service->ipconfig_ipv6)
987 __connman_ipconfig_save(service->ipconfig_ipv6, keyfile,
988 service->identifier, "IPv6.");
990 if (service->nameservers_config) {
991 guint len = g_strv_length(service->nameservers_config);
993 g_key_file_set_string_list(keyfile, service->identifier,
995 (const gchar **) service->nameservers_config, len);
997 g_key_file_remove_key(keyfile, service->identifier,
998 "Nameservers", NULL);
1000 #if defined TIZEN_EXT
1001 if(service->dns_config_method_ipv4 != 0) {
1003 method = __connman_dnsconfig_method2string(
1004 service->dns_config_method_ipv4);
1005 g_key_file_set_string(keyfile, service->identifier,
1006 "Nameservers.IPv4method", method);
1008 g_key_file_remove_key(keyfile, service->identifier,
1009 "Nameservers.IPv4method", NULL);
1011 if(service->dns_config_method_ipv6 != 0) {
1013 method = __connman_dnsconfig_method2string(
1014 service->dns_config_method_ipv6);
1015 g_key_file_set_string(keyfile, service->identifier,
1016 "Nameservers.IPv6method", method);
1018 g_key_file_remove_key(keyfile, service->identifier,
1019 "Nameservers.IPv6method", NULL);
1022 if (service->timeservers_config) {
1023 guint len = g_strv_length(service->timeservers_config);
1025 g_key_file_set_string_list(keyfile, service->identifier,
1027 (const gchar **) service->timeservers_config, len);
1029 g_key_file_remove_key(keyfile, service->identifier,
1030 "Timeservers", NULL);
1032 if (service->domains) {
1033 guint len = g_strv_length(service->domains);
1035 g_key_file_set_string_list(keyfile, service->identifier,
1037 (const gchar **) service->domains, len);
1039 g_key_file_remove_key(keyfile, service->identifier,
1042 cst_str = proxymethod2string(service->proxy_config);
1044 g_key_file_set_string(keyfile, service->identifier,
1045 "Proxy.Method", cst_str);
1047 if (service->proxies) {
1048 guint len = g_strv_length(service->proxies);
1050 g_key_file_set_string_list(keyfile, service->identifier,
1052 (const gchar **) service->proxies, len);
1054 g_key_file_remove_key(keyfile, service->identifier,
1055 "Proxy.Servers", NULL);
1057 if (service->excludes) {
1058 guint len = g_strv_length(service->excludes);
1060 g_key_file_set_string_list(keyfile, service->identifier,
1062 (const gchar **) service->excludes, len);
1064 g_key_file_remove_key(keyfile, service->identifier,
1065 "Proxy.Excludes", NULL);
1067 if (service->pac && strlen(service->pac) > 0)
1068 g_key_file_set_string(keyfile, service->identifier,
1069 "Proxy.URL", service->pac);
1071 g_key_file_remove_key(keyfile, service->identifier,
1074 if (service->hidden_service)
1075 g_key_file_set_boolean(keyfile, service->identifier, "Hidden",
1078 if (service->config_file && strlen(service->config_file) > 0)
1079 g_key_file_set_string(keyfile, service->identifier,
1080 "Config.file", service->config_file);
1082 if (service->config_entry &&
1083 strlen(service->config_entry) > 0)
1084 g_key_file_set_string(keyfile, service->identifier,
1085 "Config.ident", service->config_entry);
1087 #if defined TIZEN_EXT
1088 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
1089 service->security == CONNMAN_SERVICE_SECURITY_8021X) {
1090 if (service->eap != NULL && strlen(service->eap) > 0)
1091 g_key_file_set_string(keyfile, service->identifier,
1092 "EAP", service->eap);
1094 g_key_file_remove_key(keyfile, service->identifier,
1097 if (service->phase2 != NULL && strlen(service->phase2) > 0)
1098 g_key_file_set_string(keyfile, service->identifier,
1099 "Phase2", service->phase2);
1101 g_key_file_remove_key(keyfile, service->identifier,
1104 if (service->identity != NULL && strlen(service->identity) > 0)
1105 g_key_file_set_string(keyfile, service->identifier,
1106 "Identity", service->identity);
1108 g_key_file_remove_key(keyfile, service->identifier,
1111 if (service->ca_cert_file != NULL && strlen(service->ca_cert_file) > 0)
1112 g_key_file_set_string(keyfile, service->identifier,
1113 "CACertFile", service->ca_cert_file);
1115 g_key_file_remove_key(keyfile, service->identifier,
1116 "CACertFile", NULL);
1118 if (service->client_cert_file != NULL && strlen(service->client_cert_file) > 0)
1119 g_key_file_set_string(keyfile, service->identifier,
1120 "ClientCertFile", service->client_cert_file);
1122 g_key_file_remove_key(keyfile, service->identifier,
1123 "ClientCertFile", NULL);
1125 if (service->private_key_file != NULL && strlen(service->private_key_file) > 0)
1126 g_key_file_set_string(keyfile, service->identifier,
1127 "PrivateKeyFile", service->private_key_file);
1129 g_key_file_remove_key(keyfile, service->identifier,
1130 "PrivateKeyFile", NULL);
1132 if (service->private_key_passphrase != NULL && strlen(service->private_key_passphrase) > 0)
1133 g_key_file_set_string(keyfile, service->identifier,
1134 "PrivateKeyPassphrase", service->private_key_passphrase);
1136 g_key_file_remove_key(keyfile, service->identifier,
1137 "PrivateKeyPassphrase", NULL);
1142 __connman_storage_save_service(keyfile, service->identifier);
1144 g_key_file_free(keyfile);
1149 void __connman_service_save(struct connman_service *service)
1154 service_save(service);
1157 static enum connman_service_state combine_state(
1158 enum connman_service_state state_a,
1159 enum connman_service_state state_b)
1161 enum connman_service_state result;
1163 if (state_a == state_b) {
1168 if (state_a == CONNMAN_SERVICE_STATE_UNKNOWN) {
1173 if (state_b == CONNMAN_SERVICE_STATE_UNKNOWN) {
1178 if (state_a == CONNMAN_SERVICE_STATE_IDLE) {
1183 if (state_b == CONNMAN_SERVICE_STATE_IDLE) {
1188 if (state_a == CONNMAN_SERVICE_STATE_ONLINE) {
1193 if (state_b == CONNMAN_SERVICE_STATE_ONLINE) {
1198 if (state_a == CONNMAN_SERVICE_STATE_READY) {
1203 if (state_b == CONNMAN_SERVICE_STATE_READY) {
1208 if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION) {
1213 if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION) {
1218 if (state_a == CONNMAN_SERVICE_STATE_ASSOCIATION) {
1223 if (state_b == CONNMAN_SERVICE_STATE_ASSOCIATION) {
1228 if (state_a == CONNMAN_SERVICE_STATE_DISCONNECT) {
1233 if (state_b == CONNMAN_SERVICE_STATE_DISCONNECT) {
1238 result = CONNMAN_SERVICE_STATE_FAILURE;
1244 static bool is_connecting_state(struct connman_service *service,
1245 enum connman_service_state state)
1248 case CONNMAN_SERVICE_STATE_UNKNOWN:
1249 case CONNMAN_SERVICE_STATE_IDLE:
1250 case CONNMAN_SERVICE_STATE_FAILURE:
1251 if (service->network)
1252 return connman_network_get_connecting(service->network);
1253 case CONNMAN_SERVICE_STATE_DISCONNECT:
1254 case CONNMAN_SERVICE_STATE_READY:
1255 case CONNMAN_SERVICE_STATE_ONLINE:
1257 case CONNMAN_SERVICE_STATE_ASSOCIATION:
1258 case CONNMAN_SERVICE_STATE_CONFIGURATION:
1265 static bool is_connected_state(const struct connman_service *service,
1266 enum connman_service_state state)
1269 case CONNMAN_SERVICE_STATE_UNKNOWN:
1270 case CONNMAN_SERVICE_STATE_IDLE:
1271 case CONNMAN_SERVICE_STATE_ASSOCIATION:
1272 case CONNMAN_SERVICE_STATE_CONFIGURATION:
1273 case CONNMAN_SERVICE_STATE_DISCONNECT:
1274 case CONNMAN_SERVICE_STATE_FAILURE:
1276 case CONNMAN_SERVICE_STATE_READY:
1277 case CONNMAN_SERVICE_STATE_ONLINE:
1284 static bool is_idle_state(const struct connman_service *service,
1285 enum connman_service_state state)
1288 case CONNMAN_SERVICE_STATE_UNKNOWN:
1289 case CONNMAN_SERVICE_STATE_ASSOCIATION:
1290 case CONNMAN_SERVICE_STATE_CONFIGURATION:
1291 case CONNMAN_SERVICE_STATE_READY:
1292 case CONNMAN_SERVICE_STATE_ONLINE:
1293 case CONNMAN_SERVICE_STATE_DISCONNECT:
1294 case CONNMAN_SERVICE_STATE_FAILURE:
1296 case CONNMAN_SERVICE_STATE_IDLE:
1303 static bool is_connecting(struct connman_service *service)
1305 return is_connecting_state(service, service->state);
1308 static bool is_connected(struct connman_service *service)
1310 return is_connected_state(service, service->state);
1313 static bool nameserver_available(struct connman_service *service,
1318 family = connman_inet_check_ipaddress(ns);
1320 if (family == AF_INET)
1321 return is_connected_state(service, service->state_ipv4);
1323 if (family == AF_INET6)
1324 return is_connected_state(service, service->state_ipv6);
1329 static int nameserver_add(struct connman_service *service,
1330 const char *nameserver)
1334 if (!nameserver_available(service, nameserver))
1337 index = __connman_service_get_index(service);
1341 #if defined TIZEN_EXT
1342 DBG("Resolver append nameserver: %s", nameserver);
1344 return connman_resolver_append(index, NULL, nameserver);
1347 #if defined TIZEN_EXT
1348 static int nameserver_add_all(struct connman_service *service,
1349 enum connman_ipconfig_type type)
1351 static int nameserver_add_all(struct connman_service *service)
1356 if (service->nameservers_config) {
1357 while (service->nameservers_config[i]) {
1358 #if defined TIZEN_EXT
1359 DBG("type %d add service->nameservers_config[%d]:%s",type,
1360 i, service->nameservers_config[i]);
1361 if(strncmp(service->nameservers_config[i], "::", 2) == 0) {
1362 DBG("Invalid nameserver");
1368 case CONNMAN_IPCONFIG_TYPE_IPV4:
1369 if (connman_inet_check_ipaddress(
1370 service->nameservers_config[i]) == AF_INET &&
1371 service->dns_config_method_ipv4 ==
1372 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
1373 nameserver_add(service,
1374 service->nameservers_config[i]);
1377 case CONNMAN_IPCONFIG_TYPE_IPV6:
1378 if (connman_inet_check_ipaddress(
1379 service->nameservers_config[i]) == AF_INET6 &&
1380 service->dns_config_method_ipv6 ==
1381 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
1382 nameserver_add(service,
1383 service->nameservers_config[i]);
1386 case CONNMAN_IPCONFIG_TYPE_ALL:
1387 if (connman_inet_check_ipaddress(
1388 service->nameservers_config[i]) == AF_INET &&
1389 service->dns_config_method_ipv4 ==
1390 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
1391 nameserver_add(service,
1392 service->nameservers_config[i]);
1394 if (connman_inet_check_ipaddress(
1395 service->nameservers_config[i]) == AF_INET6 &&
1396 service->dns_config_method_ipv6 ==
1397 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
1398 nameserver_add(service,
1399 service->nameservers_config[i]);
1402 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1403 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
1406 DBG("default case do nothing");
1410 nameserver_add(service, service->nameservers_config[i]);
1414 #if !defined TIZEN_EXT
1419 #if defined TIZEN_EXT
1422 if (service->nameservers) {
1423 while (service->nameservers[i]) {
1424 #if defined TIZEN_EXT
1425 DBG("type %d service->nameservers[%d]: %s",type,
1426 i, service->nameservers[i]);
1429 case CONNMAN_IPCONFIG_TYPE_IPV4:
1430 if (connman_inet_check_ipaddress(
1431 service->nameservers[i]) == AF_INET &&
1432 service->dns_config_method_ipv4 ==
1433 CONNMAN_DNSCONFIG_METHOD_DHCP) {
1434 nameserver_add(service,
1435 service->nameservers[i]);
1438 case CONNMAN_IPCONFIG_TYPE_IPV6:
1439 if (connman_inet_check_ipaddress(
1440 service->nameservers[i]) == AF_INET6 &&
1441 service->dns_config_method_ipv6 ==
1442 CONNMAN_DNSCONFIG_METHOD_DHCP) {
1443 nameserver_add(service,
1444 service->nameservers[i]);
1447 case CONNMAN_IPCONFIG_TYPE_ALL:
1448 if (connman_inet_check_ipaddress(
1449 service->nameservers[i]) == AF_INET &&
1450 service->dns_config_method_ipv4 ==
1451 CONNMAN_DNSCONFIG_METHOD_DHCP) {
1452 nameserver_add(service,
1453 service->nameservers[i]);
1455 if (connman_inet_check_ipaddress(
1456 service->nameservers[i]) == AF_INET6 &&
1457 service->dns_config_method_ipv6 ==
1458 CONNMAN_DNSCONFIG_METHOD_DHCP) {
1459 nameserver_add(service,
1460 service->nameservers[i]);
1463 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1464 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
1467 DBG("default case do nothing");
1471 nameserver_add(service, service->nameservers[i]);
1480 static int nameserver_remove(struct connman_service *service,
1481 const char *nameserver)
1485 if (!nameserver_available(service, nameserver))
1488 index = __connman_service_get_index(service);
1492 #if defined TIZEN_EXT
1493 DBG("Resolver remove nameserver: %s", nameserver);
1495 return connman_resolver_remove(index, NULL, nameserver);
1498 #if defined TIZEN_EXT
1499 static int nameserver_remove_all(struct connman_service *service,
1500 enum connman_ipconfig_type type)
1502 static int nameserver_remove_all(struct connman_service *service)
1505 #if defined TIZEN_EXT
1507 * Skip this function if there is any connected profiles
1508 * that use same interface
1510 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
1511 __connman_service_get_connected_count_of_iface(service) > 0)
1516 index = __connman_service_get_index(service);
1520 while (service->nameservers_config && service->nameservers_config[i]) {
1521 #if defined TIZEN_EXT
1522 DBG("type %d Remove service->nameservers_config[%d]: %s",
1523 type, i, service->nameservers_config[i]);
1525 case CONNMAN_IPCONFIG_TYPE_IPV4:
1526 if (connman_inet_check_ipaddress(
1527 service->nameservers_config[i]) == AF_INET &&
1528 (service->dns_config_method_ipv4 ==
1529 CONNMAN_DNSCONFIG_METHOD_DHCP ||
1530 service->dns_config_method_ipv4 ==
1531 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
1532 nameserver_remove(service,
1533 service->nameservers_config[i]);
1536 case CONNMAN_IPCONFIG_TYPE_IPV6:
1537 if (connman_inet_check_ipaddress(
1538 service->nameservers_config[i]) == AF_INET6 &&
1539 (service->dns_config_method_ipv6 ==
1540 CONNMAN_DNSCONFIG_METHOD_DHCP ||
1541 service->dns_config_method_ipv6 ==
1542 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
1543 nameserver_remove(service,
1544 service->nameservers_config[i]);
1547 case CONNMAN_IPCONFIG_TYPE_ALL:
1548 if (connman_inet_check_ipaddress(
1549 service->nameservers_config[i]) == AF_INET &&
1550 (service->dns_config_method_ipv4 ==
1551 CONNMAN_DNSCONFIG_METHOD_DHCP ||
1552 service->dns_config_method_ipv4 ==
1553 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
1554 nameserver_remove(service,
1555 service->nameservers_config[i]);
1557 if (connman_inet_check_ipaddress(
1558 service->nameservers_config[i]) == AF_INET6 &&
1559 (service->dns_config_method_ipv6 ==
1560 CONNMAN_DNSCONFIG_METHOD_DHCP ||
1561 service->dns_config_method_ipv6 ==
1562 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
1563 nameserver_remove(service,
1564 service->nameservers_config[i]);
1567 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1568 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
1571 DBG("default case do nothing");
1575 nameserver_remove(service, service->nameservers_config[i]);
1581 while (service->nameservers && service->nameservers[i]) {
1582 #if defined TIZEN_EXT
1583 DBG("type %d Remove service->nameservers[%d]: %s",type, i,
1584 service->nameservers[i]);
1586 case CONNMAN_IPCONFIG_TYPE_IPV4:
1587 if (connman_inet_check_ipaddress(
1588 service->nameservers[i]) == AF_INET &&
1589 (service->dns_config_method_ipv4 ==
1590 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
1591 service->dns_config_method_ipv4 ==
1592 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
1593 nameserver_remove(service,
1594 service->nameservers[i]);
1597 case CONNMAN_IPCONFIG_TYPE_IPV6:
1598 if (connman_inet_check_ipaddress(
1599 service->nameservers[i]) == AF_INET6 &&
1600 (service->dns_config_method_ipv6 ==
1601 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
1602 service->dns_config_method_ipv6 ==
1603 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
1604 nameserver_remove(service,
1605 service->nameservers[i]);
1608 case CONNMAN_IPCONFIG_TYPE_ALL:
1609 if (connman_inet_check_ipaddress(
1610 service->nameservers[i]) == AF_INET &&
1611 (service->dns_config_method_ipv4 ==
1612 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
1613 service->dns_config_method_ipv4 ==
1614 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
1615 nameserver_remove(service,
1616 service->nameservers[i]);
1618 if (connman_inet_check_ipaddress(
1619 service->nameservers[i]) == AF_INET6 &&
1620 (service->dns_config_method_ipv6 ==
1621 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
1622 service->dns_config_method_ipv6 ==
1623 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
1624 nameserver_remove(service,
1625 service->nameservers[i]);
1628 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1629 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
1632 DBG("default case do nothing");
1636 nameserver_remove(service, service->nameservers[i]);
1644 static int searchdomain_add_all(struct connman_service *service)
1648 if (!is_connected(service))
1651 index = __connman_service_get_index(service);
1655 if (service->domains) {
1656 while (service->domains[i]) {
1657 connman_resolver_append(index, service->domains[i],
1665 if (service->domainname)
1666 connman_resolver_append(index, service->domainname, NULL);
1672 static int searchdomain_remove_all(struct connman_service *service)
1676 if (!is_connected(service))
1679 index = __connman_service_get_index(service);
1683 while (service->domains && service->domains[i]) {
1684 connman_resolver_remove(index, service->domains[i], NULL);
1688 if (service->domainname)
1689 connman_resolver_remove(index, service->domainname, NULL);
1695 * The is_auto variable is set to true when IPv6 autoconf nameservers are
1696 * inserted to resolver via netlink message (see rtnl.c:rtnl_newnduseropt()
1697 * for details) and not through service.c
1699 #if defined TIZEN_EXT
1700 int __connman_service_nameserver_append(struct connman_service *service,
1701 const char *nameserver, bool is_auto,
1702 enum connman_ipconfig_type type)
1704 int __connman_service_nameserver_append(struct connman_service *service,
1705 const char *nameserver, bool is_auto)
1711 DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
1717 nameservers = service->nameservers_auto;
1719 nameservers = service->nameservers;
1721 for (i = 0; nameservers && nameservers[i]; i++)
1722 #if defined TIZEN_EXT
1724 DBG("nameservers[%d] %s, nameserver %s", i, nameservers[i], nameserver);
1726 if (g_strcmp0(nameservers[i], nameserver) == 0)
1728 #if defined TIZEN_EXT
1733 len = g_strv_length(nameservers);
1734 nameservers = g_try_renew(char *, nameservers, len + 2);
1737 nameservers = g_try_new0(char *, len + 2);
1743 nameservers[len] = g_strdup(nameserver);
1744 nameservers[len + 1] = NULL;
1747 if(type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
1748 service->dns_config_method_ipv4 ==
1749 CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
1750 service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
1752 if(type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
1753 service->dns_config_method_ipv6 ==
1754 CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
1755 service->dns_config_method_ipv6 = CONNMAN_DNSCONFIG_METHOD_DHCP;
1759 service->nameservers_auto = nameservers;
1761 service->nameservers = nameservers;
1762 #if defined TIZEN_EXT
1763 DBG("nameserver add: %s, type: %d", nameserver, type);
1765 nameserver_add(service, nameserver);
1771 #if defined TIZEN_EXT
1772 int __connman_service_nameserver_remove(struct connman_service *service,
1773 const char *nameserver, bool is_auto,
1774 enum connman_ipconfig_type type)
1776 int __connman_service_nameserver_remove(struct connman_service *service,
1777 const char *nameserver, bool is_auto)
1780 char **servers, **nameservers;
1784 DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
1790 nameservers = service->nameservers_auto;
1792 nameservers = service->nameservers;
1797 for (i = 0; nameservers && nameservers[i]; i++)
1798 if (g_strcmp0(nameservers[i], nameserver) == 0) {
1806 len = g_strv_length(nameservers);
1813 servers = g_try_new0(char *, len);
1817 for (i = 0, j = 0; i < len; i++) {
1818 if (g_strcmp0(nameservers[i], nameserver)) {
1819 servers[j] = nameservers[i];
1822 g_free(nameservers[i]);
1824 nameservers[i] = NULL;
1826 servers[len - 1] = NULL;
1829 g_strfreev(nameservers);
1830 nameservers = servers;
1833 service->nameservers_auto = nameservers;
1835 service->nameservers = nameservers;
1836 #if defined TIZEN_EXT
1837 DBG("nameserver remove ip_type: %d", type);
1839 nameserver_remove(service, nameserver);
1845 void __connman_service_nameserver_clear(struct connman_service *service)
1847 #if defined TIZEN_EXT
1848 DBG("nameserver remove all ip_type: CONNMAN_IPCONFIG_TYPE_ALL");
1849 nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
1851 nameserver_remove_all(service);
1854 g_strfreev(service->nameservers);
1855 service->nameservers = NULL;
1857 #if defined TIZEN_EXT
1858 DBG("nameserver add all ip_type: CONNMAN_IPCONFIG_TYPE_ALL");
1859 nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
1861 nameserver_add_all(service);
1866 static void add_nameserver_route(int family, int index, char *nameserver,
1871 if (connman_inet_compare_subnet(index, nameserver))
1874 if (connman_inet_add_host_route(index, nameserver, gw) < 0)
1875 /* For P-t-P link the above route add will fail */
1876 connman_inet_add_host_route(index, nameserver, NULL);
1880 if (connman_inet_add_ipv6_host_route(index, nameserver,
1882 connman_inet_add_ipv6_host_route(index, nameserver,
1888 static void nameserver_add_routes(int index, char **nameservers,
1891 int i, ns_family, gw_family;
1893 gw_family = connman_inet_check_ipaddress(gw);
1897 for (i = 0; nameservers[i]; i++) {
1898 ns_family = connman_inet_check_ipaddress(nameservers[i]);
1899 if (ns_family < 0 || ns_family != gw_family)
1902 add_nameserver_route(ns_family, index, nameservers[i], gw);
1906 static void nameserver_del_routes(int index, char **nameservers,
1907 enum connman_ipconfig_type type)
1911 for (i = 0; nameservers[i]; i++) {
1912 family = connman_inet_check_ipaddress(nameservers[i]);
1918 if (type != CONNMAN_IPCONFIG_TYPE_IPV6)
1919 connman_inet_del_host_route(index,
1923 if (type != CONNMAN_IPCONFIG_TYPE_IPV4)
1924 connman_inet_del_ipv6_host_route(index,
1931 void __connman_service_nameserver_add_routes(struct connman_service *service,
1939 index = __connman_service_get_index(service);
1941 if (service->nameservers_config) {
1943 * Configured nameserver takes preference over the
1944 * discoverd nameserver gathered from DHCP, VPN, etc.
1946 nameserver_add_routes(index, service->nameservers_config, gw);
1947 } else if (service->nameservers) {
1949 * We add nameservers host routes for nameservers that
1950 * are not on our subnet. For those who are, the subnet
1951 * route will be installed by the time the dns proxy code
1952 * tries to reach them. The subnet route is installed
1953 * when setting the interface IP address.
1955 nameserver_add_routes(index, service->nameservers, gw);
1959 void __connman_service_nameserver_del_routes(struct connman_service *service,
1960 enum connman_ipconfig_type type)
1967 index = __connman_service_get_index(service);
1969 if (service->nameservers_config)
1970 nameserver_del_routes(index, service->nameservers_config,
1972 else if (service->nameservers)
1973 nameserver_del_routes(index, service->nameservers, type);
1976 static struct connman_stats *stats_get(struct connman_service *service)
1978 if (service->roaming)
1979 return &service->stats_roaming;
1981 return &service->stats;
1984 static bool stats_enabled(struct connman_service *service)
1986 struct connman_stats *stats = stats_get(service);
1988 return stats->enabled;
1991 static void stats_start(struct connman_service *service)
1993 struct connman_stats *stats = stats_get(service);
1995 DBG("service %p", service);
2000 stats->enabled = true;
2001 stats->data_last.time = stats->data.time;
2003 g_timer_start(stats->timer);
2006 static void stats_stop(struct connman_service *service)
2008 struct connman_stats *stats = stats_get(service);
2009 unsigned int seconds;
2011 DBG("service %p", service);
2016 if (!stats->enabled)
2019 g_timer_stop(stats->timer);
2021 seconds = g_timer_elapsed(stats->timer, NULL);
2022 stats->data.time = stats->data_last.time + seconds;
2024 stats->enabled = false;
2027 static void reset_stats(struct connman_service *service)
2029 DBG("service %p", service);
2032 service->stats.valid = false;
2034 service->stats.data.rx_packets = 0;
2035 service->stats.data.tx_packets = 0;
2036 service->stats.data.rx_bytes = 0;
2037 service->stats.data.tx_bytes = 0;
2038 service->stats.data.rx_errors = 0;
2039 service->stats.data.tx_errors = 0;
2040 service->stats.data.rx_dropped = 0;
2041 service->stats.data.tx_dropped = 0;
2042 service->stats.data.time = 0;
2043 service->stats.data_last.time = 0;
2045 g_timer_reset(service->stats.timer);
2048 service->stats_roaming.valid = false;
2050 service->stats_roaming.data.rx_packets = 0;
2051 service->stats_roaming.data.tx_packets = 0;
2052 service->stats_roaming.data.rx_bytes = 0;
2053 service->stats_roaming.data.tx_bytes = 0;
2054 service->stats_roaming.data.rx_errors = 0;
2055 service->stats_roaming.data.tx_errors = 0;
2056 service->stats_roaming.data.rx_dropped = 0;
2057 service->stats_roaming.data.tx_dropped = 0;
2058 service->stats_roaming.data.time = 0;
2059 service->stats_roaming.data_last.time = 0;
2061 g_timer_reset(service->stats_roaming.timer);
2064 #if defined TIZEN_EXT
2065 static gboolean __connman_service_is_internet_profile(
2066 struct connman_service *cellular)
2068 const char internet_suffix[] = "_1";
2070 DBG("Service path: %s", cellular->path);
2072 if (g_str_has_suffix(cellular->path, internet_suffix) == TRUE)
2078 static gboolean __connman_service_is_tethering_profile(
2079 struct connman_service *cellular)
2081 const char tethering_suffix[] = "_5";
2083 DBG("Service path: %s", cellular->path);
2085 if (g_str_has_suffix(cellular->path, tethering_suffix) == TRUE)
2091 struct connman_service *connman_service_get_default_connection(void)
2094 struct connman_service *service;
2095 struct connman_service *default_service = NULL;
2097 for (list = service_list; list; list = list->next) {
2098 service = list->data;
2100 DBG("service: %p %s %s %s", service, service->name,
2101 state2string(service->state),
2102 __connman_service_type2string(service->type));
2104 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
2105 is_connected(service) == TRUE) {
2107 } else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
2108 __connman_service_is_internet_profile(service) == TRUE) {
2109 if (default_service == NULL)
2110 default_service = service;
2111 else if (is_connected(service) == TRUE &&
2112 is_connected(default_service) == FALSE)
2113 default_service = service;
2114 } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET &&
2115 is_connected(service) == TRUE) {
2116 if (default_service == NULL)
2117 default_service = service;
2118 } else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH &&
2119 is_connected(service) == TRUE) {
2120 if (default_service == NULL)
2121 default_service = service;
2125 return default_service;
2129 struct connman_service *__connman_service_get_default(void)
2131 struct connman_service *service;
2136 service = service_list->data;
2138 if (!is_connected(service))
2144 bool __connman_service_index_is_default(int index)
2146 struct connman_service *service;
2151 service = __connman_service_get_default();
2153 return __connman_service_get_index(service) == index;
2156 static void default_changed(void)
2158 struct connman_service *service = __connman_service_get_default();
2160 if (service == current_default)
2163 DBG("current default %p %s", current_default,
2164 current_default ? current_default->identifier : "");
2165 DBG("new default %p %s", service, service ? service->identifier : "");
2167 #if defined TIZEN_EXT
2168 current_default = service;
2170 __connman_service_timeserver_changed(service, NULL);
2172 __connman_service_timeserver_changed(current_default, NULL);
2174 current_default = service;
2178 if (service->hostname &&
2179 connman_setting_get_bool("AllowHostnameUpdates"))
2180 __connman_utsname_set_hostname(service->hostname);
2182 if (service->domainname)
2183 __connman_utsname_set_domainname(service->domainname);
2186 __connman_notifier_default_changed(service);
2189 static void state_changed(struct connman_service *service)
2193 __connman_notifier_service_state_changed(service, service->state);
2195 str = state2string(service->state);
2199 #if !defined TIZEN_EXT
2200 if (!allow_property_changed(service))
2203 #if defined TIZEN_EXT
2204 DBG(" %s, %s", str, service->path);
2206 connman_dbus_property_changed_basic(service->path,
2207 CONNMAN_SERVICE_INTERFACE, "State",
2208 DBUS_TYPE_STRING, &str);
2211 static void strength_changed(struct connman_service *service)
2213 if (service->strength == 0)
2216 if (!allow_property_changed(service))
2219 connman_dbus_property_changed_basic(service->path,
2220 CONNMAN_SERVICE_INTERFACE, "Strength",
2221 DBUS_TYPE_BYTE, &service->strength);
2224 static void favorite_changed(struct connman_service *service)
2226 dbus_bool_t favorite;
2231 if (!allow_property_changed(service))
2234 favorite = service->favorite;
2235 connman_dbus_property_changed_basic(service->path,
2236 CONNMAN_SERVICE_INTERFACE, "Favorite",
2237 DBUS_TYPE_BOOLEAN, &favorite);
2240 static void immutable_changed(struct connman_service *service)
2242 dbus_bool_t immutable;
2247 if (!allow_property_changed(service))
2250 immutable = service->immutable;
2251 connman_dbus_property_changed_basic(service->path,
2252 CONNMAN_SERVICE_INTERFACE, "Immutable",
2253 DBUS_TYPE_BOOLEAN, &immutable);
2256 static void roaming_changed(struct connman_service *service)
2258 dbus_bool_t roaming;
2263 if (!allow_property_changed(service))
2266 roaming = service->roaming;
2267 connman_dbus_property_changed_basic(service->path,
2268 CONNMAN_SERVICE_INTERFACE, "Roaming",
2269 DBUS_TYPE_BOOLEAN, &roaming);
2272 static void autoconnect_changed(struct connman_service *service)
2274 dbus_bool_t autoconnect;
2279 if (!allow_property_changed(service))
2282 autoconnect = service->autoconnect;
2283 connman_dbus_property_changed_basic(service->path,
2284 CONNMAN_SERVICE_INTERFACE, "AutoConnect",
2285 DBUS_TYPE_BOOLEAN, &autoconnect);
2288 static void append_security(DBusMessageIter *iter, void *user_data)
2290 struct connman_service *service = user_data;
2293 str = security2string(service->security);
2295 dbus_message_iter_append_basic(iter,
2296 DBUS_TYPE_STRING, &str);
2299 * Some access points incorrectly advertise WPS even when they
2300 * are configured as open or no security, so filter
2304 switch (service->security) {
2305 case CONNMAN_SERVICE_SECURITY_PSK:
2306 case CONNMAN_SERVICE_SECURITY_WPA:
2307 case CONNMAN_SERVICE_SECURITY_RSN:
2309 dbus_message_iter_append_basic(iter,
2310 DBUS_TYPE_STRING, &str);
2312 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
2313 case CONNMAN_SERVICE_SECURITY_NONE:
2314 case CONNMAN_SERVICE_SECURITY_WEP:
2315 case CONNMAN_SERVICE_SECURITY_8021X:
2321 static void append_ethernet(DBusMessageIter *iter, void *user_data)
2323 struct connman_service *service = user_data;
2325 if (service->ipconfig_ipv4)
2326 __connman_ipconfig_append_ethernet(service->ipconfig_ipv4,
2328 else if (service->ipconfig_ipv6)
2329 __connman_ipconfig_append_ethernet(service->ipconfig_ipv6,
2333 static void append_ipv4(DBusMessageIter *iter, void *user_data)
2335 struct connman_service *service = user_data;
2337 if (!is_connected_state(service, service->state_ipv4))
2340 if (service->ipconfig_ipv4)
2341 __connman_ipconfig_append_ipv4(service->ipconfig_ipv4, iter);
2344 static void append_ipv6(DBusMessageIter *iter, void *user_data)
2346 struct connman_service *service = user_data;
2348 if (!is_connected_state(service, service->state_ipv6))
2351 if (service->ipconfig_ipv6)
2352 __connman_ipconfig_append_ipv6(service->ipconfig_ipv6, iter,
2353 service->ipconfig_ipv4);
2356 static void append_ipv4config(DBusMessageIter *iter, void *user_data)
2358 struct connman_service *service = user_data;
2360 if (service->ipconfig_ipv4)
2361 __connman_ipconfig_append_ipv4config(service->ipconfig_ipv4,
2365 static void append_ipv6config(DBusMessageIter *iter, void *user_data)
2367 struct connman_service *service = user_data;
2369 if (service->ipconfig_ipv6)
2370 __connman_ipconfig_append_ipv6config(service->ipconfig_ipv6,
2374 static void append_nameservers(DBusMessageIter *iter,
2375 struct connman_service *service, char **servers)
2378 bool available = true;
2380 for (i = 0; servers[i]; i++) {
2382 available = nameserver_available(service, servers[i]);
2384 DBG("servers[%d] %s available %d", i, servers[i], available);
2387 dbus_message_iter_append_basic(iter,
2388 DBUS_TYPE_STRING, &servers[i]);
2392 #if defined TIZEN_EXT
2393 static void append_nameserver_manual(DBusMessageIter *iter,
2394 struct connman_service *service, const char *server)
2396 bool available = true;
2399 available = nameserver_available(service, server);
2402 dbus_message_iter_append_basic(iter,
2403 DBUS_TYPE_STRING, &server);
2406 static void append_nameserver_dhcp(DBusMessageIter *iter,
2407 struct connman_service *service, const char *server)
2409 bool available = true;
2412 available = nameserver_available(service, server);
2415 dbus_message_iter_append_basic(iter,
2416 DBUS_TYPE_STRING, &server);
2420 static void append_dns(DBusMessageIter *iter, void *user_data)
2422 struct connman_service *service = user_data;
2423 #if defined TIZEN_EXT
2427 if (!is_connected(service))
2433 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4);
2435 char *str1 = g_strdup_printf("ipv4.%s", str);
2436 dbus_message_iter_append_basic(iter,
2437 DBUS_TYPE_STRING, &str1);
2441 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6);
2443 char *str1 = g_strdup_printf("ipv6.%s", str);
2444 dbus_message_iter_append_basic(iter,
2445 DBUS_TYPE_STRING, &str1);
2450 if (service->nameservers_config) {
2451 #if defined TIZEN_EXT
2453 while (service->nameservers_config[i]) {
2454 if (connman_inet_check_ipaddress(
2455 service->nameservers_config[i]) == AF_INET &&
2456 service->dns_config_method_ipv4 ==
2457 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2458 append_nameserver_manual(iter, service,
2459 service->nameservers_config[i]);
2462 if (connman_inet_check_ipaddress(
2463 service->nameservers_config[i]) == AF_INET6 &&
2464 service->dns_config_method_ipv6 ==
2465 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2466 append_nameserver_manual(iter, service,
2467 service->nameservers_config[i]);
2471 /* In case of mixed DNS Config Type one of IPv4/IPv6 can be
2472 * dynamic while other is static so try to append the DNS
2473 * Address which is dynamic also */
2474 if (service->nameservers != NULL) {
2476 while (service->nameservers[i]) {
2477 if (connman_inet_check_ipaddress(
2478 service->nameservers[i]) == AF_INET &&
2479 service->dns_config_method_ipv4 ==
2480 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2481 append_nameserver_dhcp(iter, service,
2482 service->nameservers[i]);
2485 if (connman_inet_check_ipaddress(
2486 service->nameservers[i]) == AF_INET6 &&
2487 service->dns_config_method_ipv6 ==
2488 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2489 append_nameserver_dhcp(iter, service,
2490 service->nameservers[i]);
2496 append_nameservers(iter, service, service->nameservers_config);
2500 if (service->nameservers)
2501 #if defined TIZEN_EXT
2504 while (service->nameservers[i]) {
2505 if (connman_inet_check_ipaddress(
2506 service->nameservers[i]) == AF_INET &&
2507 service->dns_config_method_ipv4 ==
2508 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2509 append_nameserver_dhcp(iter, service,
2510 service->nameservers[i]);
2513 if (connman_inet_check_ipaddress(
2514 service->nameservers[i]) == AF_INET6 &&
2515 service->dns_config_method_ipv6 ==
2516 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2517 append_nameserver_dhcp(iter, service,
2518 service->nameservers[i]);
2524 append_nameservers(iter, service,
2525 service->nameservers);
2528 if (service->nameservers_auto)
2529 append_nameservers(iter, service,
2530 service->nameservers_auto);
2532 if (!service->nameservers && !service->nameservers_auto) {
2535 DBG("append fallback nameservers");
2537 ns = connman_setting_get_string_list("FallbackNameservers");
2539 append_nameservers(iter, service, ns);
2544 static void append_dnsconfig(DBusMessageIter *iter, void *user_data)
2546 struct connman_service *service = user_data;
2549 /* Append DNS Config Type */
2551 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4);
2553 char *str1 = g_strdup_printf("ipv4.%s", str);
2554 dbus_message_iter_append_basic(iter,
2555 DBUS_TYPE_STRING, &str1);
2559 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6);
2561 char *str1 = g_strdup_printf("ipv6.%s", str);
2562 dbus_message_iter_append_basic(iter,
2563 DBUS_TYPE_STRING, &str1);
2568 if (!service->nameservers_config)
2571 #if defined TIZEN_EXT
2573 while (service->nameservers_config[i]) {
2574 if (connman_inet_check_ipaddress(service->nameservers_config[i]) == AF_INET &&
2575 service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2576 append_nameserver_manual(iter, NULL, service->nameservers_config[i]);
2579 if (connman_inet_check_ipaddress(service->nameservers_config[i]) == AF_INET6 &&
2580 service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2581 append_nameserver_manual(iter, NULL, service->nameservers_config[i]);
2586 append_nameservers(iter, NULL, service->nameservers_config);
2590 static void append_ts(DBusMessageIter *iter, void *user_data)
2592 GSList *list = user_data;
2595 char *timeserver = list->data;
2598 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
2601 list = g_slist_next(list);
2605 static void append_tsconfig(DBusMessageIter *iter, void *user_data)
2607 struct connman_service *service = user_data;
2610 if (!service->timeservers_config)
2613 for (i = 0; service->timeservers_config[i]; i++) {
2614 dbus_message_iter_append_basic(iter,
2616 &service->timeservers_config[i]);
2620 static void append_domainconfig(DBusMessageIter *iter, void *user_data)
2622 struct connman_service *service = user_data;
2625 if (!service->domains)
2628 for (i = 0; service->domains[i]; i++)
2629 dbus_message_iter_append_basic(iter,
2630 DBUS_TYPE_STRING, &service->domains[i]);
2633 static void append_domain(DBusMessageIter *iter, void *user_data)
2635 struct connman_service *service = user_data;
2637 if (!is_connected(service) &&
2638 !is_connecting(service))
2641 if (service->domains)
2642 append_domainconfig(iter, user_data);
2643 else if (service->domainname)
2644 dbus_message_iter_append_basic(iter,
2645 DBUS_TYPE_STRING, &service->domainname);
2648 static void append_proxies(DBusMessageIter *iter, void *user_data)
2650 struct connman_service *service = user_data;
2653 if (!service->proxies)
2656 for (i = 0; service->proxies[i]; i++)
2657 dbus_message_iter_append_basic(iter,
2658 DBUS_TYPE_STRING, &service->proxies[i]);
2661 static void append_excludes(DBusMessageIter *iter, void *user_data)
2663 struct connman_service *service = user_data;
2666 if (!service->excludes)
2669 for (i = 0; service->excludes[i]; i++)
2670 dbus_message_iter_append_basic(iter,
2671 DBUS_TYPE_STRING, &service->excludes[i]);
2674 static void append_proxy(DBusMessageIter *iter, void *user_data)
2676 struct connman_service *service = user_data;
2677 enum connman_service_proxy_method proxy;
2678 const char *pac = NULL;
2679 const char *method = proxymethod2string(
2680 CONNMAN_SERVICE_PROXY_METHOD_DIRECT);
2682 if (!is_connected(service))
2685 proxy = connman_service_get_proxy_method(service);
2688 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
2690 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
2692 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
2693 connman_dbus_dict_append_array(iter, "Servers",
2694 DBUS_TYPE_STRING, append_proxies,
2697 connman_dbus_dict_append_array(iter, "Excludes",
2698 DBUS_TYPE_STRING, append_excludes,
2701 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
2702 /* Maybe DHCP, or WPAD, has provided an url for a pac file */
2703 if (service->ipconfig_ipv4)
2704 pac = __connman_ipconfig_get_proxy_autoconfig(
2705 service->ipconfig_ipv4);
2706 else if (service->ipconfig_ipv6)
2707 pac = __connman_ipconfig_get_proxy_autoconfig(
2708 service->ipconfig_ipv6);
2710 if (!service->pac && !pac)
2716 connman_dbus_dict_append_basic(iter, "URL",
2717 DBUS_TYPE_STRING, &pac);
2721 method = proxymethod2string(proxy);
2724 connman_dbus_dict_append_basic(iter, "Method",
2725 DBUS_TYPE_STRING, &method);
2728 static void append_proxyconfig(DBusMessageIter *iter, void *user_data)
2730 struct connman_service *service = user_data;
2733 if (service->proxy_config == CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN)
2736 switch (service->proxy_config) {
2737 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
2739 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
2741 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
2742 if (service->proxies)
2743 connman_dbus_dict_append_array(iter, "Servers",
2745 append_proxies, service);
2747 if (service->excludes)
2748 connman_dbus_dict_append_array(iter, "Excludes",
2750 append_excludes, service);
2752 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
2754 connman_dbus_dict_append_basic(iter, "URL",
2755 DBUS_TYPE_STRING, &service->pac);
2759 method = proxymethod2string(service->proxy_config);
2761 connman_dbus_dict_append_basic(iter, "Method",
2762 DBUS_TYPE_STRING, &method);
2765 static void append_provider(DBusMessageIter *iter, void *user_data)
2767 struct connman_service *service = user_data;
2769 if (!is_connected(service))
2772 if (service->provider)
2773 __connman_provider_append_properties(service->provider, iter);
2777 static void settings_changed(struct connman_service *service,
2778 struct connman_ipconfig *ipconfig)
2780 enum connman_ipconfig_type type;
2782 if (!allow_property_changed(service))
2785 type = __connman_ipconfig_get_config_type(ipconfig);
2787 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
2788 connman_dbus_property_changed_dict(service->path,
2789 CONNMAN_SERVICE_INTERFACE, "IPv4",
2790 append_ipv4, service);
2791 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
2792 connman_dbus_property_changed_dict(service->path,
2793 CONNMAN_SERVICE_INTERFACE, "IPv6",
2794 append_ipv6, service);
2796 __connman_notifier_ipconfig_changed(service, ipconfig);
2799 static void ipv4_configuration_changed(struct connman_service *service)
2801 if (!allow_property_changed(service))
2804 connman_dbus_property_changed_dict(service->path,
2805 CONNMAN_SERVICE_INTERFACE,
2806 "IPv4.Configuration",
2811 static void ipv6_configuration_changed(struct connman_service *service)
2813 if (!allow_property_changed(service))
2816 connman_dbus_property_changed_dict(service->path,
2817 CONNMAN_SERVICE_INTERFACE,
2818 "IPv6.Configuration",
2823 static void dns_changed(struct connman_service *service)
2825 if (!allow_property_changed(service))
2828 connman_dbus_property_changed_array(service->path,
2829 CONNMAN_SERVICE_INTERFACE, "Nameservers",
2830 DBUS_TYPE_STRING, append_dns, service);
2833 static void dns_configuration_changed(struct connman_service *service)
2835 if (!allow_property_changed(service))
2838 connman_dbus_property_changed_array(service->path,
2839 CONNMAN_SERVICE_INTERFACE,
2840 "Nameservers.Configuration",
2841 DBUS_TYPE_STRING, append_dnsconfig, service);
2843 dns_changed(service);
2846 static void domain_changed(struct connman_service *service)
2848 if (!allow_property_changed(service))
2851 connman_dbus_property_changed_array(service->path,
2852 CONNMAN_SERVICE_INTERFACE, "Domains",
2853 DBUS_TYPE_STRING, append_domain, service);
2856 static void domain_configuration_changed(struct connman_service *service)
2858 if (!allow_property_changed(service))
2861 connman_dbus_property_changed_array(service->path,
2862 CONNMAN_SERVICE_INTERFACE,
2863 "Domains.Configuration",
2864 DBUS_TYPE_STRING, append_domainconfig, service);
2867 static void proxy_changed(struct connman_service *service)
2869 if (!allow_property_changed(service))
2872 connman_dbus_property_changed_dict(service->path,
2873 CONNMAN_SERVICE_INTERFACE, "Proxy",
2874 append_proxy, service);
2877 static void proxy_configuration_changed(struct connman_service *service)
2879 if (!allow_property_changed(service))
2882 connman_dbus_property_changed_dict(service->path,
2883 CONNMAN_SERVICE_INTERFACE, "Proxy.Configuration",
2884 append_proxyconfig, service);
2886 proxy_changed(service);
2889 static void timeservers_configuration_changed(struct connman_service *service)
2891 if (!allow_property_changed(service))
2894 connman_dbus_property_changed_array(service->path,
2895 CONNMAN_SERVICE_INTERFACE,
2896 "Timeservers.Configuration",
2898 append_tsconfig, service);
2901 static void link_changed(struct connman_service *service)
2903 if (!allow_property_changed(service))
2906 connman_dbus_property_changed_dict(service->path,
2907 CONNMAN_SERVICE_INTERFACE, "Ethernet",
2908 append_ethernet, service);
2911 static void stats_append_counters(DBusMessageIter *dict,
2912 struct connman_stats_data *stats,
2913 struct connman_stats_data *counters,
2916 if (counters->rx_packets != stats->rx_packets || append_all) {
2917 counters->rx_packets = stats->rx_packets;
2918 connman_dbus_dict_append_basic(dict, "RX.Packets",
2919 DBUS_TYPE_UINT32, &stats->rx_packets);
2922 if (counters->tx_packets != stats->tx_packets || append_all) {
2923 counters->tx_packets = stats->tx_packets;
2924 connman_dbus_dict_append_basic(dict, "TX.Packets",
2925 DBUS_TYPE_UINT32, &stats->tx_packets);
2928 if (counters->rx_bytes != stats->rx_bytes || append_all) {
2929 counters->rx_bytes = stats->rx_bytes;
2930 connman_dbus_dict_append_basic(dict, "RX.Bytes",
2931 DBUS_TYPE_UINT32, &stats->rx_bytes);
2934 if (counters->tx_bytes != stats->tx_bytes || append_all) {
2935 counters->tx_bytes = stats->tx_bytes;
2936 connman_dbus_dict_append_basic(dict, "TX.Bytes",
2937 DBUS_TYPE_UINT32, &stats->tx_bytes);
2940 if (counters->rx_errors != stats->rx_errors || append_all) {
2941 counters->rx_errors = stats->rx_errors;
2942 connman_dbus_dict_append_basic(dict, "RX.Errors",
2943 DBUS_TYPE_UINT32, &stats->rx_errors);
2946 if (counters->tx_errors != stats->tx_errors || append_all) {
2947 counters->tx_errors = stats->tx_errors;
2948 connman_dbus_dict_append_basic(dict, "TX.Errors",
2949 DBUS_TYPE_UINT32, &stats->tx_errors);
2952 if (counters->rx_dropped != stats->rx_dropped || append_all) {
2953 counters->rx_dropped = stats->rx_dropped;
2954 connman_dbus_dict_append_basic(dict, "RX.Dropped",
2955 DBUS_TYPE_UINT32, &stats->rx_dropped);
2958 if (counters->tx_dropped != stats->tx_dropped || append_all) {
2959 counters->tx_dropped = stats->tx_dropped;
2960 connman_dbus_dict_append_basic(dict, "TX.Dropped",
2961 DBUS_TYPE_UINT32, &stats->tx_dropped);
2964 if (counters->time != stats->time || append_all) {
2965 counters->time = stats->time;
2966 connman_dbus_dict_append_basic(dict, "Time",
2967 DBUS_TYPE_UINT32, &stats->time);
2971 static void stats_append(struct connman_service *service,
2972 const char *counter,
2973 struct connman_stats_counter *counters,
2976 DBusMessageIter array, dict;
2979 DBG("service %p counter %s", service, counter);
2981 msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
2985 dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH,
2986 &service->path, DBUS_TYPE_INVALID);
2988 dbus_message_iter_init_append(msg, &array);
2991 connman_dbus_dict_open(&array, &dict);
2993 stats_append_counters(&dict, &service->stats.data,
2994 &counters->stats.data, append_all);
2996 connman_dbus_dict_close(&array, &dict);
2998 /* roaming counter */
2999 connman_dbus_dict_open(&array, &dict);
3001 stats_append_counters(&dict, &service->stats_roaming.data,
3002 &counters->stats_roaming.data, append_all);
3004 connman_dbus_dict_close(&array, &dict);
3006 __connman_counter_send_usage(counter, msg);
3009 static void stats_update(struct connman_service *service,
3010 unsigned int rx_packets, unsigned int tx_packets,
3011 unsigned int rx_bytes, unsigned int tx_bytes,
3012 unsigned int rx_errors, unsigned int tx_errors,
3013 unsigned int rx_dropped, unsigned int tx_dropped)
3015 struct connman_stats *stats = stats_get(service);
3016 struct connman_stats_data *data_last = &stats->data_last;
3017 struct connman_stats_data *data = &stats->data;
3018 unsigned int seconds;
3020 DBG("service %p", service);
3024 rx_packets - data_last->rx_packets;
3026 tx_packets - data_last->tx_packets;
3028 rx_bytes - data_last->rx_bytes;
3030 tx_bytes - data_last->tx_bytes;
3032 rx_errors - data_last->rx_errors;
3034 tx_errors - data_last->tx_errors;
3036 rx_dropped - data_last->rx_dropped;
3038 tx_dropped - data_last->tx_dropped;
3040 stats->valid = true;
3043 data_last->rx_packets = rx_packets;
3044 data_last->tx_packets = tx_packets;
3045 data_last->rx_bytes = rx_bytes;
3046 data_last->tx_bytes = tx_bytes;
3047 data_last->rx_errors = rx_errors;
3048 data_last->tx_errors = tx_errors;
3049 data_last->rx_dropped = rx_dropped;
3050 data_last->tx_dropped = tx_dropped;
3052 seconds = g_timer_elapsed(stats->timer, NULL);
3053 stats->data.time = stats->data_last.time + seconds;
3056 void __connman_service_notify(struct connman_service *service,
3057 unsigned int rx_packets, unsigned int tx_packets,
3058 unsigned int rx_bytes, unsigned int tx_bytes,
3059 unsigned int rx_errors, unsigned int tx_errors,
3060 unsigned int rx_dropped, unsigned int tx_dropped)
3062 GHashTableIter iter;
3063 gpointer key, value;
3064 const char *counter;
3065 struct connman_stats_counter *counters;
3066 struct connman_stats_data *data;
3072 if (!is_connected(service))
3075 stats_update(service,
3076 rx_packets, tx_packets,
3078 rx_errors, tx_errors,
3079 rx_dropped, tx_dropped);
3081 data = &stats_get(service)->data;
3082 err = __connman_stats_update(service, service->roaming, data);
3084 connman_error("Failed to store statistics for %s",
3085 service->identifier);
3087 g_hash_table_iter_init(&iter, service->counter_table);
3088 while (g_hash_table_iter_next(&iter, &key, &value)) {
3092 stats_append(service, counter, counters, counters->append_all);
3093 counters->append_all = false;
3097 int __connman_service_counter_register(const char *counter)
3099 struct connman_service *service;
3101 struct connman_stats_counter *counters;
3103 DBG("counter %s", counter);
3105 counter_list = g_slist_prepend(counter_list, (gpointer)counter);
3107 for (list = service_list; list; list = list->next) {
3108 service = list->data;
3110 counters = g_try_new0(struct connman_stats_counter, 1);
3114 counters->append_all = true;
3116 g_hash_table_replace(service->counter_table, (gpointer)counter,
3123 void __connman_service_counter_unregister(const char *counter)
3125 struct connman_service *service;
3128 DBG("counter %s", counter);
3130 for (list = service_list; list; list = list->next) {
3131 service = list->data;
3133 g_hash_table_remove(service->counter_table, counter);
3136 counter_list = g_slist_remove(counter_list, counter);
3139 int __connman_service_iterate_services(service_iterate_cb cb, void *user_data)
3143 for (list = service_list; list; list = list->next) {
3144 struct connman_service *service = list->data;
3146 cb(service, user_data);
3152 #if defined TIZEN_EXT
3153 static void append_wifi_ext_info(DBusMessageIter *dict,
3154 struct connman_network *network)
3156 char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
3157 char *bssid_str = bssid_buff;
3159 unsigned int ssid_len;
3160 unsigned char *bssid;
3161 unsigned int maxrate;
3162 unsigned int keymgmt;
3164 const char *enc_mode;
3167 ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len);
3168 bssid = connman_network_get_bssid(network);
3169 maxrate = connman_network_get_maxrate(network);
3170 frequency = connman_network_get_frequency(network);
3171 enc_mode = connman_network_get_enc_mode(network);
3172 passpoint = connman_network_get_is_hs20AP(network);
3173 keymgmt = connman_network_get_keymgmt(network);
3175 snprintf(bssid_str, WIFI_BSSID_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
3176 bssid[0], bssid[1], bssid[2],
3177 bssid[3], bssid[4], bssid[5]);
3179 connman_dbus_dict_append_fixed_array(dict, "SSID",
3180 DBUS_TYPE_BYTE, &ssid, ssid_len);
3181 connman_dbus_dict_append_basic(dict, "BSSID",
3182 DBUS_TYPE_STRING, &bssid_str);
3183 connman_dbus_dict_append_basic(dict, "MaxRate",
3184 DBUS_TYPE_UINT32, &maxrate);
3185 connman_dbus_dict_append_basic(dict, "Frequency",
3186 DBUS_TYPE_UINT16, &frequency);
3187 connman_dbus_dict_append_basic(dict, "EncryptionMode",
3188 DBUS_TYPE_STRING, &enc_mode);
3189 connman_dbus_dict_append_basic(dict, "Passpoint",
3190 DBUS_TYPE_BOOLEAN, &passpoint);
3191 connman_dbus_dict_append_basic(dict, "Keymgmt",
3192 DBUS_TYPE_UINT32, &keymgmt);
3196 static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
3197 struct connman_service *service)
3203 #if defined TIZEN_EXT
3204 unsigned int frequency = 0U;
3205 if (service && service->network) {
3206 frequency = connman_network_get_frequency(service->network);
3207 connman_dbus_dict_append_basic(dict, "Frequency",
3208 DBUS_TYPE_UINT16, &frequency);
3212 str = __connman_service_type2string(service->type);
3214 connman_dbus_dict_append_basic(dict, "Type",
3215 DBUS_TYPE_STRING, &str);
3217 connman_dbus_dict_append_array(dict, "Security",
3218 DBUS_TYPE_STRING, append_security, service);
3220 str = state2string(service->state);
3222 connman_dbus_dict_append_basic(dict, "State",
3223 DBUS_TYPE_STRING, &str);
3226 str = state2string(service->state_ipv6);
3228 connman_dbus_dict_append_basic(dict, "StateIPv6",
3229 DBUS_TYPE_STRING, &str);
3232 str = error2string(service->error);
3234 connman_dbus_dict_append_basic(dict, "Error",
3235 DBUS_TYPE_STRING, &str);
3237 if (service->strength > 0)
3238 connman_dbus_dict_append_basic(dict, "Strength",
3239 DBUS_TYPE_BYTE, &service->strength);
3241 val = service->favorite;
3242 connman_dbus_dict_append_basic(dict, "Favorite",
3243 DBUS_TYPE_BOOLEAN, &val);
3245 val = service->immutable;
3246 connman_dbus_dict_append_basic(dict, "Immutable",
3247 DBUS_TYPE_BOOLEAN, &val);
3249 if (service->favorite)
3250 val = service->autoconnect;
3252 val = service->favorite;
3254 connman_dbus_dict_append_basic(dict, "AutoConnect",
3255 DBUS_TYPE_BOOLEAN, &val);
3258 connman_dbus_dict_append_basic(dict, "Name",
3259 DBUS_TYPE_STRING, &service->name);
3261 switch (service->type) {
3262 case CONNMAN_SERVICE_TYPE_UNKNOWN:
3263 case CONNMAN_SERVICE_TYPE_SYSTEM:
3264 case CONNMAN_SERVICE_TYPE_GPS:
3265 case CONNMAN_SERVICE_TYPE_VPN:
3266 case CONNMAN_SERVICE_TYPE_P2P:
3268 case CONNMAN_SERVICE_TYPE_CELLULAR:
3269 val = service->roaming;
3270 connman_dbus_dict_append_basic(dict, "Roaming",
3271 DBUS_TYPE_BOOLEAN, &val);
3273 connman_dbus_dict_append_dict(dict, "Ethernet",
3274 append_ethernet, service);
3276 case CONNMAN_SERVICE_TYPE_WIFI:
3277 #if defined TIZEN_EXT
3278 if (service->network != NULL)
3279 append_wifi_ext_info(dict, service->network);
3281 connman_dbus_dict_append_dict(dict, "Ethernet",
3282 append_ethernet, service);
3284 connman_dbus_dict_append_basic(dict, "DisconnectReason",
3285 DBUS_TYPE_INT32, &service->disconnect_reason);
3289 case CONNMAN_SERVICE_TYPE_ETHERNET:
3290 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
3291 case CONNMAN_SERVICE_TYPE_GADGET:
3292 connman_dbus_dict_append_dict(dict, "Ethernet",
3293 append_ethernet, service);
3297 connman_dbus_dict_append_dict(dict, "IPv4", append_ipv4, service);
3299 connman_dbus_dict_append_dict(dict, "IPv4.Configuration",
3300 append_ipv4config, service);
3302 connman_dbus_dict_append_dict(dict, "IPv6", append_ipv6, service);
3304 connman_dbus_dict_append_dict(dict, "IPv6.Configuration",
3305 append_ipv6config, service);
3307 connman_dbus_dict_append_array(dict, "Nameservers",
3308 DBUS_TYPE_STRING, append_dns, service);
3310 connman_dbus_dict_append_array(dict, "Nameservers.Configuration",
3311 DBUS_TYPE_STRING, append_dnsconfig, service);
3313 if (service->state == CONNMAN_SERVICE_STATE_READY ||
3314 service->state == CONNMAN_SERVICE_STATE_ONLINE)
3315 list = __connman_timeserver_get_all(service);
3319 connman_dbus_dict_append_array(dict, "Timeservers",
3320 DBUS_TYPE_STRING, append_ts, list);
3322 g_slist_free_full(list, g_free);
3324 connman_dbus_dict_append_array(dict, "Timeservers.Configuration",
3325 DBUS_TYPE_STRING, append_tsconfig, service);
3327 connman_dbus_dict_append_array(dict, "Domains",
3328 DBUS_TYPE_STRING, append_domain, service);
3330 connman_dbus_dict_append_array(dict, "Domains.Configuration",
3331 DBUS_TYPE_STRING, append_domainconfig, service);
3333 connman_dbus_dict_append_dict(dict, "Proxy", append_proxy, service);
3335 connman_dbus_dict_append_dict(dict, "Proxy.Configuration",
3336 append_proxyconfig, service);
3338 connman_dbus_dict_append_dict(dict, "Provider",
3339 append_provider, service);
3342 static void append_struct_service(DBusMessageIter *iter,
3343 connman_dbus_append_cb_t function,
3344 struct connman_service *service)
3346 DBusMessageIter entry, dict;
3348 dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &entry);
3350 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
3353 connman_dbus_dict_open(&entry, &dict);
3355 function(&dict, service);
3356 connman_dbus_dict_close(&entry, &dict);
3358 dbus_message_iter_close_container(iter, &entry);
3361 static void append_dict_properties(DBusMessageIter *dict, void *user_data)
3363 struct connman_service *service = user_data;
3365 append_properties(dict, TRUE, service);
3368 static void append_struct(gpointer value, gpointer user_data)
3370 struct connman_service *service = value;
3371 DBusMessageIter *iter = user_data;
3376 append_struct_service(iter, append_dict_properties, service);
3379 void __connman_service_list_struct(DBusMessageIter *iter)
3381 g_list_foreach(service_list, append_struct, iter);
3384 #if defined TIZEN_EXT
3385 static void append_wifi_vsie_properties(DBusMessageIter *iter,
3386 struct connman_service *service)
3388 DBusMessageIter dict;
3389 const void *wifi_vsie;
3390 unsigned int wifi_vsie_len;
3392 connman_dbus_dict_open(iter, &dict);
3394 wifi_vsie = connman_network_get_blob(service->network, "WiFi.Vsie", &wifi_vsie_len);
3396 if(wifi_vsie_len > 0) {
3397 DBG("ConnMan, service->path=%s vsie length=%d", service->path, wifi_vsie_len);
3400 connman_dbus_dict_append_fixed_array(&dict, "Vsie", DBUS_TYPE_BYTE,
3401 &wifi_vsie, wifi_vsie_len);
3403 connman_dbus_dict_close(iter, &dict);
3406 void __connman_wifi_vsie_list_struct(DBusMessageIter *iter)
3409 DBusMessageIter entry;
3411 DBG("ConnMan, __connman_wifi_vsie_list_struct API called");
3413 for (list = service_list; list; list = list->next) {
3414 struct connman_service *service = list->data;
3416 if (!service->path ||
3417 service->type != CONNMAN_SERVICE_TYPE_WIFI ||
3418 service->network == NULL)
3421 dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT,
3423 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
3425 append_wifi_vsie_properties(&entry, service);
3426 dbus_message_iter_close_container(iter, &entry);
3431 bool __connman_service_is_hidden(struct connman_service *service)
3433 return service->hidden;
3437 __connman_service_is_split_routing(struct connman_service *service)
3439 return service->do_split_routing;
3442 bool __connman_service_index_is_split_routing(int index)
3444 struct connman_service *service;
3449 service = __connman_service_lookup_from_index(index);
3453 return __connman_service_is_split_routing(service);
3456 int __connman_service_get_index(struct connman_service *service)
3461 if (service->network)
3462 return connman_network_get_index(service->network);
3463 else if (service->provider)
3464 return connman_provider_get_index(service->provider);
3469 void __connman_service_set_hidden(struct connman_service *service)
3471 if (!service || service->hidden)
3474 service->hidden_service = true;
3477 void __connman_service_set_hostname(struct connman_service *service,
3478 const char *hostname)
3480 if (!service || service->hidden)
3483 g_free(service->hostname);
3484 service->hostname = g_strdup(hostname);
3487 const char *__connman_service_get_hostname(struct connman_service *service)
3492 return service->hostname;
3495 void __connman_service_set_domainname(struct connman_service *service,
3496 const char *domainname)
3498 if (!service || service->hidden)
3501 g_free(service->domainname);
3502 service->domainname = g_strdup(domainname);
3504 domain_changed(service);
3507 const char *connman_service_get_domainname(struct connman_service *service)
3512 if (service->domains)
3513 return service->domains[0];
3515 return service->domainname;
3518 char **connman_service_get_nameservers(struct connman_service *service)
3523 if (service->nameservers_config)
3524 return g_strdupv(service->nameservers_config);
3525 else if (service->nameservers ||
3526 service->nameservers_auto) {
3527 int len = 0, len_auto = 0, i;
3530 if (service->nameservers)
3531 len = g_strv_length(service->nameservers);
3532 if (service->nameservers_auto)
3533 len_auto = g_strv_length(service->nameservers_auto);
3535 nameservers = g_try_new0(char *, len + len_auto + 1);
3539 for (i = 0; i < len; i++)
3540 nameservers[i] = g_strdup(service->nameservers[i]);
3542 for (i = 0; i < len_auto; i++)
3543 nameservers[i + len] =
3544 g_strdup(service->nameservers_auto[i]);
3549 return g_strdupv(connman_setting_get_string_list("FallbackNameservers"));
3552 char **connman_service_get_timeservers_config(struct connman_service *service)
3557 return service->timeservers_config;
3560 char **connman_service_get_timeservers(struct connman_service *service)
3565 return service->timeservers;
3568 #if defined TIZEN_EXT
3570 * Description: Telephony plug-in requires manual PROXY setting function
3572 int connman_service_set_proxy(struct connman_service *service,
3573 const char *proxy, gboolean active)
3575 char **proxies_array = NULL;
3577 if (service == NULL)
3580 switch (service->type) {
3581 case CONNMAN_SERVICE_TYPE_CELLULAR:
3582 case CONNMAN_SERVICE_TYPE_ETHERNET:
3583 case CONNMAN_SERVICE_TYPE_WIFI:
3590 g_strfreev(service->proxies);
3591 service->proxies = NULL;
3594 proxies_array = g_strsplit(proxy, " ", 0);
3596 service->proxies = proxies_array;
3598 if (proxy == NULL) {
3599 service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
3600 DBG("proxy changed (%d)", active);
3602 service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_MANUAL;
3603 DBG("proxy chagned %s (%d)", proxy, active);
3606 if (active == TRUE) {
3607 proxy_changed(service);
3609 __connman_notifier_proxy_changed(service);
3616 void connman_service_set_proxy_method(struct connman_service *service,
3617 enum connman_service_proxy_method method)
3619 if (!service || service->hidden)
3622 service->proxy = method;
3624 proxy_changed(service);
3626 if (method != CONNMAN_SERVICE_PROXY_METHOD_AUTO)
3627 __connman_notifier_proxy_changed(service);
3630 enum connman_service_proxy_method connman_service_get_proxy_method(
3631 struct connman_service *service)
3634 return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
3636 if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN) {
3637 if (service->proxy_config == CONNMAN_SERVICE_PROXY_METHOD_AUTO &&
3639 return service->proxy;
3641 return service->proxy_config;
3644 return service->proxy;
3647 char **connman_service_get_proxy_servers(struct connman_service *service)
3649 return g_strdupv(service->proxies);
3652 char **connman_service_get_proxy_excludes(struct connman_service *service)
3654 return g_strdupv(service->excludes);
3657 const char *connman_service_get_proxy_url(struct connman_service *service)
3662 return service->pac;
3665 void __connman_service_set_proxy_autoconfig(struct connman_service *service,
3668 if (!service || service->hidden)
3671 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_AUTO;
3673 if (service->ipconfig_ipv4) {
3674 if (__connman_ipconfig_set_proxy_autoconfig(
3675 service->ipconfig_ipv4, url) < 0)
3677 } else if (service->ipconfig_ipv6) {
3678 if (__connman_ipconfig_set_proxy_autoconfig(
3679 service->ipconfig_ipv6, url) < 0)
3684 proxy_changed(service);
3686 __connman_notifier_proxy_changed(service);
3689 const char *connman_service_get_proxy_autoconfig(struct connman_service *service)
3694 if (service->ipconfig_ipv4)
3695 return __connman_ipconfig_get_proxy_autoconfig(
3696 service->ipconfig_ipv4);
3697 else if (service->ipconfig_ipv6)
3698 return __connman_ipconfig_get_proxy_autoconfig(
3699 service->ipconfig_ipv6);
3703 #if defined TIZEN_EXT
3704 int connman_service_get_ipv6_dns_method(struct connman_service *service)
3707 DBG("Service is NULL");
3711 return service->dns_config_method_ipv6;
3715 void __connman_service_set_timeservers(struct connman_service *service,
3723 g_strfreev(service->timeservers);
3724 service->timeservers = NULL;
3726 for (i = 0; timeservers && timeservers[i]; i++)
3727 __connman_service_timeserver_append(service, timeservers[i]);
3730 int __connman_service_timeserver_append(struct connman_service *service,
3731 const char *timeserver)
3735 DBG("service %p timeserver %s", service, timeserver);
3740 if (service->timeservers) {
3743 for (i = 0; service->timeservers[i]; i++)
3744 if (g_strcmp0(service->timeservers[i], timeserver) == 0)
3747 len = g_strv_length(service->timeservers);
3748 service->timeservers = g_try_renew(char *, service->timeservers,
3752 service->timeservers = g_try_new0(char *, len + 2);
3755 if (!service->timeservers)
3758 service->timeservers[len] = g_strdup(timeserver);
3759 service->timeservers[len + 1] = NULL;
3764 int __connman_service_timeserver_remove(struct connman_service *service,
3765 const char *timeserver)
3768 int len, i, j, found = 0;
3770 DBG("service %p timeserver %s", service, timeserver);
3775 if (!service->timeservers)
3778 for (i = 0; service->timeservers &&
3779 service->timeservers[i]; i++)
3780 if (g_strcmp0(service->timeservers[i], timeserver) == 0) {
3788 len = g_strv_length(service->timeservers);
3791 g_strfreev(service->timeservers);
3792 service->timeservers = NULL;
3797 servers = g_try_new0(char *, len);
3801 for (i = 0, j = 0; i < len; i++) {
3802 if (g_strcmp0(service->timeservers[i], timeserver) != 0) {
3803 servers[j] = g_strdup(service->timeservers[i]);
3809 servers[len - 1] = NULL;
3811 g_strfreev(service->timeservers);
3812 service->timeservers = servers;
3817 void __connman_service_timeserver_changed(struct connman_service *service,
3823 if (!allow_property_changed(service))
3826 connman_dbus_property_changed_array(service->path,
3827 CONNMAN_SERVICE_INTERFACE, "Timeservers",
3828 DBUS_TYPE_STRING, append_ts, ts_list);
3831 void __connman_service_set_pac(struct connman_service *service,
3834 if (service->hidden)
3836 g_free(service->pac);
3837 service->pac = g_strdup(pac);
3839 proxy_changed(service);
3842 #if defined TIZEN_EXT
3843 void __connman_service_set_proxy(struct connman_service *service,
3844 const char *proxies)
3846 char **proxies_array = NULL;
3848 g_strfreev(service->proxies);
3849 service->proxies = NULL;
3851 if (proxies != NULL)
3852 proxies_array = g_strsplit(proxies, " ", 0);
3854 service->proxies = proxies_array;
3858 void __connman_service_set_identity(struct connman_service *service,
3859 const char *identity)
3861 if (service->immutable || service->hidden)
3864 g_free(service->identity);
3865 service->identity = g_strdup(identity);
3867 if (service->network)
3868 connman_network_set_string(service->network,
3873 void __connman_service_set_agent_identity(struct connman_service *service,
3874 const char *agent_identity)
3876 if (service->hidden)
3878 g_free(service->agent_identity);
3879 service->agent_identity = g_strdup(agent_identity);
3881 if (service->network)
3882 connman_network_set_string(service->network,
3883 "WiFi.AgentIdentity",
3884 service->agent_identity);
3887 static int check_passphrase(enum connman_service_security security,
3888 const char *passphrase)
3896 length = strlen(passphrase);
3899 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
3900 case CONNMAN_SERVICE_SECURITY_NONE:
3901 case CONNMAN_SERVICE_SECURITY_WPA:
3902 #if !defined TIZEN_EXT
3903 case CONNMAN_SERVICE_SECURITY_RSN:
3906 DBG("service security '%s' (%d) not handled",
3907 security2string(security), security);
3911 case CONNMAN_SERVICE_SECURITY_PSK:
3912 #if defined TIZEN_EXT
3913 case CONNMAN_SERVICE_SECURITY_RSN:
3915 /* A raw key is always 64 bytes length,
3916 * its content is in hex representation.
3917 * A PSK key must be between [8..63].
3920 for (i = 0; i < 64; i++)
3921 if (!isxdigit((unsigned char)
3924 } else if (length < 8 || length > 63)
3927 case CONNMAN_SERVICE_SECURITY_WEP:
3928 /* length of WEP key is 10 or 26
3929 * length of WEP passphrase is 5 or 13
3931 if (length == 10 || length == 26) {
3932 for (i = 0; i < length; i++)
3933 if (!isxdigit((unsigned char)
3936 } else if (length != 5 && length != 13)
3940 case CONNMAN_SERVICE_SECURITY_8021X:
3947 int __connman_service_set_passphrase(struct connman_service *service,
3948 const char *passphrase)
3952 if (service->hidden)
3955 if (service->immutable &&
3956 service->security != CONNMAN_SERVICE_SECURITY_8021X)
3959 err = check_passphrase(service->security, passphrase);
3964 g_free(service->passphrase);
3965 service->passphrase = g_strdup(passphrase);
3967 if (service->network)
3968 connman_network_set_string(service->network, "WiFi.Passphrase",
3969 service->passphrase);
3974 const char *__connman_service_get_passphrase(struct connman_service *service)
3979 return service->passphrase;
3982 static DBusMessage *get_properties(DBusConnection *conn,
3983 DBusMessage *msg, void *user_data)
3985 struct connman_service *service = user_data;
3987 DBusMessageIter array, dict;
3989 DBG("service %p", service);
3991 reply = dbus_message_new_method_return(msg);
3995 dbus_message_iter_init_append(reply, &array);
3997 connman_dbus_dict_open(&array, &dict);
3998 append_properties(&dict, FALSE, service);
3999 connman_dbus_dict_close(&array, &dict);
4004 static int update_proxy_configuration(struct connman_service *service,
4005 DBusMessageIter *array)
4007 DBusMessageIter dict;
4008 enum connman_service_proxy_method method;
4009 GString *servers_str = NULL;
4010 GString *excludes_str = NULL;
4011 const char *url = NULL;
4013 method = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
4015 dbus_message_iter_recurse(array, &dict);
4017 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
4018 DBusMessageIter entry, variant;
4022 dbus_message_iter_recurse(&dict, &entry);
4024 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
4027 dbus_message_iter_get_basic(&entry, &key);
4028 dbus_message_iter_next(&entry);
4030 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
4033 dbus_message_iter_recurse(&entry, &variant);
4035 type = dbus_message_iter_get_arg_type(&variant);
4037 if (g_str_equal(key, "Method")) {
4040 if (type != DBUS_TYPE_STRING)
4043 dbus_message_iter_get_basic(&variant, &val);
4044 method = string2proxymethod(val);
4045 } else if (g_str_equal(key, "URL")) {
4046 if (type != DBUS_TYPE_STRING)
4049 dbus_message_iter_get_basic(&variant, &url);
4050 } else if (g_str_equal(key, "Servers")) {
4051 DBusMessageIter str_array;
4053 if (type != DBUS_TYPE_ARRAY)
4056 servers_str = g_string_new(NULL);
4060 dbus_message_iter_recurse(&variant, &str_array);
4062 while (dbus_message_iter_get_arg_type(&str_array) ==
4066 dbus_message_iter_get_basic(&str_array, &val);
4068 if (servers_str->len > 0)
4069 g_string_append_printf(servers_str,
4072 g_string_append(servers_str, val);
4074 dbus_message_iter_next(&str_array);
4076 } else if (g_str_equal(key, "Excludes")) {
4077 DBusMessageIter str_array;
4079 if (type != DBUS_TYPE_ARRAY)
4082 excludes_str = g_string_new(NULL);
4086 dbus_message_iter_recurse(&variant, &str_array);
4088 while (dbus_message_iter_get_arg_type(&str_array) ==
4092 dbus_message_iter_get_basic(&str_array, &val);
4094 if (excludes_str->len > 0)
4095 g_string_append_printf(excludes_str,
4098 g_string_append(excludes_str, val);
4100 dbus_message_iter_next(&str_array);
4104 dbus_message_iter_next(&dict);
4108 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
4110 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
4111 if (!servers_str && !service->proxies)
4115 g_strfreev(service->proxies);
4117 if (servers_str->len > 0)
4118 service->proxies = g_strsplit_set(
4119 servers_str->str, " ", 0);
4121 service->proxies = NULL;
4125 g_strfreev(service->excludes);
4127 if (excludes_str->len > 0)
4128 service->excludes = g_strsplit_set(
4129 excludes_str->str, " ", 0);
4131 service->excludes = NULL;
4134 if (!service->proxies)
4135 method = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
4138 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
4139 g_free(service->pac);
4141 if (url && strlen(url) > 0)
4142 service->pac = g_strdup(url);
4144 service->pac = NULL;
4146 /* if we are connected:
4147 - if service->pac == NULL
4148 - if __connman_ipconfig_get_proxy_autoconfig(
4149 service->ipconfig) == NULL
4150 --> We should start WPAD */
4153 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
4158 g_string_free(servers_str, TRUE);
4161 g_string_free(excludes_str, TRUE);
4163 service->proxy_config = method;
4169 g_string_free(servers_str, TRUE);
4172 g_string_free(excludes_str, TRUE);
4177 int __connman_service_reset_ipconfig(struct connman_service *service,
4178 enum connman_ipconfig_type type, DBusMessageIter *array,
4179 enum connman_service_state *new_state)
4181 struct connman_ipconfig *ipconfig, *new_ipconfig;
4182 enum connman_ipconfig_method old_method, new_method;
4183 enum connman_service_state state;
4186 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
4187 ipconfig = service->ipconfig_ipv4;
4188 state = service->state_ipv4;
4189 new_method = CONNMAN_IPCONFIG_METHOD_DHCP;
4190 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
4191 ipconfig = service->ipconfig_ipv6;
4192 state = service->state_ipv6;
4193 new_method = CONNMAN_IPCONFIG_METHOD_AUTO;
4200 old_method = __connman_ipconfig_get_method(ipconfig);
4201 index = __connman_ipconfig_get_index(ipconfig);
4203 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4204 new_ipconfig = create_ip4config(service, index,
4205 CONNMAN_IPCONFIG_METHOD_UNKNOWN);
4207 new_ipconfig = create_ip6config(service, index);
4210 err = __connman_ipconfig_set_config(new_ipconfig, array);
4212 __connman_ipconfig_unref(new_ipconfig);
4216 new_method = __connman_ipconfig_get_method(new_ipconfig);
4219 if (is_connecting_state(service, state) ||
4220 is_connected_state(service, state))
4221 __connman_network_clear_ipconfig(service->network, ipconfig);
4223 __connman_ipconfig_unref(ipconfig);
4225 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4226 service->ipconfig_ipv4 = new_ipconfig;
4227 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
4228 service->ipconfig_ipv6 = new_ipconfig;
4230 if (is_connecting_state(service, state) ||
4231 is_connected_state(service, state))
4232 __connman_ipconfig_enable(new_ipconfig);
4234 if (new_state && new_method != old_method) {
4235 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4236 *new_state = service->state_ipv4;
4238 *new_state = service->state_ipv6;
4240 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
4243 DBG("err %d ipconfig %p type %d method %d state %s", err,
4244 new_ipconfig, type, new_method,
4245 !new_state ? "-" : state2string(*new_state));
4250 static DBusMessage *set_property(DBusConnection *conn,
4251 DBusMessage *msg, void *user_data)
4253 struct connman_service *service = user_data;
4254 DBusMessageIter iter, value;
4258 DBG("service %p", service);
4260 if (!dbus_message_iter_init(msg, &iter))
4261 return __connman_error_invalid_arguments(msg);
4263 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
4264 return __connman_error_invalid_arguments(msg);
4266 if (service->type == CONNMAN_SERVICE_TYPE_WIFI && is_connected(service)) {
4268 if (connman_dbus_get_connection_unix_user_sync(conn,
4269 dbus_message_get_sender(msg),
4271 DBG("Can not get unix user id!");
4272 return __connman_error_permission_denied(msg);
4275 if (!connman_service_is_user_allowed(service, uid)) {
4276 DBG("Not allow this user to operate this wifi service now!");
4277 return __connman_error_permission_denied(msg);
4281 dbus_message_iter_get_basic(&iter, &name);
4282 dbus_message_iter_next(&iter);
4284 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
4285 return __connman_error_invalid_arguments(msg);
4287 dbus_message_iter_recurse(&iter, &value);
4289 type = dbus_message_iter_get_arg_type(&value);
4291 if (g_str_equal(name, "AutoConnect")) {
4292 dbus_bool_t autoconnect;
4294 if (type != DBUS_TYPE_BOOLEAN)
4295 return __connman_error_invalid_arguments(msg);
4297 if (!service->favorite)
4298 return __connman_error_invalid_service(msg);
4300 dbus_message_iter_get_basic(&value, &autoconnect);
4302 if (service->autoconnect == autoconnect)
4303 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
4305 service->autoconnect = autoconnect;
4307 autoconnect_changed(service);
4310 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
4312 service_save(service);
4313 } else if (g_str_equal(name, "Nameservers.Configuration")) {
4314 DBusMessageIter entry;
4318 #if defined TIZEN_EXT
4319 enum connman_ipconfig_type ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4323 if (__connman_provider_is_immutable(service->provider) ||
4325 return __connman_error_not_supported(msg);
4327 if (type != DBUS_TYPE_ARRAY)
4328 return __connman_error_invalid_arguments(msg);
4330 str = g_string_new(NULL);
4332 return __connman_error_invalid_arguments(msg);
4334 index = __connman_service_get_index(service);
4335 gw = __connman_ipconfig_get_gateway_from_index(index,
4336 CONNMAN_IPCONFIG_TYPE_ALL);
4338 if (gw && strlen(gw))
4339 __connman_service_nameserver_del_routes(service,
4340 CONNMAN_IPCONFIG_TYPE_ALL);
4342 dbus_message_iter_recurse(&value, &entry);
4344 #if defined TIZEN_EXT
4345 /* IPv4/IPv6 Last DNS config method */
4346 int last_dns_ipv4 = service->dns_config_method_ipv4;
4347 int last_dns_ipv6 = service->dns_config_method_ipv6;
4348 DBG("Last DNS Config Method IPv4: %d IPv6: %d", last_dns_ipv4, last_dns_ipv6);
4351 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
4353 dbus_message_iter_get_basic(&entry, &val);
4354 dbus_message_iter_next(&entry);
4356 /* First unpack the DNS Config Method */
4357 DBG("DNS Config Method: %s", val);
4358 if((g_strcmp0(val, "ipv4.manual") == 0)) {
4359 service->dns_config_method_ipv4 =
4360 CONNMAN_DNSCONFIG_METHOD_MANUAL;
4362 if(last_dns_ipv4 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
4363 if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
4364 ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
4366 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4369 } else if(g_strcmp0(val, "ipv4.dhcp") == 0) {
4370 service->dns_config_method_ipv4 =
4371 CONNMAN_DNSCONFIG_METHOD_DHCP;
4372 if(last_dns_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
4373 ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
4376 } else if(g_strcmp0(val, "ipv6.manual") == 0) {
4377 service->dns_config_method_ipv6 =
4378 CONNMAN_DNSCONFIG_METHOD_MANUAL;
4379 if(last_dns_ipv6 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
4380 if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
4381 ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
4383 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4386 } else if(g_strcmp0(val, "ipv6.dhcp") == 0) {
4387 service->dns_config_method_ipv6 =
4388 CONNMAN_DNSCONFIG_METHOD_DHCP;
4389 if(last_dns_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
4390 ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
4395 if (connman_inet_check_ipaddress(val) > 0) {
4397 g_string_append_printf(str, " %s", val);
4399 g_string_append(str, val);
4403 #if defined TIZEN_EXT
4404 if (service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_DHCP &&
4405 service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_DHCP) {
4406 DBG("Both IPv4 and IPv6 DNS Method DHCP");
4407 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4409 if (gw && strlen(gw))
4410 __connman_service_nameserver_del_routes(service,
4413 DBG("%s ip_type: %d nameserver remove all", name, ip_type);
4414 nameserver_remove_all(service, ip_type);
4416 nameserver_remove_all(service);
4418 g_strfreev(service->nameservers_config);
4421 service->nameservers_config =
4422 g_strsplit_set(str->str, " ", 0);
4424 service->nameservers_config = NULL;
4427 g_string_free(str, TRUE);
4429 if (gw && strlen(gw))
4430 __connman_service_nameserver_add_routes(service, gw);
4432 #if defined TIZEN_EXT
4433 DBG("%s ip_type: %d nameserver add all", name, ip_type);
4434 nameserver_add_all(service, ip_type);
4436 nameserver_add_all(service);
4438 dns_configuration_changed(service);
4440 if (__connman_service_is_connected_state(service,
4441 CONNMAN_IPCONFIG_TYPE_IPV4))
4442 __connman_wispr_start(service,
4443 CONNMAN_IPCONFIG_TYPE_IPV4);
4445 if (__connman_service_is_connected_state(service,
4446 CONNMAN_IPCONFIG_TYPE_IPV6))
4447 __connman_wispr_start(service,
4448 CONNMAN_IPCONFIG_TYPE_IPV6);
4450 service_save(service);
4451 } else if (g_str_equal(name, "Timeservers.Configuration")) {
4452 DBusMessageIter entry;
4453 GSList *list = NULL;
4456 if (service->immutable)
4457 return __connman_error_not_supported(msg);
4459 if (type != DBUS_TYPE_ARRAY)
4460 return __connman_error_invalid_arguments(msg);
4462 dbus_message_iter_recurse(&value, &entry);
4464 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
4468 dbus_message_iter_get_basic(&entry, &val);
4470 new_head = __connman_timeserver_add_list(list, val);
4471 if (list != new_head) {
4476 dbus_message_iter_next(&entry);
4479 g_strfreev(service->timeservers_config);
4480 service->timeservers_config = NULL;
4483 service->timeservers_config = g_new0(char *, count+1);
4487 service->timeservers_config[count] = list->data;
4488 list = g_slist_delete_link(list, list);
4492 service_save(service);
4493 timeservers_configuration_changed(service);
4495 if (service == __connman_service_get_default())
4496 __connman_timeserver_sync(service);
4498 } else if (g_str_equal(name, "Domains.Configuration")) {
4499 DBusMessageIter entry;
4502 if (service->immutable)
4503 return __connman_error_not_supported(msg);
4505 if (type != DBUS_TYPE_ARRAY)
4506 return __connman_error_invalid_arguments(msg);
4508 str = g_string_new(NULL);
4510 return __connman_error_invalid_arguments(msg);
4512 dbus_message_iter_recurse(&value, &entry);
4514 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
4516 dbus_message_iter_get_basic(&entry, &val);
4517 dbus_message_iter_next(&entry);
4519 g_string_append_printf(str, " %s", val);
4521 g_string_append(str, val);
4524 searchdomain_remove_all(service);
4525 g_strfreev(service->domains);
4528 service->domains = g_strsplit_set(str->str, " ", 0);
4530 service->domains = NULL;
4532 g_string_free(str, TRUE);
4534 searchdomain_add_all(service);
4535 domain_configuration_changed(service);
4536 domain_changed(service);
4538 service_save(service);
4539 } else if (g_str_equal(name, "Proxy.Configuration")) {
4542 if (service->immutable)
4543 return __connman_error_not_supported(msg);
4545 if (type != DBUS_TYPE_ARRAY)
4546 return __connman_error_invalid_arguments(msg);
4548 err = update_proxy_configuration(service, &value);
4551 return __connman_error_failed(msg, -err);
4553 proxy_configuration_changed(service);
4555 __connman_notifier_proxy_changed(service);
4557 service_save(service);
4558 } else if (g_str_equal(name, "IPv4.Configuration") ||
4559 g_str_equal(name, "IPv6.Configuration")) {
4561 enum connman_service_state state =
4562 CONNMAN_SERVICE_STATE_UNKNOWN;
4563 enum connman_ipconfig_type type =
4564 CONNMAN_IPCONFIG_TYPE_UNKNOWN;
4567 if (service->type == CONNMAN_SERVICE_TYPE_VPN ||
4569 return __connman_error_not_supported(msg);
4573 if (!service->ipconfig_ipv4 &&
4574 !service->ipconfig_ipv6)
4575 return __connman_error_invalid_property(msg);
4577 if (g_str_equal(name, "IPv4.Configuration"))
4578 type = CONNMAN_IPCONFIG_TYPE_IPV4;
4580 type = CONNMAN_IPCONFIG_TYPE_IPV6;
4582 err = __connman_service_reset_ipconfig(service, type, &value,
4586 if (is_connected_state(service, state) ||
4587 is_connecting_state(service, state)) {
4588 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4589 __connman_network_enable_ipconfig(service->network,
4590 service->ipconfig_ipv4);
4592 __connman_network_enable_ipconfig(service->network,
4593 service->ipconfig_ipv6);
4596 return __connman_error_failed(msg, -err);
4599 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4600 ipv4_configuration_changed(service);
4602 ipv6_configuration_changed(service);
4604 if (is_connecting(service) || is_connected(service)) {
4605 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4606 __connman_network_enable_ipconfig(service->network,
4607 service->ipconfig_ipv4);
4609 __connman_network_enable_ipconfig(service->network,
4610 service->ipconfig_ipv6);
4613 service_save(service);
4615 return __connman_error_invalid_property(msg);
4617 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
4620 static void set_error(struct connman_service *service,
4621 enum connman_service_error error)
4625 if (service->error == error)
4628 service->error = error;
4633 #if !defined TIZEN_EXT
4634 if (!allow_property_changed(service))
4638 str = error2string(service->error);
4643 connman_dbus_property_changed_basic(service->path,
4644 CONNMAN_SERVICE_INTERFACE, "Error",
4645 DBUS_TYPE_STRING, &str);
4648 static void set_idle(struct connman_service *service)
4650 service->state = service->state_ipv4 = service->state_ipv6 =
4651 CONNMAN_SERVICE_STATE_IDLE;
4652 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
4653 state_changed(service);
4656 static DBusMessage *clear_property(DBusConnection *conn,
4657 DBusMessage *msg, void *user_data)
4659 struct connman_service *service = user_data;
4662 DBG("service %p", service);
4664 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
4667 if (g_str_equal(name, "Error")) {
4668 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
4670 g_get_current_time(&service->modified);
4671 service_save(service);
4673 return __connman_error_invalid_property(msg);
4675 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
4678 static bool is_ipconfig_usable(struct connman_service *service)
4680 if (!__connman_ipconfig_is_usable(service->ipconfig_ipv4) &&
4681 !__connman_ipconfig_is_usable(service->ipconfig_ipv6))
4687 static bool is_ignore(struct connman_service *service)
4689 if (!service->autoconnect)
4692 if (service->roaming)
4695 if (service->ignore)
4698 if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
4701 if (!is_ipconfig_usable(service))
4707 static void disconnect_on_last_session(enum connman_service_type type)
4711 for (list = service_list; list; list = list->next) {
4712 struct connman_service *service = list->data;
4714 if (service->type != type)
4717 if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_SESSION)
4720 __connman_service_disconnect(service);
4725 static int active_sessions[MAX_CONNMAN_SERVICE_TYPES] = {};
4726 static int active_count = 0;
4728 void __connman_service_set_active_session(bool enable, GSList *list)
4738 while (list != NULL) {
4739 enum connman_service_type type = GPOINTER_TO_INT(list->data);
4742 case CONNMAN_SERVICE_TYPE_ETHERNET:
4743 case CONNMAN_SERVICE_TYPE_WIFI:
4744 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
4745 case CONNMAN_SERVICE_TYPE_CELLULAR:
4746 case CONNMAN_SERVICE_TYPE_GADGET:
4748 active_sessions[type]++;
4750 active_sessions[type]--;
4753 case CONNMAN_SERVICE_TYPE_UNKNOWN:
4754 case CONNMAN_SERVICE_TYPE_SYSTEM:
4755 case CONNMAN_SERVICE_TYPE_GPS:
4756 case CONNMAN_SERVICE_TYPE_VPN:
4757 case CONNMAN_SERVICE_TYPE_P2P:
4761 if (active_sessions[type] == 0)
4762 disconnect_on_last_session(type);
4764 list = g_slist_next(list);
4767 DBG("eth %d wifi %d bt %d cellular %d gadget %d sessions %d",
4768 active_sessions[CONNMAN_SERVICE_TYPE_ETHERNET],
4769 active_sessions[CONNMAN_SERVICE_TYPE_WIFI],
4770 active_sessions[CONNMAN_SERVICE_TYPE_BLUETOOTH],
4771 active_sessions[CONNMAN_SERVICE_TYPE_CELLULAR],
4772 active_sessions[CONNMAN_SERVICE_TYPE_GADGET],
4776 struct preferred_tech_data {
4777 GList *preferred_list;
4778 enum connman_service_type type;
4781 static void preferred_tech_add_by_type(gpointer data, gpointer user_data)
4783 struct connman_service *service = data;
4784 struct preferred_tech_data *tech_data = user_data;
4786 if (service->type == tech_data->type) {
4787 tech_data->preferred_list =
4788 g_list_append(tech_data->preferred_list, service);
4790 DBG("type %d service %p %s", tech_data->type, service,
4795 static GList *preferred_tech_list_get(void)
4797 unsigned int *tech_array;
4798 struct preferred_tech_data tech_data = { 0, };
4801 tech_array = connman_setting_get_uint_list("PreferredTechnologies");
4805 if (connman_setting_get_bool("SingleConnectedTechnology")) {
4807 for (list = service_list; list; list = list->next) {
4808 struct connman_service *service = list->data;
4810 if (!is_connected(service))
4813 if (service->connect_reason ==
4814 CONNMAN_SERVICE_CONNECT_REASON_USER) {
4815 DBG("service %p name %s is user connected",
4816 service, service->name);
4817 #if defined TIZEN_EXT
4818 /* We can connect to a favorite service like
4819 * wifi even we have a userconnect for cellular
4820 * because we have refount for cellular service
4822 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
4825 if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
4833 for (i = 0; tech_array[i] != 0; i += 1) {
4834 tech_data.type = tech_array[i];
4835 g_list_foreach(service_list, preferred_tech_add_by_type,
4839 return tech_data.preferred_list;
4842 static bool auto_connect_service(GList *services,
4843 enum connman_service_connect_reason reason,
4846 struct connman_service *service = NULL;
4847 bool ignore[MAX_CONNMAN_SERVICE_TYPES] = { };
4848 bool autoconnecting = false;
4851 DBG("preferred %d sessions %d reason %s", preferred, active_count,
4852 reason2string(reason));
4854 ignore[CONNMAN_SERVICE_TYPE_VPN] = true;
4856 for (list = services; list; list = list->next) {
4857 service = list->data;
4859 if (ignore[service->type]) {
4860 DBG("service %p type %s ignore", service,
4861 __connman_service_type2string(service->type));
4865 #if defined TIZEN_EXT
4866 DBG("service %p %s %s %s, favorite(%d), ignore(%d), hidden(%d, %d)",
4867 service, service->name,
4868 state2string(service->state),
4869 __connman_service_type2string(service->type),
4870 service->favorite, is_ignore(service),
4871 service->hidden, service->hidden_service);
4873 /* Tizen takes Wi-Fi as the highest priority into consideration. */
4874 if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
4875 if (is_connecting(service) == TRUE || is_connected(service) == TRUE)
4879 if (service->pending ||
4880 is_connecting(service) ||
4881 is_connected(service)) {
4885 ignore[service->type] = true;
4886 autoconnecting = true;
4888 DBG("service %p type %s busy", service,
4889 __connman_service_type2string(service->type));
4894 if (!service->favorite) {
4898 #if defined TIZEN_EXT
4899 DBG("Service is not favorite, autoconnecting %d",
4902 return autoconnecting;
4905 #if defined TIZEN_EXT
4906 DBG("service %p identifier %s roaming %d ignore %d "
4907 "ipconfig_usable %d autoconnect %d state %d",
4909 service->identifier, service->roaming,
4910 service->ignore, is_ipconfig_usable(service),
4911 service->autoconnect, service->state);
4913 if (is_ignore(service) || service->state !=
4914 CONNMAN_SERVICE_STATE_IDLE)
4917 if (autoconnecting && !active_sessions[service->type]) {
4918 DBG("service %p type %s has no users", service,
4919 __connman_service_type2string(service->type));
4923 if (!is_service_owner_user_login(service)) {
4924 DBG("favorite user not login, wifi auto connect denied");
4928 DBG("service %p %s %s", service, service->name,
4929 (preferred) ? "preferred" : reason2string(reason));
4931 __connman_service_connect(service, reason);
4936 ignore[service->type] = true;
4939 return autoconnecting;
4942 static gboolean run_auto_connect(gpointer data)
4944 enum connman_service_connect_reason reason = GPOINTER_TO_UINT(data);
4945 bool autoconnecting = false;
4946 GList *preferred_tech;
4948 autoconnect_timeout = 0;
4952 preferred_tech = preferred_tech_list_get();
4953 if (preferred_tech) {
4954 autoconnecting = auto_connect_service(preferred_tech, reason,
4956 g_list_free(preferred_tech);
4959 if (!autoconnecting || active_count)
4960 auto_connect_service(service_list, reason, false);
4965 void __connman_service_auto_connect(enum connman_service_connect_reason reason)
4969 if (autoconnect_timeout != 0)
4972 if (!__connman_session_policy_autoconnect(reason))
4975 #if defined TIZEN_EXT
4976 /* Adding Timeout of 500ms before trying to auto connect.
4977 * This is done because of below scenario
4978 * 1. Device is connected to AP1
4979 * 2. WPS Connection request is initiated for AP2
4980 * 3. Immediately WPS Connection is Cancelled
4981 * When WPS Connection Connection is initiated for AP2 then
4982 * sometimes there is a scenario where connman gets in ASSOCIATED
4983 * state with AP1 due to autoconnect and subsequently the connection
4984 * initiated by AP1 fails and connman service for AP1 comes in
4985 * FAILURE state due to this when connection with AP2 is cancelled
4986 * then autoconnect with AP1 doesn't works because its autoconnection
4987 * is ignored as its last state was FAILURE rather than IDLE */
4988 autoconnect_timeout = g_timeout_add(500, run_auto_connect,
4990 autoconnect_timeout = g_timeout_add_seconds(0, run_auto_connect,
4992 GUINT_TO_POINTER(reason));
4995 static gboolean run_vpn_auto_connect(gpointer data) {
4997 bool need_split = false;
4999 vpn_autoconnect_timeout = 0;
5001 for (list = service_list; list; list = list->next) {
5002 struct connman_service *service = list->data;
5005 if (service->type != CONNMAN_SERVICE_TYPE_VPN)
5008 if (is_connected(service) || is_connecting(service)) {
5009 if (!service->do_split_routing)
5014 if (is_ignore(service) || !service->favorite)
5017 if (need_split && !service->do_split_routing) {
5018 DBG("service %p no split routing", service);
5022 DBG("service %p %s %s", service, service->name,
5023 service->do_split_routing ?
5024 "split routing" : "");
5026 res = __connman_service_connect(service,
5027 CONNMAN_SERVICE_CONNECT_REASON_AUTO);
5028 if (res < 0 && res != -EINPROGRESS)
5031 if (!service->do_split_routing)
5038 static void vpn_auto_connect(void)
5040 if (vpn_autoconnect_timeout)
5043 vpn_autoconnect_timeout =
5044 g_timeout_add_seconds(0, run_vpn_auto_connect, NULL);
5047 static void remove_timeout(struct connman_service *service)
5049 if (service->timeout > 0) {
5050 g_source_remove(service->timeout);
5051 service->timeout = 0;
5055 static void reply_pending(struct connman_service *service, int error)
5057 remove_timeout(service);
5059 if (service->pending) {
5060 connman_dbus_reply_pending(service->pending, error, NULL);
5061 service->pending = NULL;
5064 if (service->provider_pending) {
5065 connman_dbus_reply_pending(service->provider_pending,
5066 error, service->path);
5067 service->provider_pending = NULL;
5072 __connman_service_is_provider_pending(struct connman_service *service)
5077 if (service->provider_pending)
5083 void __connman_service_set_provider_pending(struct connman_service *service,
5086 if (service->provider_pending) {
5087 DBG("service %p provider pending msg %p already exists",
5088 service, service->provider_pending);
5092 service->provider_pending = msg;
5096 static void check_pending_msg(struct connman_service *service)
5098 if (!service->pending)
5101 DBG("service %p pending msg %p already exists", service,
5103 dbus_message_unref(service->pending);
5106 void __connman_service_set_hidden_data(struct connman_service *service,
5109 DBusMessage *pending = user_data;
5111 DBG("service %p pending %p", service, pending);
5116 check_pending_msg(service);
5118 service->pending = pending;
5121 void __connman_service_return_error(struct connman_service *service,
5122 int error, gpointer user_data)
5124 DBG("service %p error %d user_data %p", service, error, user_data);
5126 __connman_service_set_hidden_data(service, user_data);
5128 reply_pending(service, error);
5131 static gboolean connect_timeout(gpointer user_data)
5133 struct connman_service *service = user_data;
5134 bool autoconnect = false;
5136 DBG("service %p", service);
5138 service->timeout = 0;
5140 if (service->network)
5141 __connman_network_disconnect(service->network);
5142 else if (service->provider)
5143 connman_provider_disconnect(service->provider);
5145 __connman_ipconfig_disable(service->ipconfig_ipv4);
5146 __connman_ipconfig_disable(service->ipconfig_ipv6);
5148 __connman_stats_service_unregister(service);
5150 if (service->pending) {
5153 reply = __connman_error_operation_timeout(service->pending);
5155 g_dbus_send_message(connection, reply);
5157 dbus_message_unref(service->pending);
5158 service->pending = NULL;
5162 __connman_service_ipconfig_indicate_state(service,
5163 CONNMAN_SERVICE_STATE_FAILURE,
5164 CONNMAN_IPCONFIG_TYPE_IPV4);
5165 __connman_service_ipconfig_indicate_state(service,
5166 CONNMAN_SERVICE_STATE_FAILURE,
5167 CONNMAN_IPCONFIG_TYPE_IPV6);
5170 service->connect_reason !=
5171 CONNMAN_SERVICE_CONNECT_REASON_USER)
5172 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
5177 static DBusMessage *connect_service(DBusConnection *conn,
5178 DBusMessage *msg, void *user_data)
5180 struct connman_service *service = user_data;
5181 #if defined TIZEN_EXT
5188 DBG("service %p", service);
5190 #if defined TIZEN_EXT
5192 * Description: TIZEN implements system global connection management.
5194 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
5195 connman_service_user_pdn_connection_ref(service);
5198 if (service->pending)
5199 return __connman_error_in_progress(msg);
5201 if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
5203 if (connman_dbus_get_connection_unix_user_sync(conn,
5204 dbus_message_get_sender(msg),
5206 DBG("Can not get unix user id!");
5207 return __connman_error_permission_denied(msg);
5210 if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
5211 DBG("Not allow this user to connect this wifi service now!");
5212 return __connman_error_permission_denied(msg);
5215 if (uid != USER_ROOT && uid != service->user.favorite_user)
5216 service->request_passphrase_input = true;
5218 service->user.current_user = uid;
5220 if (!service->passphrase && uid == service->user.favorite_user) {
5221 DBG("Now load this favorite user's passphrase.");
5222 service_load_passphrase(service);
5226 #if !defined TIZEN_EXT
5227 index = __connman_service_get_index(service);
5229 for (list = service_list; list; list = list->next) {
5230 struct connman_service *temp = list->data;
5232 #if defined TIZEN_EXT
5233 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
5236 if (!is_connecting(temp) && !is_connected(temp))
5239 if (service == temp)
5242 if (service->type != temp->type)
5245 if (__connman_service_get_index(temp) == index &&
5246 __connman_service_disconnect(temp) == -EINPROGRESS)
5250 if (err == -EINPROGRESS)
5251 return __connman_error_operation_timeout(msg);
5254 service->ignore = false;
5256 service->pending = dbus_message_ref(msg);
5258 err = __connman_service_connect(service,
5259 CONNMAN_SERVICE_CONNECT_REASON_USER);
5261 if (err == -EINPROGRESS)
5264 if (service->pending) {
5265 dbus_message_unref(service->pending);
5266 service->pending = NULL;
5270 return __connman_error_failed(msg, -err);
5272 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5275 static DBusMessage *disconnect_service(DBusConnection *conn,
5276 DBusMessage *msg, void *user_data)
5278 struct connman_service *service = user_data;
5281 DBG("service %p", service);
5283 #if defined TIZEN_EXT
5285 * Description: TIZEN implements system global connection management.
5287 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
5288 if (connman_service_user_pdn_connection_unref_and_test(service) != TRUE)
5289 return __connman_error_failed(msg, EISCONN);
5291 if (is_connected(service) == TRUE &&
5292 service == connman_service_get_default_connection())
5293 return __connman_error_failed(msg, EISCONN);
5297 if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
5299 if (connman_dbus_get_connection_unix_user_sync(conn,
5300 dbus_message_get_sender(msg),
5302 DBG("Can not get unix user id!");
5303 return __connman_error_permission_denied(msg);
5306 if (!connman_service_is_user_allowed(service, uid)) {
5307 DBG("Not allow this user to disconnect this wifi service now!");
5308 return __connman_error_permission_denied(msg);
5312 service->ignore = true;
5314 err = __connman_service_disconnect(service);
5315 if (err < 0 && err != -EINPROGRESS)
5316 return __connman_error_failed(msg, -err);
5318 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5321 #if defined TIZEN_EXT
5322 static void __connman_service_cleanup_network_8021x(struct connman_service *service)
5324 if (service == NULL)
5327 DBG("service %p ", service);
5329 connman_network_set_string(service->network, "WiFi.EAP", NULL);
5330 connman_network_set_string(service->network, "WiFi.Identity", NULL);
5331 connman_network_set_string(service->network, "WiFi.CACertFile", NULL);
5332 connman_network_set_string(service->network, "WiFi.ClientCertFile", NULL);
5333 connman_network_set_string(service->network, "WiFi.PrivateKeyFile", NULL);
5334 connman_network_set_string(service->network, "WiFi.PrivateKeyPassphrase", NULL);
5335 connman_network_set_string(service->network, "WiFi.Phase2", NULL);
5339 bool __connman_service_remove(struct connman_service *service)
5341 if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET ||
5342 service->type == CONNMAN_SERVICE_TYPE_GADGET)
5345 if (service->immutable || service->hidden ||
5346 __connman_provider_is_immutable(service->provider))
5349 #if !defined TIZEN_EXT
5350 if (!service->favorite && service->state !=
5351 CONNMAN_SERVICE_STATE_FAILURE)
5355 __connman_service_disconnect(service);
5357 g_free(service->passphrase);
5358 service->passphrase = NULL;
5360 g_free(service->identity);
5361 service->identity = NULL;
5363 g_free(service->agent_identity);
5364 service->agent_identity = NULL;
5366 g_free(service->eap);
5367 service->eap = NULL;
5369 #if defined TIZEN_EXT
5370 g_free(service->ca_cert_file);
5371 service->ca_cert_file = NULL;
5373 g_free(service->client_cert_file);
5374 service->client_cert_file = NULL;
5376 g_free(service->private_key_file);
5377 service->private_key_file = NULL;
5379 g_free(service->private_key_passphrase);
5380 service->private_key_passphrase = NULL;
5382 g_free(service->phase2);
5383 service->phase2 = NULL;
5385 __connman_service_cleanup_network_8021x(service);
5387 __connman_ipconfig_set_method(service->ipconfig_ipv4, CONNMAN_IPCONFIG_METHOD_DHCP);
5388 __connman_ipconfig_set_method(service->ipconfig_ipv6, CONNMAN_IPCONFIG_METHOD_AUTO);
5389 connman_service_set_proxy(service, NULL, false);
5391 __connman_service_nameserver_clear(service);
5393 g_strfreev(service->nameservers_config);
5394 service->nameservers_config = NULL;
5398 #if defined TIZEN_EXT
5399 if (service->security != CONNMAN_SERVICE_SECURITY_8021X)
5403 service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
5405 service->user.favorite_user = USER_NONE;
5407 __connman_service_set_favorite(service, false);
5409 __connman_ipconfig_ipv6_reset_privacy(service->ipconfig_ipv6);
5411 #if defined TIZEN_EXT
5412 /* Reset IP Method and DNS Method to DHCP */
5413 __connman_ipconfig_set_method(service->ipconfig_ipv4,
5414 CONNMAN_IPCONFIG_METHOD_DHCP);
5415 service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
5416 g_strfreev(service->nameservers_config);
5417 service->nameservers_config = NULL;
5420 #if defined TIZEN_EXT
5421 __connman_storage_remove_service(service->identifier);
5423 service_save(service);
5429 static DBusMessage *remove_service(DBusConnection *conn,
5430 DBusMessage *msg, void *user_data)
5432 struct connman_service *service = user_data;
5434 DBG("service %p", service);
5436 if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
5438 if (connman_dbus_get_connection_unix_user_sync(conn,
5439 dbus_message_get_sender(msg),
5441 DBG("Can not get unix user id!");
5442 return __connman_error_permission_denied(msg);
5445 #if !defined TIZEN_EXT
5446 if (!connman_service_is_user_allowed(service, uid)) {
5447 DBG("Not allow this user to remove this wifi service now!");
5448 return __connman_error_permission_denied(msg);
5453 if (!__connman_service_remove(service))
5454 return __connman_error_not_supported(msg);
5456 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5459 static bool check_suitable_state(enum connman_service_state a,
5460 enum connman_service_state b)
5463 * Special check so that "ready" service can be moved before
5466 if ((a == CONNMAN_SERVICE_STATE_ONLINE &&
5467 b == CONNMAN_SERVICE_STATE_READY) ||
5468 (b == CONNMAN_SERVICE_STATE_ONLINE &&
5469 a == CONNMAN_SERVICE_STATE_READY))
5475 static void downgrade_state(struct connman_service *service)
5480 DBG("service %p state4 %d state6 %d", service, service->state_ipv4,
5481 service->state_ipv6);
5483 if (service->state_ipv4 == CONNMAN_SERVICE_STATE_ONLINE)
5484 __connman_service_ipconfig_indicate_state(service,
5485 CONNMAN_SERVICE_STATE_READY,
5486 CONNMAN_IPCONFIG_TYPE_IPV4);
5488 if (service->state_ipv6 == CONNMAN_SERVICE_STATE_ONLINE)
5489 __connman_service_ipconfig_indicate_state(service,
5490 CONNMAN_SERVICE_STATE_READY,
5491 CONNMAN_IPCONFIG_TYPE_IPV6);
5494 static void apply_relevant_default_downgrade(struct connman_service *service)
5496 struct connman_service *def_service;
5498 def_service = __connman_service_get_default();
5502 if (def_service == service &&
5503 def_service->state == CONNMAN_SERVICE_STATE_ONLINE) {
5504 def_service->state = CONNMAN_SERVICE_STATE_READY;
5505 __connman_notifier_leave_online(def_service->type);
5506 state_changed(def_service);
5510 static void switch_default_service(struct connman_service *default_service,
5511 struct connman_service *downgrade_service)
5513 struct connman_service *service;
5516 apply_relevant_default_downgrade(default_service);
5517 src = g_list_find(service_list, downgrade_service);
5518 dst = g_list_find(service_list, default_service);
5521 if (src == dst || src->next == dst)
5524 service = src->data;
5525 service_list = g_list_delete_link(service_list, src);
5526 service_list = g_list_insert_before(service_list, dst, service);
5528 downgrade_state(downgrade_service);
5531 static DBusMessage *move_service(DBusConnection *conn,
5532 DBusMessage *msg, void *user_data,
5535 struct connman_service *service = user_data;
5536 struct connman_service *target;
5538 enum connman_ipconfig_method target4, target6;
5539 enum connman_ipconfig_method service4, service6;
5541 DBG("service %p", service);
5543 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
5546 if (!service->favorite)
5547 return __connman_error_not_supported(msg);
5549 target = find_service(path);
5550 if (!target || !target->favorite || target == service)
5551 return __connman_error_invalid_service(msg);
5553 if (target->type == CONNMAN_SERVICE_TYPE_VPN) {
5555 * We only allow VPN route splitting if there are
5556 * routes defined for a given VPN.
5558 if (!__connman_provider_check_routes(target->provider)) {
5559 connman_info("Cannot move service. "
5560 "No routes defined for provider %s",
5561 __connman_provider_get_ident(target->provider));
5562 return __connman_error_invalid_service(msg);
5565 target->do_split_routing = true;
5567 target->do_split_routing = false;
5569 service->do_split_routing = false;
5571 target4 = __connman_ipconfig_get_method(target->ipconfig_ipv4);
5572 target6 = __connman_ipconfig_get_method(target->ipconfig_ipv6);
5573 service4 = __connman_ipconfig_get_method(service->ipconfig_ipv4);
5574 service6 = __connman_ipconfig_get_method(service->ipconfig_ipv6);
5576 DBG("target %s method %d/%d state %d/%d split %d", target->identifier,
5577 target4, target6, target->state_ipv4, target->state_ipv6,
5578 target->do_split_routing);
5580 DBG("service %s method %d/%d state %d/%d", service->identifier,
5582 service->state_ipv4, service->state_ipv6);
5585 * If method is OFF, then we do not need to check the corresponding
5588 if (target4 == CONNMAN_IPCONFIG_METHOD_OFF) {
5589 if (service6 != CONNMAN_IPCONFIG_METHOD_OFF) {
5590 if (!check_suitable_state(target->state_ipv6,
5591 service->state_ipv6))
5592 return __connman_error_invalid_service(msg);
5596 if (target6 == CONNMAN_IPCONFIG_METHOD_OFF) {
5597 if (service4 != CONNMAN_IPCONFIG_METHOD_OFF) {
5598 if (!check_suitable_state(target->state_ipv4,
5599 service->state_ipv4))
5600 return __connman_error_invalid_service(msg);
5604 if (service4 == CONNMAN_IPCONFIG_METHOD_OFF) {
5605 if (target6 != CONNMAN_IPCONFIG_METHOD_OFF) {
5606 if (!check_suitable_state(target->state_ipv6,
5607 service->state_ipv6))
5608 return __connman_error_invalid_service(msg);
5612 if (service6 == CONNMAN_IPCONFIG_METHOD_OFF) {
5613 if (target4 != CONNMAN_IPCONFIG_METHOD_OFF) {
5614 if (!check_suitable_state(target->state_ipv4,
5615 service->state_ipv4))
5616 return __connman_error_invalid_service(msg);
5620 g_get_current_time(&service->modified);
5621 service_save(service);
5622 service_save(target);
5625 * If the service which goes down is the default service and is
5626 * online, we downgrade directly its state to ready so:
5627 * the service which goes up, needs to recompute its state which
5628 * is triggered via downgrading it - if relevant - to state ready.
5631 switch_default_service(target, service);
5633 switch_default_service(service, target);
5635 __connman_connection_update_gateway();
5637 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5640 static DBusMessage *move_before(DBusConnection *conn,
5641 DBusMessage *msg, void *user_data)
5643 return move_service(conn, msg, user_data, true);
5646 static DBusMessage *move_after(DBusConnection *conn,
5647 DBusMessage *msg, void *user_data)
5649 return move_service(conn, msg, user_data, false);
5652 static DBusMessage *reset_counters(DBusConnection *conn,
5653 DBusMessage *msg, void *user_data)
5655 struct connman_service *service = user_data;
5657 reset_stats(service);
5659 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5662 static DBusMessage *get_user_favorite(DBusConnection *conn,
5663 DBusMessage *msg, void *user_data)
5666 uid_t uid = USER_NONE;
5667 dbus_bool_t user_favorite = false;
5668 struct connman_service *service = user_data;
5670 connman_dbus_get_connection_unix_user_sync(conn,
5671 dbus_message_get_sender(msg),
5673 if (uid == USER_ROOT)
5674 user_favorite = service->favorite;
5675 else if (uid != USER_NONE && uid == service->user.favorite_user) {
5676 DBG("The service is favorite to this user!");
5677 user_favorite = true;
5680 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5681 dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN,
5682 &user_favorite, DBUS_TYPE_INVALID);
5686 static struct _services_notify {
5692 static void service_append_added_foreach(gpointer data, gpointer user_data)
5694 struct connman_service *service = data;
5695 DBusMessageIter *iter = user_data;
5697 if (!service || !service->path) {
5698 #if !defined TIZEN_EXT
5699 DBG("service %p or path is NULL", service);
5704 if (g_hash_table_lookup(services_notify->add, service->path)) {
5705 #if !defined TIZEN_EXT
5706 DBG("new %s", service->path);
5709 append_struct(service, iter);
5710 g_hash_table_remove(services_notify->add, service->path);
5712 #if !defined TIZEN_EXT
5713 DBG("changed %s", service->path);
5716 append_struct_service(iter, NULL, service);
5720 static void service_append_ordered(DBusMessageIter *iter, void *user_data)
5722 g_list_foreach(service_list, service_append_added_foreach, iter);
5725 static void append_removed(gpointer key, gpointer value, gpointer user_data)
5727 char *objpath = key;
5728 DBusMessageIter *iter = user_data;
5730 DBG("removed %s", objpath);
5731 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &objpath);
5734 static void service_append_removed(DBusMessageIter *iter, void *user_data)
5736 g_hash_table_foreach(services_notify->remove, append_removed, iter);
5739 static gboolean service_send_changed(gpointer data)
5741 DBusMessage *signal;
5745 services_notify->id = 0;
5747 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
5748 CONNMAN_MANAGER_INTERFACE, "ServicesChanged");
5752 __connman_dbus_append_objpath_dict_array(signal,
5753 service_append_ordered, NULL);
5754 __connman_dbus_append_objpath_array(signal,
5755 service_append_removed, NULL);
5757 dbus_connection_send(connection, signal, NULL);
5758 dbus_message_unref(signal);
5760 g_hash_table_remove_all(services_notify->remove);
5761 g_hash_table_remove_all(services_notify->add);
5766 static void service_schedule_changed(void)
5768 if (services_notify->id != 0)
5771 services_notify->id = g_timeout_add(100, service_send_changed, NULL);
5774 static void service_schedule_added(struct connman_service *service)
5776 DBG("service %p", service);
5778 g_hash_table_remove(services_notify->remove, service->path);
5779 g_hash_table_replace(services_notify->add, service->path, service);
5781 service_schedule_changed();
5784 static void service_schedule_removed(struct connman_service *service)
5786 if (!service || !service->path) {
5787 DBG("service %p or path is NULL", service);
5791 DBG("service %p %s", service, service->path);
5793 g_hash_table_remove(services_notify->add, service->path);
5794 g_hash_table_replace(services_notify->remove, g_strdup(service->path),
5797 service_schedule_changed();
5800 static bool allow_property_changed(struct connman_service *service)
5802 #if defined TIZEN_EXT
5803 if (service->path == NULL)
5806 if (g_hash_table_lookup_extended(services_notify->add, service->path,
5808 DBG("no property updates for service %p", service);
5815 static const GDBusMethodTable service_methods[] = {
5816 { GDBUS_DEPRECATED_METHOD("GetProperties",
5817 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
5819 { GDBUS_METHOD("SetProperty",
5820 GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
5821 NULL, set_property) },
5822 { GDBUS_METHOD("ClearProperty",
5823 GDBUS_ARGS({ "name", "s" }), NULL,
5825 { GDBUS_ASYNC_METHOD("Connect", NULL, NULL,
5827 { GDBUS_METHOD("Disconnect", NULL, NULL,
5828 disconnect_service) },
5829 { GDBUS_METHOD("Remove", NULL, NULL, remove_service) },
5830 { GDBUS_METHOD("MoveBefore",
5831 GDBUS_ARGS({ "service", "o" }), NULL,
5833 { GDBUS_METHOD("MoveAfter",
5834 GDBUS_ARGS({ "service", "o" }), NULL,
5836 { GDBUS_METHOD("ResetCounters", NULL, NULL, reset_counters) },
5837 { GDBUS_METHOD("GetUserFavorite",
5838 NULL, GDBUS_ARGS({ "value", "v" }),
5839 get_user_favorite) },
5843 static const GDBusSignalTable service_signals[] = {
5844 { GDBUS_SIGNAL("PropertyChanged",
5845 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
5849 static void service_free(gpointer user_data)
5851 struct connman_service *service = user_data;
5852 char *path = service->path;
5854 DBG("service %p", service);
5856 reply_pending(service, ENOENT);
5858 __connman_notifier_service_remove(service);
5859 service_schedule_removed(service);
5861 __connman_wispr_stop(service);
5862 stats_stop(service);
5864 service->path = NULL;
5867 __connman_connection_update_gateway();
5869 g_dbus_unregister_interface(connection, path,
5870 CONNMAN_SERVICE_INTERFACE);
5874 g_hash_table_destroy(service->counter_table);
5876 if (service->network) {
5877 __connman_network_disconnect(service->network);
5878 connman_network_unref(service->network);
5879 service->network = NULL;
5882 if (service->provider)
5883 connman_provider_unref(service->provider);
5885 if (service->ipconfig_ipv4) {
5886 __connman_ipconfig_set_ops(service->ipconfig_ipv4, NULL);
5887 __connman_ipconfig_set_data(service->ipconfig_ipv4, NULL);
5888 __connman_ipconfig_unref(service->ipconfig_ipv4);
5889 service->ipconfig_ipv4 = NULL;
5892 if (service->ipconfig_ipv6) {
5893 __connman_ipconfig_set_ops(service->ipconfig_ipv6, NULL);
5894 __connman_ipconfig_set_data(service->ipconfig_ipv6, NULL);
5895 __connman_ipconfig_unref(service->ipconfig_ipv6);
5896 service->ipconfig_ipv6 = NULL;
5899 g_strfreev(service->timeservers);
5900 g_strfreev(service->timeservers_config);
5901 g_strfreev(service->nameservers);
5902 g_strfreev(service->nameservers_config);
5903 g_strfreev(service->nameservers_auto);
5904 g_strfreev(service->domains);
5905 g_strfreev(service->proxies);
5906 g_strfreev(service->excludes);
5908 g_free(service->hostname);
5909 g_free(service->domainname);
5910 g_free(service->pac);
5911 g_free(service->name);
5912 g_free(service->passphrase);
5913 g_free(service->identifier);
5914 g_free(service->eap);
5915 g_free(service->identity);
5916 g_free(service->agent_identity);
5917 g_free(service->ca_cert_file);
5918 g_free(service->client_cert_file);
5919 g_free(service->private_key_file);
5920 g_free(service->private_key_passphrase);
5921 g_free(service->phase2);
5922 g_free(service->config_file);
5923 g_free(service->config_entry);
5925 if (service->stats.timer)
5926 g_timer_destroy(service->stats.timer);
5927 if (service->stats_roaming.timer)
5928 g_timer_destroy(service->stats_roaming.timer);
5930 if (current_default == service)
5931 current_default = NULL;
5936 static void stats_init(struct connman_service *service)
5939 service->stats.valid = false;
5940 service->stats.enabled = false;
5941 service->stats.timer = g_timer_new();
5944 service->stats_roaming.valid = false;
5945 service->stats_roaming.enabled = false;
5946 service->stats_roaming.timer = g_timer_new();
5949 static void service_initialize(struct connman_service *service)
5951 DBG("service %p", service);
5953 service->refcount = 1;
5955 service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
5957 service->type = CONNMAN_SERVICE_TYPE_UNKNOWN;
5958 service->security = CONNMAN_SERVICE_SECURITY_UNKNOWN;
5960 service->state = CONNMAN_SERVICE_STATE_UNKNOWN;
5961 service->state_ipv4 = CONNMAN_SERVICE_STATE_UNKNOWN;
5962 service->state_ipv6 = CONNMAN_SERVICE_STATE_UNKNOWN;
5964 service->favorite = false;
5965 service->immutable = false;
5966 service->hidden = false;
5968 service->ignore = false;
5970 service->user.favorite_user = USER_NONE;
5971 service->user.current_user = USER_NONE;
5973 service->request_passphrase_input = false;
5975 service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
5979 stats_init(service);
5981 service->provider = NULL;
5983 service->wps = false;
5984 #if defined TIZEN_EXT
5985 service->storage_reload = false;
5987 * Description: TIZEN implements system global connection management.
5989 service->user_pdn_connection_refcount = 0;
5990 __sync_synchronize();
5995 * connman_service_create:
5997 * Allocate a new service.
5999 * Returns: a newly-allocated #connman_service structure
6001 struct connman_service *connman_service_create(void)
6004 struct connman_stats_counter *counters;
6005 const char *counter;
6007 struct connman_service *service;
6009 service = g_try_new0(struct connman_service, 1);
6013 DBG("service %p", service);
6015 service->counter_table = g_hash_table_new_full(g_str_hash,
6016 g_str_equal, NULL, g_free);
6018 for (list = counter_list; list; list = list->next) {
6019 counter = list->data;
6021 counters = g_try_new0(struct connman_stats_counter, 1);
6023 g_hash_table_destroy(service->counter_table);
6028 counters->append_all = true;
6030 g_hash_table_replace(service->counter_table, (gpointer)counter,
6034 service_initialize(service);
6040 * connman_service_ref:
6041 * @service: service structure
6043 * Increase reference counter of service
6045 struct connman_service *
6046 connman_service_ref_debug(struct connman_service *service,
6047 const char *file, int line, const char *caller)
6049 DBG("%p ref %d by %s:%d:%s()", service, service->refcount + 1,
6050 file, line, caller);
6052 __sync_fetch_and_add(&service->refcount, 1);
6058 * connman_service_unref:
6059 * @service: service structure
6061 * Decrease reference counter of service and release service if no
6064 void connman_service_unref_debug(struct connman_service *service,
6065 const char *file, int line, const char *caller)
6067 DBG("%p ref %d by %s:%d:%s()", service, service->refcount - 1,
6068 file, line, caller);
6070 if (__sync_fetch_and_sub(&service->refcount, 1) != 1)
6073 service_list = g_list_remove(service_list, service);
6075 __connman_service_disconnect(service);
6077 g_hash_table_remove(service_hash, service->identifier);
6080 static gint service_compare(gconstpointer a, gconstpointer b)
6082 struct connman_service *service_a = (void *) a;
6083 struct connman_service *service_b = (void *) b;
6084 enum connman_service_state state_a, state_b;
6085 bool a_connected, b_connected;
6088 state_a = service_a->state;
6089 state_b = service_b->state;
6090 a_connected = is_connected(service_a);
6091 b_connected = is_connected(service_b);
6093 if (a_connected && b_connected) {
6094 if (service_a->order > service_b->order)
6097 if (service_a->order < service_b->order)
6101 if (state_a != state_b) {
6102 if (a_connected && b_connected) {
6103 /* We prefer online over ready state */
6104 if (state_a == CONNMAN_SERVICE_STATE_ONLINE)
6107 if (state_b == CONNMAN_SERVICE_STATE_ONLINE)
6116 if (is_connecting(service_a))
6118 if (is_connecting(service_b))
6122 if (service_a->favorite && !service_b->favorite)
6125 if (!service_a->favorite && service_b->favorite)
6128 if (service_a->type != service_b->type) {
6130 if (service_a->type == CONNMAN_SERVICE_TYPE_ETHERNET)
6132 if (service_b->type == CONNMAN_SERVICE_TYPE_ETHERNET)
6135 if (service_a->type == CONNMAN_SERVICE_TYPE_WIFI)
6137 if (service_b->type == CONNMAN_SERVICE_TYPE_WIFI)
6140 if (service_a->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6142 if (service_b->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6145 if (service_a->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
6147 if (service_b->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
6150 if (service_a->type == CONNMAN_SERVICE_TYPE_VPN)
6152 if (service_b->type == CONNMAN_SERVICE_TYPE_VPN)
6155 if (service_a->type == CONNMAN_SERVICE_TYPE_GADGET)
6157 if (service_b->type == CONNMAN_SERVICE_TYPE_GADGET)
6161 strength = (gint) service_b->strength - (gint) service_a->strength;
6165 return g_strcmp0(service_a->name, service_b->name);
6168 static void service_list_sort(void)
6170 if (service_list && service_list->next) {
6171 service_list = g_list_sort(service_list, service_compare);
6172 service_schedule_changed();
6177 * connman_service_get_type:
6178 * @service: service structure
6180 * Get the type of service
6182 enum connman_service_type connman_service_get_type(struct connman_service *service)
6185 return CONNMAN_SERVICE_TYPE_UNKNOWN;
6187 return service->type;
6191 * connman_service_get_interface:
6192 * @service: service structure
6194 * Get network interface of service
6196 char *connman_service_get_interface(struct connman_service *service)
6203 index = __connman_service_get_index(service);
6205 return connman_inet_ifname(index);
6209 * __connman_service_is_user_allowed:
6210 * @type: service type
6213 * Check a user is allowed to operate a type of service
6215 bool __connman_service_is_user_allowed(enum connman_service_type type,
6219 uid_t owner_user = USER_NONE;
6221 for (list = service_list; list; list = list->next) {
6222 struct connman_service *service = list->data;
6224 if (service->type != type)
6227 if (is_connected(service)) {
6228 owner_user = service->user.favorite_user;
6233 if (uid == USER_NONE ||
6234 (uid != USER_ROOT &&
6235 owner_user != USER_NONE &&
6243 * connman_service_get_network:
6244 * @service: service structure
6246 * Get the service network
6248 struct connman_network *
6249 __connman_service_get_network(struct connman_service *service)
6254 return service->network;
6257 struct connman_ipconfig *
6258 __connman_service_get_ip4config(struct connman_service *service)
6263 return service->ipconfig_ipv4;
6266 struct connman_ipconfig *
6267 __connman_service_get_ip6config(struct connman_service *service)
6272 return service->ipconfig_ipv6;
6275 struct connman_ipconfig *
6276 __connman_service_get_ipconfig(struct connman_service *service, int family)
6278 if (family == AF_INET)
6279 return __connman_service_get_ip4config(service);
6280 else if (family == AF_INET6)
6281 return __connman_service_get_ip6config(service);
6287 bool __connman_service_is_connected_state(struct connman_service *service,
6288 enum connman_ipconfig_type type)
6294 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
6296 case CONNMAN_IPCONFIG_TYPE_IPV4:
6297 return is_connected_state(service, service->state_ipv4);
6298 case CONNMAN_IPCONFIG_TYPE_IPV6:
6299 return is_connected_state(service, service->state_ipv6);
6300 case CONNMAN_IPCONFIG_TYPE_ALL:
6301 return is_connected_state(service,
6302 CONNMAN_IPCONFIG_TYPE_IPV4) &&
6303 is_connected_state(service,
6304 CONNMAN_IPCONFIG_TYPE_IPV6);
6309 enum connman_service_security __connman_service_get_security(
6310 struct connman_service *service)
6313 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
6315 return service->security;
6318 const char *__connman_service_get_phase2(struct connman_service *service)
6323 return service->phase2;
6326 bool __connman_service_wps_enabled(struct connman_service *service)
6331 return service->wps;
6334 void __connman_service_mark_dirty(void)
6336 services_dirty = true;
6339 #if defined TIZEN_EXT
6341 * Returns profile count if there is any connected profiles
6342 * that use same interface
6344 int __connman_service_get_connected_count_of_iface(
6345 struct connman_service *service)
6354 index1 = __connman_service_get_index(service);
6359 for (list = service_list; list; list = list->next) {
6360 struct connman_service *service2 = list->data;
6362 if (service == service2)
6365 index2 = __connman_service_get_index(service2);
6367 if (is_connected(service2) && index2 > 0 && index1 == index2)
6373 DBG("Interface index %d, count %d", index1, count);
6378 void __connman_service_set_storage_reload(struct connman_service *service,
6379 bool storage_reload)
6381 if (service != NULL)
6382 service->storage_reload = storage_reload;
6387 * __connman_service_set_favorite_delayed:
6388 * @service: service structure
6389 * @favorite: favorite value
6390 * @delay_ordering: do not order service sequence
6392 * Change the favorite setting of service
6394 int __connman_service_set_favorite_delayed(struct connman_service *service,
6396 bool delay_ordering)
6398 #if defined TIZEN_EXT
6399 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6402 if (service->hidden)
6405 if (service->favorite == favorite)
6408 service->favorite = favorite;
6410 if (!delay_ordering)
6411 __connman_service_get_order(service);
6413 favorite_changed(service);
6415 if (!delay_ordering) {
6417 service_list_sort();
6419 __connman_connection_update_gateway();
6426 * __connman_service_set_favorite:
6427 * @service: service structure
6428 * @favorite: favorite value
6430 * Change the favorite setting of service
6432 int __connman_service_set_favorite(struct connman_service *service,
6435 return __connman_service_set_favorite_delayed(service, favorite,
6439 bool connman_service_get_favorite(struct connman_service *service)
6441 return service->favorite;
6444 bool connman_service_get_autoconnect(struct connman_service *service)
6446 return service->autoconnect;
6449 int __connman_service_set_immutable(struct connman_service *service,
6452 if (service->hidden)
6455 if (service->immutable == immutable)
6458 service->immutable = immutable;
6460 immutable_changed(service);
6465 int __connman_service_set_ignore(struct connman_service *service,
6471 service->ignore = ignore;
6476 void __connman_service_set_string(struct connman_service *service,
6477 const char *key, const char *value)
6479 if (service->hidden)
6481 if (g_str_equal(key, "EAP")) {
6482 g_free(service->eap);
6483 service->eap = g_strdup(value);
6484 } else if (g_str_equal(key, "Identity")) {
6485 g_free(service->identity);
6486 service->identity = g_strdup(value);
6487 } else if (g_str_equal(key, "CACertFile")) {
6488 g_free(service->ca_cert_file);
6489 service->ca_cert_file = g_strdup(value);
6490 } else if (g_str_equal(key, "ClientCertFile")) {
6491 g_free(service->client_cert_file);
6492 service->client_cert_file = g_strdup(value);
6493 } else if (g_str_equal(key, "PrivateKeyFile")) {
6494 g_free(service->private_key_file);
6495 service->private_key_file = g_strdup(value);
6496 } else if (g_str_equal(key, "PrivateKeyPassphrase")) {
6497 g_free(service->private_key_passphrase);
6498 service->private_key_passphrase = g_strdup(value);
6499 } else if (g_str_equal(key, "Phase2")) {
6500 g_free(service->phase2);
6501 service->phase2 = g_strdup(value);
6502 } else if (g_str_equal(key, "Passphrase"))
6503 __connman_service_set_passphrase(service, value);
6506 void __connman_service_set_search_domains(struct connman_service *service,
6509 searchdomain_remove_all(service);
6511 if (service->domains)
6512 g_strfreev(service->domains);
6514 service->domains = g_strdupv(domains);
6516 searchdomain_add_all(service);
6519 static void service_complete(struct connman_service *service)
6521 reply_pending(service, EIO);
6523 if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
6524 __connman_service_auto_connect(service->connect_reason);
6526 g_get_current_time(&service->modified);
6527 service_save(service);
6530 static void report_error_cb(void *user_context, bool retry,
6533 struct connman_service *service = user_context;
6536 __connman_service_connect(service,
6537 CONNMAN_SERVICE_CONNECT_REASON_USER);
6539 /* It is not relevant to stay on Failure state
6540 * when failing is due to wrong user input */
6541 __connman_service_clear_error(service);
6542 #if defined TIZEN_EXT
6543 /* Reseting the state back in case of failure state */
6544 service->state_ipv4 = service->state_ipv6 =
6545 CONNMAN_SERVICE_STATE_IDLE;
6547 if (service->error != CONNMAN_SERVICE_ERROR_AUTH_FAILED)
6548 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
6550 service_complete(service);
6551 __connman_connection_update_gateway();
6555 static int check_wpspin(struct connman_service *service, const char *wpspin)
6563 length = strlen(wpspin);
6565 /* If 0, it will mean user wants to use PBC method */
6567 connman_network_set_string(service->network,
6568 "WiFi.PinWPS", NULL);
6572 /* A WPS PIN is always 8 chars length,
6573 * its content is in digit representation.
6578 for (i = 0; i < 8; i++)
6579 if (!isdigit((unsigned char) wpspin[i]))
6582 connman_network_set_string(service->network, "WiFi.PinWPS", wpspin);
6587 static void request_input_cb(struct connman_service *service,
6588 bool values_received,
6589 const char *name, int name_len,
6590 const char *identity, const char *passphrase,
6591 bool wps, const char *wpspin,
6592 const char *error, void *user_data)
6594 struct connman_device *device;
6595 const char *security;
6598 DBG("RequestInput return, %p", service);
6601 DBG("error: %s", error);
6603 if (g_strcmp0(error,
6604 "net.connman.Agent.Error.Canceled") == 0) {
6607 if (service->hidden)
6608 __connman_service_return_error(service,
6609 ECANCELED, user_data);
6612 if (service->hidden)
6613 __connman_service_return_error(service,
6614 ETIMEDOUT, user_data);
6618 if (service->hidden && name_len > 0 && name_len <= 32) {
6619 device = connman_network_get_device(service->network);
6620 security = connman_network_get_string(service->network,
6622 err = __connman_device_request_hidden_scan(device,
6624 identity, passphrase,
6625 security, user_data);
6627 __connman_service_return_error(service, -err,
6631 if (!values_received || service->hidden) {
6636 if (wps && service->network) {
6637 err = check_wpspin(service, wpspin);
6641 connman_network_set_bool(service->network, "WiFi.UseWPS", wps);
6645 __connman_service_set_agent_identity(service, identity);
6648 err = __connman_service_set_passphrase(service, passphrase);
6652 /* We forget any previous error. */
6653 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
6655 __connman_service_connect(service,
6656 CONNMAN_SERVICE_CONNECT_REASON_USER);
6658 } else if (err == -ENOKEY) {
6659 __connman_service_indicate_error(service,
6660 CONNMAN_SERVICE_ERROR_INVALID_KEY);
6662 /* It is not relevant to stay on Failure state
6663 * when failing is due to wrong user input */
6664 service->state = CONNMAN_SERVICE_STATE_IDLE;
6666 if (!service->hidden) {
6668 * If there was a real error when requesting
6669 * hidden scan, then that error is returned already
6670 * to the user somewhere above so do not try to
6673 __connman_service_return_error(service, -err,
6677 service_complete(service);
6678 __connman_connection_update_gateway();
6682 static void downgrade_connected_services(void)
6684 struct connman_service *up_service;
6687 for (list = service_list; list; list = list->next) {
6688 up_service = list->data;
6690 if (!is_connected(up_service))
6693 if (up_service->state == CONNMAN_SERVICE_STATE_ONLINE)
6696 downgrade_state(up_service);
6700 static int service_update_preferred_order(struct connman_service *default_service,
6701 struct connman_service *new_service,
6702 enum connman_service_state new_state)
6704 unsigned int *tech_array;
6707 if (!default_service || default_service == new_service ||
6708 default_service->state != new_state)
6711 tech_array = connman_setting_get_uint_list("PreferredTechnologies");
6714 for (i = 0; tech_array[i] != 0; i += 1) {
6715 if (default_service->type == tech_array[i])
6718 if (new_service->type == tech_array[i]) {
6719 switch_default_service(default_service,
6721 __connman_connection_update_gateway();
6730 #if defined TIZEN_EXT
6731 static gboolean __connman_service_can_drop(struct connman_service *service)
6733 if (is_connected(service) == TRUE || is_connecting(service) == TRUE) {
6734 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR)
6736 else if (connman_service_is_no_ref_user_pdn_connection(service) == TRUE)
6742 static struct connman_device *default_connecting_device = NULL;
6744 static void __connman_service_disconnect_default(struct connman_service *service)
6746 struct connman_device *default_device = NULL;
6748 if (default_connecting_device == NULL)
6751 default_device = connman_network_get_device(
6752 __connman_service_get_network(service));
6754 DBG("Disconnecting service %p %s", service, service->path);
6755 DBG("Disconnecting device %p %p %s",
6756 default_connecting_device,
6758 connman_device_get_string(default_device, "Name"));
6760 if (default_connecting_device == default_device)
6761 default_connecting_device = NULL;
6764 static void __connman_service_connect_default(struct connman_service *current)
6768 bool default_internet;
6769 struct connman_service *service;
6770 struct connman_service *default_service = NULL;
6771 struct connman_device *default_device = NULL;
6773 if (current->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
6774 switch (current->state) {
6775 case CONNMAN_SERVICE_STATE_UNKNOWN:
6776 case CONNMAN_SERVICE_STATE_ASSOCIATION:
6777 case CONNMAN_SERVICE_STATE_CONFIGURATION:
6783 if (default_connecting_device &&
6784 __connman_service_is_internet_profile(current) == TRUE) {
6785 if (current->network == NULL)
6788 default_device = connman_network_get_device(current->network);
6789 if (default_connecting_device == default_device) {
6790 DBG("Cellular service[%s] %p %s",
6791 state2string(current->state), current, current->path);
6792 DBG("Cellular device %p %p %s",
6793 default_connecting_device, default_device,
6794 connman_device_get_string(default_device, "Name"));
6796 default_connecting_device = NULL;
6801 } else if (is_connected(current) == TRUE || is_connecting(current) == TRUE)
6804 /* Always-on: keep default cellular connection as possible */
6805 for (list = service_list; list; list = list->next) {
6806 service = list->data;
6808 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
6809 __connman_service_is_internet_profile(service) != TRUE ||
6810 service->network == NULL) {
6815 connman_network_get_bool(service->network, "DefaultInternet");
6817 DBG("service: %p %s %s %s (default: %d)", service, service->name,
6818 __connman_service_type2string(service->type),
6819 state2string(service->state), default_internet);
6821 if (default_internet) {
6822 default_service = service;
6823 if (is_connected(default_service) == TRUE ||
6824 is_connecting(default_service) == TRUE)
6827 default_device = connman_network_get_device(default_service->network);
6828 if (default_connecting_device == default_device) {
6829 DBG("Device is connecting (%p)", default_connecting_device);
6833 default_connecting_device = default_device;
6834 default_service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_USER;
6836 err = __connman_network_connect(default_service->network);
6837 DBG("Connecting default service %p %s [%d]",
6838 default_service, default_service->path, err);
6839 DBG("Connecting device %p %s", default_connecting_device,
6840 connman_device_get_string(default_connecting_device, "Name"));
6841 if (err < 0 && err != -EINPROGRESS) {
6842 default_connecting_device = NULL;
6850 static void single_connected_tech(struct connman_service *allowed)
6852 struct connman_service *service;
6853 GSList *services = NULL, *list;
6856 DBG("keeping %p %s", allowed, allowed->path);
6858 #if defined TIZEN_EXT
6859 if (!allowed || allowed->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6863 for (iter = service_list; iter; iter = iter->next) {
6864 service = iter->data;
6866 #if defined TIZEN_EXT
6867 if (service != allowed && service->type != allowed->type &&
6868 __connman_service_can_drop(service) == TRUE)
6870 if (!is_connected(service))
6873 if (service == allowed)
6876 services = g_slist_prepend(services, service);
6879 for (list = services; list; list = list->next) {
6880 service = list->data;
6882 DBG("disconnecting %p %s", service, service->path);
6883 #if defined TIZEN_EXT
6884 __connman_service_disconnect_default(service);
6886 __connman_service_disconnect(service);
6889 g_slist_free(services);
6892 #if defined TIZEN_EXT
6893 static void set_priority_connected_service(void)
6895 struct connman_service *service;
6898 for (list = service_list; list; list = list->next) {
6899 service = list->data;
6901 if (is_connected(service) == FALSE)
6909 static const char *get_dbus_sender(struct connman_service *service)
6911 if (!service->pending)
6914 return dbus_message_get_sender(service->pending);
6917 static int service_indicate_state(struct connman_service *service)
6919 enum connman_service_state old_state, new_state;
6920 struct connman_service *def_service;
6921 enum connman_ipconfig_method method;
6927 old_state = service->state;
6928 new_state = combine_state(service->state_ipv4, service->state_ipv6);
6930 DBG("service %p old %s - new %s/%s => %s",
6932 state2string(old_state),
6933 state2string(service->state_ipv4),
6934 state2string(service->state_ipv6),
6935 state2string(new_state));
6937 if (old_state == new_state)
6940 def_service = __connman_service_get_default();
6942 if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
6943 result = service_update_preferred_order(def_service,
6944 service, new_state);
6945 if (result == -EALREADY)
6949 if (old_state == CONNMAN_SERVICE_STATE_ONLINE)
6950 __connman_notifier_leave_online(service->type);
6952 if (is_connected_state(service, old_state) &&
6953 !is_connected_state(service, new_state))
6954 searchdomain_remove_all(service);
6956 service->state = new_state;
6957 state_changed(service);
6960 case CONNMAN_SERVICE_STATE_UNKNOWN:
6964 case CONNMAN_SERVICE_STATE_IDLE:
6965 if (old_state != CONNMAN_SERVICE_STATE_DISCONNECT)
6966 __connman_service_disconnect(service);
6970 case CONNMAN_SERVICE_STATE_ASSOCIATION:
6974 case CONNMAN_SERVICE_STATE_CONFIGURATION:
6975 if (!service->new_service &&
6976 __connman_stats_service_register(service) == 0) {
6978 * For new services the statistics are updated after
6979 * we have successfully connected.
6981 __connman_stats_get(service, false,
6982 &service->stats.data);
6983 __connman_stats_get(service, true,
6984 &service->stats_roaming.data);
6989 case CONNMAN_SERVICE_STATE_READY:
6990 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
6992 if (service->new_service &&
6993 __connman_stats_service_register(service) == 0) {
6995 * This is normally done after configuring state
6996 * but for new service do this after we have connected
6999 __connman_stats_get(service, false,
7000 &service->stats.data);
7001 __connman_stats_get(service, true,
7002 &service->stats_roaming.data);
7005 service->new_service = false;
7009 def_service = __connman_service_get_default();
7011 service_update_preferred_order(def_service, service, new_state);
7013 __connman_service_set_favorite(service, true);
7015 reply_pending(service, 0);
7017 g_get_current_time(&service->modified);
7018 service_save(service);
7020 searchdomain_add_all(service);
7021 dns_changed(service);
7022 domain_changed(service);
7023 proxy_changed(service);
7025 if (old_state != CONNMAN_SERVICE_STATE_ONLINE)
7026 __connman_notifier_connect(service->type);
7028 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
7029 connman_network_get_bool(service->network,
7033 pass = connman_network_get_string(service->network,
7036 __connman_service_set_passphrase(service, pass);
7038 connman_network_set_bool(service->network,
7039 "WiFi.UseWPS", false);
7042 method = __connman_ipconfig_get_method(service->ipconfig_ipv6);
7043 if (method == CONNMAN_IPCONFIG_METHOD_OFF)
7044 __connman_ipconfig_disable_ipv6(
7045 service->ipconfig_ipv6);
7047 if (connman_setting_get_bool("SingleConnectedTechnology"))
7048 single_connected_tech(service);
7049 else if (service->type != CONNMAN_SERVICE_TYPE_VPN)
7052 #if defined TIZEN_EXT
7053 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
7054 set_priority_connected_service();
7059 case CONNMAN_SERVICE_STATE_ONLINE:
7063 case CONNMAN_SERVICE_STATE_DISCONNECT:
7064 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
7066 reply_pending(service, ECONNABORTED);
7068 def_service = __connman_service_get_default();
7069 service->disconnect_reason = connman_network_get_disconnect_reason(service->network);
7071 if (!__connman_notifier_is_connected() &&
7073 def_service->provider)
7074 connman_provider_disconnect(def_service->provider);
7078 __connman_wispr_stop(service);
7080 __connman_wpad_stop(service);
7082 #if defined TIZEN_EXT
7084 * Skip the functions if there is any connected profiles
7085 * that use same interface
7087 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
7088 __connman_service_get_connected_count_of_iface(
7091 dns_changed(service);
7092 domain_changed(service);
7093 proxy_changed(service);
7094 #if defined TIZEN_EXT
7099 * Previous services which are connected and which states
7100 * are set to online should reset relevantly ipconfig_state
7101 * to ready so wispr/portal will be rerun on those
7103 downgrade_connected_services();
7105 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
7108 case CONNMAN_SERVICE_STATE_FAILURE:
7109 #if defined TIZEN_EXT
7110 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
7112 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
7114 if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER &&
7115 connman_agent_report_error(service, service->path,
7116 error2string(service->error),
7118 get_dbus_sender(service),
7119 NULL) == -EINPROGRESS)
7121 service_complete(service);
7126 service_list_sort();
7128 #if defined TIZEN_EXT
7129 __connman_service_connect_default(service);
7132 __connman_connection_update_gateway();
7134 if ((old_state == CONNMAN_SERVICE_STATE_ONLINE &&
7135 new_state != CONNMAN_SERVICE_STATE_READY) ||
7136 (old_state == CONNMAN_SERVICE_STATE_READY &&
7137 new_state != CONNMAN_SERVICE_STATE_ONLINE)) {
7138 __connman_notifier_disconnect(service->type);
7141 if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
7142 __connman_notifier_enter_online(service->type);
7146 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
7147 service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER &&
7148 (new_state == CONNMAN_SERVICE_STATE_READY ||
7149 new_state == CONNMAN_SERVICE_STATE_ONLINE)) {
7150 if (service->user.favorite_user != service->user.current_user) {
7151 DBG("Now set service favorite user id from %d to %d",
7152 service->user.favorite_user, service->user.current_user);
7154 service->user.favorite_user = service->user.current_user;
7156 service_save(service);
7163 int __connman_service_indicate_error(struct connman_service *service,
7164 enum connman_service_error error)
7166 DBG("service %p error %d", service, error);
7171 if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
7174 set_error(service, error);
7176 /* default internet service: fix not cleared if pdp activation*/
7177 #if defined TIZEN_EXT
7179 * If connection failed for default service(DefaultInternet),
7180 * default_connecting_device should be cleared.
7182 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
7183 service->error == CONNMAN_SERVICE_ERROR_CONNECT_FAILED)
7184 __connman_service_disconnect_default(service);
7186 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
7187 service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) {
7188 g_free(service->passphrase);
7189 service->passphrase = NULL;
7193 __connman_service_ipconfig_indicate_state(service,
7194 CONNMAN_SERVICE_STATE_FAILURE,
7195 CONNMAN_IPCONFIG_TYPE_IPV4);
7196 __connman_service_ipconfig_indicate_state(service,
7197 CONNMAN_SERVICE_STATE_FAILURE,
7198 CONNMAN_IPCONFIG_TYPE_IPV6);
7202 int __connman_service_clear_error(struct connman_service *service)
7204 DBusMessage *pending, *provider_pending;
7206 DBG("service %p", service);
7211 if (service->state != CONNMAN_SERVICE_STATE_FAILURE)
7214 pending = service->pending;
7215 service->pending = NULL;
7216 provider_pending = service->provider_pending;
7217 service->provider_pending = NULL;
7219 __connman_service_ipconfig_indicate_state(service,
7220 CONNMAN_SERVICE_STATE_IDLE,
7221 CONNMAN_IPCONFIG_TYPE_IPV6);
7223 __connman_service_ipconfig_indicate_state(service,
7224 CONNMAN_SERVICE_STATE_IDLE,
7225 CONNMAN_IPCONFIG_TYPE_IPV4);
7227 service->pending = pending;
7228 service->provider_pending = provider_pending;
7233 int __connman_service_indicate_default(struct connman_service *service)
7235 DBG("service %p state %s", service, state2string(service->state));
7237 if (!is_connected(service)) {
7239 * If service is not yet fully connected, then we must not
7240 * change the default yet. The default gw will be changed
7241 * after the service state is in ready.
7243 return -EINPROGRESS;
7251 enum connman_service_state __connman_service_ipconfig_get_state(
7252 struct connman_service *service,
7253 enum connman_ipconfig_type type)
7256 return CONNMAN_SERVICE_STATE_UNKNOWN;
7258 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
7259 return service->state_ipv4;
7261 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
7262 return service->state_ipv6;
7264 return CONNMAN_SERVICE_STATE_UNKNOWN;
7267 static void check_proxy_setup(struct connman_service *service)
7270 * We start WPAD if we haven't got a PAC URL from DHCP and
7271 * if our proxy manual configuration is either empty or set
7272 * to AUTO with an empty URL.
7275 if (service->proxy != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN)
7278 if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN &&
7279 (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_AUTO ||
7283 if (__connman_wpad_start(service) < 0) {
7284 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
7285 __connman_notifier_proxy_changed(service);
7292 __connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
7295 #if defined TIZEN_EXT
7296 void connman_check_proxy_setup_and_wispr_start(struct connman_service *service){
7298 DBG("check the proxy and start wispr");
7299 check_proxy_setup(service);
7305 * How many networks are connected at the same time. If more than 1,
7306 * then set the rp_filter setting properly (loose mode routing) so that network
7307 * connectivity works ok. This is only done for IPv4 networks as IPv6
7308 * does not have rp_filter knob.
7310 static int connected_networks_count;
7311 static int original_rp_filter;
7313 static void service_rp_filter(struct connman_service *service,
7316 enum connman_ipconfig_method method;
7318 method = __connman_ipconfig_get_method(service->ipconfig_ipv4);
7321 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
7322 case CONNMAN_IPCONFIG_METHOD_OFF:
7323 case CONNMAN_IPCONFIG_METHOD_AUTO:
7325 case CONNMAN_IPCONFIG_METHOD_FIXED:
7326 case CONNMAN_IPCONFIG_METHOD_MANUAL:
7327 case CONNMAN_IPCONFIG_METHOD_DHCP:
7332 if (connected_networks_count == 1) {
7334 filter_value = __connman_ipconfig_set_rp_filter();
7335 if (filter_value < 0)
7338 original_rp_filter = filter_value;
7340 connected_networks_count++;
7343 if (connected_networks_count == 2)
7344 __connman_ipconfig_unset_rp_filter(original_rp_filter);
7346 connected_networks_count--;
7347 if (connected_networks_count < 0)
7348 connected_networks_count = 0;
7351 DBG("%s %s ipconfig %p method %d count %d filter %d",
7352 connected ? "connected" : "disconnected", service->identifier,
7353 service->ipconfig_ipv4, method,
7354 connected_networks_count, original_rp_filter);
7357 static gboolean redo_wispr(gpointer user_data)
7359 struct connman_service *service = user_data;
7360 int refcount = service->refcount - 1;
7362 connman_service_unref(service);
7363 if (refcount == 0) {
7364 DBG("Service %p already removed", service);
7368 __connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV6);
7373 int __connman_service_online_check_failed(struct connman_service *service,
7374 enum connman_ipconfig_type type)
7376 DBG("service %p type %d count %d", service, type,
7377 service->online_check_count);
7379 /* currently we only retry IPv6 stuff */
7380 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 ||
7381 service->online_check_count != 1) {
7382 connman_warn("Online check failed for %p %s", service,
7387 service->online_check_count = 0;
7390 * We set the timeout to 1 sec so that we have a chance to get
7391 * necessary IPv6 router advertisement messages that might have
7394 g_timeout_add_seconds(1, redo_wispr, connman_service_ref(service));
7399 int __connman_service_ipconfig_indicate_state(struct connman_service *service,
7400 enum connman_service_state new_state,
7401 enum connman_ipconfig_type type)
7403 struct connman_ipconfig *ipconfig = NULL;
7404 enum connman_service_state old_state;
7405 enum connman_ipconfig_method method;
7411 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
7412 case CONNMAN_IPCONFIG_TYPE_ALL:
7415 case CONNMAN_IPCONFIG_TYPE_IPV4:
7416 old_state = service->state_ipv4;
7417 ipconfig = service->ipconfig_ipv4;
7421 case CONNMAN_IPCONFIG_TYPE_IPV6:
7422 old_state = service->state_ipv6;
7423 ipconfig = service->ipconfig_ipv6;
7432 if (old_state == new_state)
7435 #if defined TIZEN_EXT
7436 __sync_synchronize();
7437 if (service->user_pdn_connection_refcount > 0 &&
7438 service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
7439 if (new_state == CONNMAN_SERVICE_STATE_FAILURE ||
7440 new_state == CONNMAN_SERVICE_STATE_DISCONNECT ||
7441 new_state == CONNMAN_SERVICE_STATE_IDLE) {
7442 service->user_pdn_connection_refcount = 0;
7443 __sync_synchronize();
7447 DBG("service %p (%s) old state %d (%s) new state %d (%s) type %d (%s)",
7448 service, service ? service->identifier : NULL,
7449 old_state, state2string(old_state),
7450 new_state, state2string(new_state),
7451 type, __connman_ipconfig_type2string(type));
7453 switch (new_state) {
7454 case CONNMAN_SERVICE_STATE_UNKNOWN:
7455 case CONNMAN_SERVICE_STATE_IDLE:
7456 case CONNMAN_SERVICE_STATE_ASSOCIATION:
7458 case CONNMAN_SERVICE_STATE_CONFIGURATION:
7459 __connman_ipconfig_enable(ipconfig);
7461 case CONNMAN_SERVICE_STATE_READY:
7462 #if defined TIZEN_EXT
7463 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
7464 __connman_service_is_internet_profile(service) != TRUE) {
7465 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
7466 service_rp_filter(service, TRUE);
7471 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
7472 #if !defined TIZEN_EXT
7473 check_proxy_setup(service);
7475 service_rp_filter(service, true);
7477 service->online_check_count = 1;
7478 __connman_wispr_start(service, type);
7481 case CONNMAN_SERVICE_STATE_ONLINE:
7483 case CONNMAN_SERVICE_STATE_DISCONNECT:
7484 if (service->state == CONNMAN_SERVICE_STATE_IDLE)
7487 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
7488 service_rp_filter(service, false);
7491 case CONNMAN_SERVICE_STATE_FAILURE:
7495 /* Keep that state, but if the ipconfig method is OFF, then we set
7496 the state to IDLE so that it will not affect the combined state
7499 method = __connman_ipconfig_get_method(ipconfig);
7501 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
7502 case CONNMAN_IPCONFIG_METHOD_OFF:
7503 new_state = CONNMAN_SERVICE_STATE_IDLE;
7506 case CONNMAN_IPCONFIG_METHOD_FIXED:
7507 case CONNMAN_IPCONFIG_METHOD_MANUAL:
7508 case CONNMAN_IPCONFIG_METHOD_DHCP:
7509 case CONNMAN_IPCONFIG_METHOD_AUTO:
7514 if (is_connected_state(service, old_state) &&
7515 !is_connected_state(service, new_state))
7516 #if defined TIZEN_EXT
7518 DBG("nameserver remove all, type: %d", type);
7519 nameserver_remove_all(service, type);
7521 nameserver_remove_all(service);
7523 #if defined TIZEN_EXT
7527 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
7528 service->state_ipv4 = new_state;
7530 service->state_ipv6 = new_state;
7532 if (!is_connected_state(service, old_state) &&
7533 is_connected_state(service, new_state))
7534 #if defined TIZEN_EXT
7536 DBG("nameserver add all, type: %d", type);
7537 nameserver_add_all(service, type);
7539 nameserver_add_all(service);
7541 #if defined TIZEN_EXT
7545 #if defined TIZEN_EXT
7546 int ret = service_indicate_state(service);
7547 /*Sent the Ready changed signal again in case IPv4 IP set
7550 if(ret == -EALREADY && type == CONNMAN_IPCONFIG_TYPE_IPV4
7551 && new_state == CONNMAN_SERVICE_STATE_READY) {
7552 DBG("Notify IPv4 state new/old %d/%d", new_state,old_state);
7553 state_changed(service);
7558 return service_indicate_state(service);
7561 static bool prepare_network(struct connman_service *service)
7563 enum connman_network_type type;
7564 unsigned int ssid_len;
7566 type = connman_network_get_type(service->network);
7569 case CONNMAN_NETWORK_TYPE_UNKNOWN:
7570 case CONNMAN_NETWORK_TYPE_VENDOR:
7572 case CONNMAN_NETWORK_TYPE_WIFI:
7573 if (!connman_network_get_blob(service->network, "WiFi.SSID",
7577 if (service->passphrase)
7578 connman_network_set_string(service->network,
7579 "WiFi.Passphrase", service->passphrase);
7581 case CONNMAN_NETWORK_TYPE_ETHERNET:
7582 case CONNMAN_NETWORK_TYPE_GADGET:
7583 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
7584 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
7585 case CONNMAN_NETWORK_TYPE_CELLULAR:
7592 static void prepare_8021x(struct connman_service *service)
7595 connman_network_set_string(service->network, "WiFi.EAP",
7598 if (service->identity)
7599 connman_network_set_string(service->network, "WiFi.Identity",
7602 if (service->ca_cert_file)
7603 connman_network_set_string(service->network, "WiFi.CACertFile",
7604 service->ca_cert_file);
7606 if (service->client_cert_file)
7607 connman_network_set_string(service->network,
7608 "WiFi.ClientCertFile",
7609 service->client_cert_file);
7611 if (service->private_key_file)
7612 connman_network_set_string(service->network,
7613 "WiFi.PrivateKeyFile",
7614 service->private_key_file);
7616 if (service->private_key_passphrase)
7617 connman_network_set_string(service->network,
7618 "WiFi.PrivateKeyPassphrase",
7619 service->private_key_passphrase);
7621 if (service->phase2)
7622 connman_network_set_string(service->network, "WiFi.Phase2",
7626 static int service_connect(struct connman_service *service)
7630 if (service->hidden)
7633 #if defined TIZEN_EXT
7637 index = __connman_service_get_index(service);
7639 for (list = service_list; list; list = list->next) {
7640 struct connman_service *temp = list->data;
7642 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
7645 if (!is_connecting(temp) && !is_connected(temp))
7648 if (service == temp)
7651 if (service->type != temp->type)
7654 if (__connman_service_get_index(temp) == index &&
7655 __connman_service_disconnect(temp) == -EINPROGRESS)
7656 return -EINPROGRESS;
7660 switch (service->type) {
7661 case CONNMAN_SERVICE_TYPE_UNKNOWN:
7662 case CONNMAN_SERVICE_TYPE_SYSTEM:
7663 case CONNMAN_SERVICE_TYPE_GPS:
7664 case CONNMAN_SERVICE_TYPE_P2P:
7666 case CONNMAN_SERVICE_TYPE_ETHERNET:
7667 case CONNMAN_SERVICE_TYPE_GADGET:
7668 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
7669 case CONNMAN_SERVICE_TYPE_CELLULAR:
7670 case CONNMAN_SERVICE_TYPE_VPN:
7672 case CONNMAN_SERVICE_TYPE_WIFI:
7673 switch (service->security) {
7674 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
7675 case CONNMAN_SERVICE_SECURITY_NONE:
7677 case CONNMAN_SERVICE_SECURITY_WEP:
7678 case CONNMAN_SERVICE_SECURITY_PSK:
7679 case CONNMAN_SERVICE_SECURITY_WPA:
7680 case CONNMAN_SERVICE_SECURITY_RSN:
7681 if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
7684 if (service->request_passphrase_input) {
7685 DBG("Now try to connect other user's favorite service");
7686 service->request_passphrase_input = false;
7688 } else if (!service->passphrase) {
7689 if (!service->network)
7692 if (!service->wps ||
7693 !connman_network_get_bool(service->network, "WiFi.UseWPS"))
7698 case CONNMAN_SERVICE_SECURITY_8021X:
7702 #if defined TIZEN_EXT
7704 * never request credentials if using EAP-TLS, EAP-SIM
7705 * or EAP-AKA (EAP-TLS, EAP-SIM and EAP-AKA networks
7706 * need to be fully provisioned)
7708 DBG("service eap: %s", service->eap);
7709 if (g_str_equal(service->eap, "tls") ||
7710 g_str_equal(service->eap, "sim") ||
7711 g_str_equal(service->eap, "aka"))
7715 * never request credentials if using EAP-TLS
7716 * (EAP-TLS networks need to be fully provisioned)
7718 if (g_str_equal(service->eap, "tls"))
7722 * Return -ENOKEY if either identity or passphrase is
7723 * missing. Agent provided credentials can be used as
7724 * fallback if needed.
7726 if (((!service->identity &&
7727 !service->agent_identity) ||
7728 !service->passphrase) ||
7729 service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
7737 if (service->network) {
7738 if (!prepare_network(service))
7741 switch (service->security) {
7742 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
7743 case CONNMAN_SERVICE_SECURITY_NONE:
7744 case CONNMAN_SERVICE_SECURITY_WEP:
7745 case CONNMAN_SERVICE_SECURITY_PSK:
7746 case CONNMAN_SERVICE_SECURITY_WPA:
7747 case CONNMAN_SERVICE_SECURITY_RSN:
7749 case CONNMAN_SERVICE_SECURITY_8021X:
7750 prepare_8021x(service);
7754 if (__connman_stats_service_register(service) == 0) {
7755 __connman_stats_get(service, false,
7756 &service->stats.data);
7757 __connman_stats_get(service, true,
7758 &service->stats_roaming.data);
7761 if (service->ipconfig_ipv4)
7762 __connman_ipconfig_enable(service->ipconfig_ipv4);
7763 if (service->ipconfig_ipv6)
7764 __connman_ipconfig_enable(service->ipconfig_ipv6);
7766 err = __connman_network_connect(service->network);
7767 } else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
7769 err = __connman_provider_connect(service->provider);
7774 if (err != -EINPROGRESS) {
7775 __connman_ipconfig_disable(service->ipconfig_ipv4);
7776 __connman_ipconfig_disable(service->ipconfig_ipv6);
7777 __connman_stats_service_unregister(service);
7784 int __connman_service_connect(struct connman_service *service,
7785 enum connman_service_connect_reason reason)
7789 DBG("service %p state %s connect reason %s -> %s",
7790 service, state2string(service->state),
7791 reason2string(service->connect_reason),
7792 reason2string(reason));
7794 if (is_connected(service))
7797 if (is_connecting(service))
7800 switch (service->type) {
7801 case CONNMAN_SERVICE_TYPE_UNKNOWN:
7802 case CONNMAN_SERVICE_TYPE_SYSTEM:
7803 case CONNMAN_SERVICE_TYPE_GPS:
7804 case CONNMAN_SERVICE_TYPE_P2P:
7807 case CONNMAN_SERVICE_TYPE_ETHERNET:
7808 case CONNMAN_SERVICE_TYPE_GADGET:
7809 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
7810 case CONNMAN_SERVICE_TYPE_CELLULAR:
7811 case CONNMAN_SERVICE_TYPE_VPN:
7812 case CONNMAN_SERVICE_TYPE_WIFI:
7816 if (!is_ipconfig_usable(service))
7819 __connman_service_clear_error(service);
7821 err = service_connect(service);
7823 service->connect_reason = reason;
7827 if (err == -EINPROGRESS) {
7828 if (service->timeout == 0)
7829 service->timeout = g_timeout_add_seconds(
7830 CONNECT_TIMEOUT, connect_timeout, service);
7832 return -EINPROGRESS;
7835 if (service->network)
7836 __connman_network_disconnect(service->network);
7837 else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
7839 connman_provider_disconnect(service->provider);
7841 if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
7842 if (err == -ENOKEY || err == -EPERM) {
7843 DBusMessage *pending = NULL;
7846 * We steal the reply here. The idea is that the
7847 * connecting client will see the connection status
7848 * after the real hidden network is connected or
7849 * connection failed.
7851 if (service->hidden) {
7852 pending = service->pending;
7853 service->pending = NULL;
7856 err = __connman_agent_request_passphrase_input(service,
7858 get_dbus_sender(service),
7860 if (service->hidden && err != -EINPROGRESS)
7861 service->pending = pending;
7865 reply_pending(service, -err);
7871 int __connman_service_disconnect(struct connman_service *service)
7875 DBG("service %p", service);
7877 service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
7878 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
7880 connman_agent_cancel(service);
7882 reply_pending(service, ECONNABORTED);
7884 if (service->network) {
7885 err = __connman_network_disconnect(service->network);
7886 } else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
7888 err = connman_provider_disconnect(service->provider);
7892 if (err < 0 && err != -EINPROGRESS)
7895 __connman_6to4_remove(service->ipconfig_ipv4);
7897 if (service->ipconfig_ipv4)
7898 __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv4,
7901 __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv6,
7904 #if defined TIZEN_EXT
7906 * Skip the functions If there is any connected profiles
7907 * that use same interface
7909 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
7910 __connman_service_get_connected_count_of_iface(service) <= 0) {
7912 __connman_ipconfig_address_remove(service->ipconfig_ipv4);
7913 settings_changed(service, service->ipconfig_ipv4);
7915 __connman_ipconfig_address_remove(service->ipconfig_ipv6);
7916 settings_changed(service, service->ipconfig_ipv6);
7918 __connman_ipconfig_disable(service->ipconfig_ipv4);
7919 __connman_ipconfig_disable(service->ipconfig_ipv6);
7920 #if defined TIZEN_EXT
7924 __connman_stats_service_unregister(service);
7929 int __connman_service_disconnect_all(void)
7931 struct connman_service *service;
7932 GSList *services = NULL, *list;
7937 for (iter = service_list; iter; iter = iter->next) {
7938 service = iter->data;
7940 if (!is_connected(service))
7943 services = g_slist_prepend(services, service);
7946 for (list = services; list; list = list->next) {
7947 struct connman_service *service = list->data;
7949 service->ignore = true;
7951 __connman_service_disconnect(service);
7954 g_slist_free(services);
7960 * lookup_by_identifier:
7961 * @identifier: service identifier
7963 * Look up a service by identifier (reference count will not be increased)
7965 static struct connman_service *lookup_by_identifier(const char *identifier)
7967 return g_hash_table_lookup(service_hash, identifier);
7970 struct provision_user_data {
7975 static void provision_changed(gpointer value, gpointer user_data)
7977 struct connman_service *service = value;
7978 struct provision_user_data *data = user_data;
7979 const char *path = data->ident;
7982 ret = __connman_config_provision_service_ident(service, path,
7983 service->config_file, service->config_entry);
7988 int __connman_service_provision_changed(const char *ident)
7990 struct provision_user_data data = {
7995 g_list_foreach(service_list, provision_changed, (void *)&data);
7998 * Because the provision_changed() might have set some services
7999 * as favorite, we must sort the sequence now.
8001 if (services_dirty) {
8002 services_dirty = false;
8004 service_list_sort();
8006 __connman_connection_update_gateway();
8012 void __connman_service_set_config(struct connman_service *service,
8013 const char *file_id, const char *entry)
8018 g_free(service->config_file);
8019 service->config_file = g_strdup(file_id);
8021 g_free(service->config_entry);
8022 service->config_entry = g_strdup(entry);
8026 * __connman_service_get:
8027 * @identifier: service identifier
8029 * Look up a service by identifier or create a new one if not found
8031 static struct connman_service *service_get(const char *identifier)
8033 struct connman_service *service;
8035 service = g_hash_table_lookup(service_hash, identifier);
8037 connman_service_ref(service);
8041 service = connman_service_create();
8045 DBG("service %p", service);
8047 service->identifier = g_strdup(identifier);
8049 service_list = g_list_insert_sorted(service_list, service,
8052 g_hash_table_insert(service_hash, service->identifier, service);
8057 static int service_register(struct connman_service *service)
8059 DBG("service %p", service);
8064 service->path = g_strdup_printf("%s/service/%s", CONNMAN_PATH,
8065 service->identifier);
8067 DBG("path %s", service->path);
8069 if (__connman_config_provision_service(service) < 0)
8070 service_load(service);
8072 g_dbus_register_interface(connection, service->path,
8073 CONNMAN_SERVICE_INTERFACE,
8074 service_methods, service_signals,
8075 NULL, service, NULL);
8077 service_list_sort();
8079 __connman_connection_update_gateway();
8084 static void service_up(struct connman_ipconfig *ipconfig,
8087 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8089 DBG("%s up", ifname);
8091 link_changed(service);
8093 service->stats.valid = false;
8094 service->stats_roaming.valid = false;
8097 static void service_down(struct connman_ipconfig *ipconfig,
8100 DBG("%s down", ifname);
8103 static void service_lower_up(struct connman_ipconfig *ipconfig,
8106 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8108 DBG("%s lower up", ifname);
8110 stats_start(service);
8113 static void service_lower_down(struct connman_ipconfig *ipconfig,
8116 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8118 DBG("%s lower down", ifname);
8120 if (!is_idle_state(service, service->state_ipv4))
8121 __connman_ipconfig_disable(service->ipconfig_ipv4);
8123 if (!is_idle_state(service, service->state_ipv6))
8124 __connman_ipconfig_disable(service->ipconfig_ipv6);
8126 stats_stop(service);
8127 service_save(service);
8130 static void service_ip_bound(struct connman_ipconfig *ipconfig,
8133 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8134 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
8135 enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
8136 #if defined TIZEN_EXT
8140 DBG("%s ip bound", ifname);
8142 type = __connman_ipconfig_get_config_type(ipconfig);
8143 method = __connman_ipconfig_get_method(ipconfig);
8145 DBG("service %p ipconfig %p type %d method %d", service, ipconfig,
8148 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
8149 method == CONNMAN_IPCONFIG_METHOD_AUTO)
8150 #if defined TIZEN_EXT
8152 err = __connman_ipconfig_gateway_add(ipconfig, service);
8155 __connman_connection_gateway_activate(service,
8156 CONNMAN_IPCONFIG_TYPE_IPV6);
8159 __connman_service_ipconfig_indicate_state(service,
8160 CONNMAN_SERVICE_STATE_READY,
8161 CONNMAN_IPCONFIG_TYPE_IPV6);
8164 settings_changed(service, ipconfig);
8167 static void service_ip_release(struct connman_ipconfig *ipconfig,
8170 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8171 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
8172 enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
8174 DBG("%s ip release", ifname);
8176 type = __connman_ipconfig_get_config_type(ipconfig);
8177 method = __connman_ipconfig_get_method(ipconfig);
8179 DBG("service %p ipconfig %p type %d method %d", service, ipconfig,
8182 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
8183 method == CONNMAN_IPCONFIG_METHOD_OFF)
8184 __connman_service_ipconfig_indicate_state(service,
8185 CONNMAN_SERVICE_STATE_DISCONNECT,
8186 CONNMAN_IPCONFIG_TYPE_IPV6);
8188 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
8189 method == CONNMAN_IPCONFIG_METHOD_OFF)
8190 __connman_service_ipconfig_indicate_state(service,
8191 CONNMAN_SERVICE_STATE_DISCONNECT,
8192 CONNMAN_IPCONFIG_TYPE_IPV4);
8194 settings_changed(service, ipconfig);
8197 static void service_route_changed(struct connman_ipconfig *ipconfig,
8200 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8202 DBG("%s route changed", ifname);
8204 settings_changed(service, ipconfig);
8207 static const struct connman_ipconfig_ops service_ops = {
8209 .down = service_down,
8210 .lower_up = service_lower_up,
8211 .lower_down = service_lower_down,
8212 .ip_bound = service_ip_bound,
8213 .ip_release = service_ip_release,
8214 .route_set = service_route_changed,
8215 .route_unset = service_route_changed,
8218 static struct connman_ipconfig *create_ip4config(struct connman_service *service,
8219 int index, enum connman_ipconfig_method method)
8221 struct connman_ipconfig *ipconfig_ipv4;
8223 ipconfig_ipv4 = __connman_ipconfig_create(index,
8224 CONNMAN_IPCONFIG_TYPE_IPV4);
8228 __connman_ipconfig_set_method(ipconfig_ipv4, method);
8230 __connman_ipconfig_set_data(ipconfig_ipv4, service);
8232 __connman_ipconfig_set_ops(ipconfig_ipv4, &service_ops);
8234 return ipconfig_ipv4;
8237 static struct connman_ipconfig *create_ip6config(struct connman_service *service,
8240 struct connman_ipconfig *ipconfig_ipv6;
8242 ipconfig_ipv6 = __connman_ipconfig_create(index,
8243 CONNMAN_IPCONFIG_TYPE_IPV6);
8247 __connman_ipconfig_set_data(ipconfig_ipv6, service);
8249 __connman_ipconfig_set_ops(ipconfig_ipv6, &service_ops);
8251 return ipconfig_ipv6;
8254 void __connman_service_read_ip4config(struct connman_service *service)
8258 if (!service->ipconfig_ipv4)
8261 keyfile = connman_storage_load_service(service->identifier);
8265 __connman_ipconfig_load(service->ipconfig_ipv4, keyfile,
8266 service->identifier, "IPv4.");
8268 g_key_file_free(keyfile);
8271 void connman_service_create_ip4config(struct connman_service *service,
8274 DBG("ipv4 %p", service->ipconfig_ipv4);
8276 if (service->ipconfig_ipv4)
8279 service->ipconfig_ipv4 = create_ip4config(service, index,
8280 CONNMAN_IPCONFIG_METHOD_DHCP);
8281 __connman_service_read_ip4config(service);
8284 void __connman_service_read_ip6config(struct connman_service *service)
8288 if (!service->ipconfig_ipv6)
8291 keyfile = connman_storage_load_service(service->identifier);
8295 __connman_ipconfig_load(service->ipconfig_ipv6, keyfile,
8296 service->identifier, "IPv6.");
8298 g_key_file_free(keyfile);
8301 void connman_service_create_ip6config(struct connman_service *service,
8304 DBG("ipv6 %p", service->ipconfig_ipv6);
8306 if (service->ipconfig_ipv6)
8309 service->ipconfig_ipv6 = create_ip6config(service, index);
8311 __connman_service_read_ip6config(service);
8315 * connman_service_lookup_from_network:
8316 * @network: network structure
8318 * Look up a service by network (reference count will not be increased)
8320 struct connman_service *connman_service_lookup_from_network(struct connman_network *network)
8322 struct connman_service *service;
8323 const char *ident, *group;
8329 ident = __connman_network_get_ident(network);
8333 group = connman_network_get_group(network);
8337 name = g_strdup_printf("%s_%s_%s",
8338 __connman_network_get_type(network), ident, group);
8339 service = lookup_by_identifier(name);
8345 struct connman_service *__connman_service_lookup_from_index(int index)
8347 struct connman_service *service;
8350 for (list = service_list; list; list = list->next) {
8351 service = list->data;
8353 if (__connman_ipconfig_get_index(service->ipconfig_ipv4)
8357 if (__connman_ipconfig_get_index(service->ipconfig_ipv6)
8365 struct connman_service *__connman_service_lookup_from_ident(const char *identifier)
8367 return lookup_by_identifier(identifier);
8370 const char *__connman_service_get_ident(struct connman_service *service)
8372 return service->identifier;
8375 const char *__connman_service_get_path(struct connman_service *service)
8377 return service->path;
8380 const char *__connman_service_get_name(struct connman_service *service)
8382 return service->name;
8385 enum connman_service_state __connman_service_get_state(struct connman_service *service)
8387 return service->state;
8390 unsigned int __connman_service_get_order(struct connman_service *service)
8392 unsigned int order = 0;
8399 if (!service->favorite)
8402 #if defined TIZEN_EXT
8403 if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
8404 service->do_split_routing == FALSE)
8406 else if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
8407 if (service->order < 5)
8409 } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
8411 else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
8413 else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
8414 __connman_service_is_internet_profile(service) == TRUE)
8416 else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
8417 __connman_service_is_tethering_profile(service) == TRUE)
8419 else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
8424 if (service == service_list->data)
8427 if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
8428 !service->do_split_routing) {
8429 service->order = 10;
8433 DBG("service %p name %s order %d split %d", service, service->name,
8434 order, service->do_split_routing);
8439 void __connman_service_update_ordering(void)
8441 if (service_list && service_list->next)
8442 service_list = g_list_sort(service_list, service_compare);
8445 static enum connman_service_type convert_network_type(struct connman_network *network)
8447 enum connman_network_type type = connman_network_get_type(network);
8450 case CONNMAN_NETWORK_TYPE_UNKNOWN:
8451 case CONNMAN_NETWORK_TYPE_VENDOR:
8453 case CONNMAN_NETWORK_TYPE_ETHERNET:
8454 return CONNMAN_SERVICE_TYPE_ETHERNET;
8455 case CONNMAN_NETWORK_TYPE_WIFI:
8456 return CONNMAN_SERVICE_TYPE_WIFI;
8457 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
8458 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
8459 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
8460 case CONNMAN_NETWORK_TYPE_CELLULAR:
8461 return CONNMAN_SERVICE_TYPE_CELLULAR;
8462 case CONNMAN_NETWORK_TYPE_GADGET:
8463 return CONNMAN_SERVICE_TYPE_GADGET;
8466 return CONNMAN_SERVICE_TYPE_UNKNOWN;
8469 static enum connman_service_security convert_wifi_security(const char *security)
8472 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
8473 else if (g_str_equal(security, "none"))
8474 return CONNMAN_SERVICE_SECURITY_NONE;
8475 else if (g_str_equal(security, "wep"))
8476 return CONNMAN_SERVICE_SECURITY_WEP;
8477 else if (g_str_equal(security, "psk"))
8478 return CONNMAN_SERVICE_SECURITY_PSK;
8479 else if (g_str_equal(security, "ieee8021x"))
8480 return CONNMAN_SERVICE_SECURITY_8021X;
8481 else if (g_str_equal(security, "wpa"))
8482 return CONNMAN_SERVICE_SECURITY_WPA;
8483 else if (g_str_equal(security, "rsn"))
8484 return CONNMAN_SERVICE_SECURITY_RSN;
8485 #if defined TIZEN_EXT
8486 else if (g_str_equal(security, "ft_psk") == TRUE)
8487 return CONNMAN_SERVICE_SECURITY_PSK;
8488 else if (g_str_equal(security, "ft_ieee8021x") == TRUE)
8489 return CONNMAN_SERVICE_SECURITY_8021X;
8492 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
8495 static void update_from_network(struct connman_service *service,
8496 struct connman_network *network)
8498 uint8_t strength = service->strength;
8501 DBG("service %p network %p", service, network);
8503 if (is_connected(service))
8506 if (is_connecting(service))
8509 str = connman_network_get_string(network, "Name");
8511 g_free(service->name);
8512 service->name = g_strdup(str);
8513 service->hidden = false;
8515 g_free(service->name);
8516 service->name = NULL;
8517 service->hidden = true;
8520 service->strength = connman_network_get_strength(network);
8521 service->roaming = connman_network_get_bool(network, "Roaming");
8523 if (service->strength == 0) {
8525 * Filter out 0-values; it's unclear what they mean
8526 * and they cause anomalous sorting of the priority list.
8528 service->strength = strength;
8531 str = connman_network_get_string(network, "WiFi.Security");
8532 service->security = convert_wifi_security(str);
8534 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
8535 service->wps = connman_network_get_bool(network, "WiFi.WPS");
8537 if (service->strength > strength && service->network) {
8538 connman_network_unref(service->network);
8539 service->network = connman_network_ref(network);
8541 strength_changed(service);
8544 if (!service->network)
8545 service->network = connman_network_ref(network);
8547 service_list_sort();
8551 * __connman_service_create_from_network:
8552 * @network: network structure
8554 * Look up service by network and if not found, create one
8556 struct connman_service * __connman_service_create_from_network(struct connman_network *network)
8558 struct connman_service *service;
8559 struct connman_device *device;
8560 const char *ident, *group;
8562 unsigned int *auto_connect_types;
8565 DBG("network %p", network);
8570 ident = __connman_network_get_ident(network);
8574 group = connman_network_get_group(network);
8578 name = g_strdup_printf("%s_%s_%s",
8579 __connman_network_get_type(network), ident, group);
8580 service = service_get(name);
8586 if (__connman_network_get_weakness(network))
8589 if (service->path) {
8590 update_from_network(service, network);
8591 __connman_connection_update_gateway();
8595 service->type = convert_network_type(network);
8597 auto_connect_types = connman_setting_get_uint_list("DefaultAutoConnectTechnologies");
8598 service->autoconnect = false;
8599 for (i = 0; auto_connect_types &&
8600 auto_connect_types[i] != 0; i++) {
8601 if (service->type == auto_connect_types[i]) {
8602 service->autoconnect = true;
8607 switch (service->type) {
8608 case CONNMAN_SERVICE_TYPE_UNKNOWN:
8609 case CONNMAN_SERVICE_TYPE_SYSTEM:
8610 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
8611 case CONNMAN_SERVICE_TYPE_GPS:
8612 case CONNMAN_SERVICE_TYPE_VPN:
8613 case CONNMAN_SERVICE_TYPE_GADGET:
8614 case CONNMAN_SERVICE_TYPE_WIFI:
8615 case CONNMAN_SERVICE_TYPE_CELLULAR:
8616 case CONNMAN_SERVICE_TYPE_P2P:
8618 case CONNMAN_SERVICE_TYPE_ETHERNET:
8619 service->favorite = true;
8623 service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
8624 service->state = combine_state(service->state_ipv4, service->state_ipv6);
8626 update_from_network(service, network);
8628 index = connman_network_get_index(network);
8630 if (!service->ipconfig_ipv4)
8631 service->ipconfig_ipv4 = create_ip4config(service, index,
8632 CONNMAN_IPCONFIG_METHOD_DHCP);
8634 if (!service->ipconfig_ipv6)
8635 service->ipconfig_ipv6 = create_ip6config(service, index);
8637 service_register(service);
8639 if (service->favorite) {
8640 device = connman_network_get_device(service->network);
8641 if (device && !connman_device_get_scanning(device)) {
8643 switch (service->type) {
8644 case CONNMAN_SERVICE_TYPE_UNKNOWN:
8645 case CONNMAN_SERVICE_TYPE_SYSTEM:
8646 case CONNMAN_SERVICE_TYPE_P2P:
8649 case CONNMAN_SERVICE_TYPE_GADGET:
8650 case CONNMAN_SERVICE_TYPE_ETHERNET:
8651 if (service->autoconnect) {
8652 __connman_service_connect(service,
8653 CONNMAN_SERVICE_CONNECT_REASON_AUTO);
8658 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
8659 case CONNMAN_SERVICE_TYPE_GPS:
8660 case CONNMAN_SERVICE_TYPE_VPN:
8661 case CONNMAN_SERVICE_TYPE_WIFI:
8662 case CONNMAN_SERVICE_TYPE_CELLULAR:
8663 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
8668 #if defined TIZEN_EXT
8669 /* TIZEN synchronizes below information when the service creates */
8670 if (service->eap != NULL)
8671 connman_network_set_string(service->network, "WiFi.EAP",
8673 if (service->identity != NULL)
8674 connman_network_set_string(service->network, "WiFi.Identity",
8676 if (service->phase2 != NULL)
8677 connman_network_set_string(service->network, "WiFi.Phase2",
8682 __connman_notifier_service_add(service, service->name);
8683 service_schedule_added(service);
8688 void __connman_service_update_from_network(struct connman_network *network)
8690 bool need_sort = false;
8691 struct connman_service *service;
8697 service = connman_service_lookup_from_network(network);
8701 if (!service->network)
8704 #if defined TIZEN_EXT
8705 if (service->storage_reload) {
8706 service_load(service);
8707 __connman_service_set_storage_reload(service, false);
8711 name = connman_network_get_string(service->network, "Name");
8712 if (g_strcmp0(service->name, name) != 0) {
8713 g_free(service->name);
8714 service->name = g_strdup(name);
8716 if (allow_property_changed(service))
8717 connman_dbus_property_changed_basic(service->path,
8718 CONNMAN_SERVICE_INTERFACE, "Name",
8719 DBUS_TYPE_STRING, &service->name);
8722 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
8723 service->wps = connman_network_get_bool(network, "WiFi.WPS");
8725 strength = connman_network_get_strength(service->network);
8726 if (strength == service->strength)
8729 service->strength = strength;
8732 strength_changed(service);
8735 roaming = connman_network_get_bool(service->network, "Roaming");
8736 if (roaming == service->roaming)
8739 stats_enable = stats_enabled(service);
8741 stats_stop(service);
8743 service->roaming = roaming;
8747 stats_start(service);
8749 roaming_changed(service);
8753 service_list_sort();
8757 void __connman_service_remove_from_network(struct connman_network *network)
8759 struct connman_service *service;
8761 service = connman_service_lookup_from_network(network);
8763 DBG("network %p service %p", network, service);
8768 service->ignore = true;
8770 __connman_connection_gateway_remove(service,
8771 CONNMAN_IPCONFIG_TYPE_ALL);
8773 connman_service_unref(service);
8777 * __connman_service_create_from_provider:
8778 * @provider: provider structure
8780 * Look up service by provider and if not found, create one
8782 struct connman_service *
8783 __connman_service_create_from_provider(struct connman_provider *provider)
8785 struct connman_service *service;
8786 const char *ident, *str;
8788 int index = connman_provider_get_index(provider);
8790 DBG("provider %p", provider);
8792 ident = __connman_provider_get_ident(provider);
8796 name = g_strdup_printf("vpn_%s", ident);
8797 service = service_get(name);
8803 service->type = CONNMAN_SERVICE_TYPE_VPN;
8804 service->provider = connman_provider_ref(provider);
8805 service->autoconnect = false;
8806 service->favorite = true;
8808 service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
8809 service->state = combine_state(service->state_ipv4, service->state_ipv6);
8811 str = connman_provider_get_string(provider, "Name");
8813 g_free(service->name);
8814 service->name = g_strdup(str);
8815 service->hidden = false;
8817 g_free(service->name);
8818 service->name = NULL;
8819 service->hidden = true;
8822 service->strength = 0;
8824 if (!service->ipconfig_ipv4)
8825 service->ipconfig_ipv4 = create_ip4config(service, index,
8826 CONNMAN_IPCONFIG_METHOD_MANUAL);
8828 if (!service->ipconfig_ipv6)
8829 service->ipconfig_ipv6 = create_ip6config(service, index);
8831 service_register(service);
8833 __connman_notifier_service_add(service, service->name);
8834 service_schedule_added(service);
8839 static void remove_unprovisioned_services(void)
8842 GKeyFile *keyfile, *configkeyfile;
8843 char *file, *section;
8846 services = connman_storage_get_services();
8850 for (; services[i]; i++) {
8851 file = section = NULL;
8852 keyfile = configkeyfile = NULL;
8854 keyfile = connman_storage_load_service(services[i]);
8858 file = g_key_file_get_string(keyfile, services[i],
8859 "Config.file", NULL);
8863 section = g_key_file_get_string(keyfile, services[i],
8864 "Config.ident", NULL);
8868 configkeyfile = __connman_storage_load_config(file);
8869 if (!configkeyfile) {
8871 * Config file is missing, remove the provisioned
8874 __connman_storage_remove_service(services[i]);
8878 if (!g_key_file_has_group(configkeyfile, section))
8880 * Config section is missing, remove the provisioned
8883 __connman_storage_remove_service(services[i]);
8887 g_key_file_free(keyfile);
8890 g_key_file_free(configkeyfile);
8896 g_strfreev(services);
8899 static int agent_probe(struct connman_agent *agent)
8901 DBG("agent %p", agent);
8905 static void agent_remove(struct connman_agent *agent)
8907 DBG("agent %p", agent);
8910 static void *agent_context_ref(void *context)
8912 struct connman_service *service = context;
8914 return (void *)connman_service_ref(service);
8917 static void agent_context_unref(void *context)
8919 struct connman_service *service = context;
8921 connman_service_unref(service);
8924 static struct connman_agent_driver agent_driver = {
8926 .interface = CONNMAN_AGENT_INTERFACE,
8927 .probe = agent_probe,
8928 .remove = agent_remove,
8929 .context_ref = agent_context_ref,
8930 .context_unref = agent_context_unref,
8933 int __connman_service_init(void)
8939 err = connman_agent_driver_register(&agent_driver);
8941 connman_error("Cannot register agent driver for %s",
8946 connection = connman_dbus_get_connection();
8948 service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
8949 NULL, service_free);
8951 services_notify = g_new0(struct _services_notify, 1);
8952 services_notify->remove = g_hash_table_new_full(g_str_hash,
8953 g_str_equal, g_free, NULL);
8954 services_notify->add = g_hash_table_new(g_str_hash, g_str_equal);
8956 remove_unprovisioned_services();
8961 void __connman_service_cleanup(void)
8965 if (vpn_autoconnect_timeout) {
8966 g_source_remove(vpn_autoconnect_timeout);
8967 vpn_autoconnect_timeout = 0;
8970 if (autoconnect_timeout != 0) {
8971 g_source_remove(autoconnect_timeout);
8972 autoconnect_timeout = 0;
8975 connman_agent_driver_unregister(&agent_driver);
8977 g_list_free(service_list);
8978 service_list = NULL;
8980 g_hash_table_destroy(service_hash);
8981 service_hash = NULL;
8983 g_slist_free(counter_list);
8984 counter_list = NULL;
8986 if (services_notify->id != 0) {
8987 g_source_remove(services_notify->id);
8988 service_send_changed(NULL);
8989 g_hash_table_destroy(services_notify->remove);
8990 g_hash_table_destroy(services_notify->add);
8992 g_free(services_notify);
8994 dbus_connection_unref(connection);