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;
3158 unsigned char *bssid;
3159 unsigned int maxrate;
3160 unsigned int keymgmt;
3162 const char *enc_mode;
3165 bssid = connman_network_get_bssid(network);
3166 maxrate = connman_network_get_maxrate(network);
3167 frequency = connman_network_get_frequency(network);
3168 enc_mode = connman_network_get_enc_mode(network);
3169 passpoint = connman_network_get_is_hs20AP(network);
3170 keymgmt = connman_network_get_keymgmt(network);
3172 snprintf(bssid_str, WIFI_BSSID_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
3173 bssid[0], bssid[1], bssid[2],
3174 bssid[3], bssid[4], bssid[5]);
3176 connman_dbus_dict_append_basic(dict, "BSSID",
3177 DBUS_TYPE_STRING, &bssid_str);
3178 connman_dbus_dict_append_basic(dict, "MaxRate",
3179 DBUS_TYPE_UINT32, &maxrate);
3180 connman_dbus_dict_append_basic(dict, "Frequency",
3181 DBUS_TYPE_UINT16, &frequency);
3182 connman_dbus_dict_append_basic(dict, "EncryptionMode",
3183 DBUS_TYPE_STRING, &enc_mode);
3184 connman_dbus_dict_append_basic(dict, "Passpoint",
3185 DBUS_TYPE_BOOLEAN, &passpoint);
3186 connman_dbus_dict_append_basic(dict, "Keymgmt",
3187 DBUS_TYPE_UINT32, &keymgmt);
3191 static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
3192 struct connman_service *service)
3198 #if defined TIZEN_EXT
3199 unsigned int frequency = 0U;
3200 if (service && service->network) {
3201 frequency = connman_network_get_frequency(service->network);
3202 connman_dbus_dict_append_basic(dict, "Frequency",
3203 DBUS_TYPE_UINT16, &frequency);
3207 str = __connman_service_type2string(service->type);
3209 connman_dbus_dict_append_basic(dict, "Type",
3210 DBUS_TYPE_STRING, &str);
3212 connman_dbus_dict_append_array(dict, "Security",
3213 DBUS_TYPE_STRING, append_security, service);
3215 str = state2string(service->state);
3217 connman_dbus_dict_append_basic(dict, "State",
3218 DBUS_TYPE_STRING, &str);
3221 str = state2string(service->state_ipv6);
3223 connman_dbus_dict_append_basic(dict, "StateIPv6",
3224 DBUS_TYPE_STRING, &str);
3227 str = error2string(service->error);
3229 connman_dbus_dict_append_basic(dict, "Error",
3230 DBUS_TYPE_STRING, &str);
3232 if (service->strength > 0)
3233 connman_dbus_dict_append_basic(dict, "Strength",
3234 DBUS_TYPE_BYTE, &service->strength);
3236 val = service->favorite;
3237 connman_dbus_dict_append_basic(dict, "Favorite",
3238 DBUS_TYPE_BOOLEAN, &val);
3240 val = service->immutable;
3241 connman_dbus_dict_append_basic(dict, "Immutable",
3242 DBUS_TYPE_BOOLEAN, &val);
3244 if (service->favorite)
3245 val = service->autoconnect;
3247 val = service->favorite;
3249 connman_dbus_dict_append_basic(dict, "AutoConnect",
3250 DBUS_TYPE_BOOLEAN, &val);
3253 connman_dbus_dict_append_basic(dict, "Name",
3254 DBUS_TYPE_STRING, &service->name);
3256 switch (service->type) {
3257 case CONNMAN_SERVICE_TYPE_UNKNOWN:
3258 case CONNMAN_SERVICE_TYPE_SYSTEM:
3259 case CONNMAN_SERVICE_TYPE_GPS:
3260 case CONNMAN_SERVICE_TYPE_VPN:
3261 case CONNMAN_SERVICE_TYPE_P2P:
3263 case CONNMAN_SERVICE_TYPE_CELLULAR:
3264 val = service->roaming;
3265 connman_dbus_dict_append_basic(dict, "Roaming",
3266 DBUS_TYPE_BOOLEAN, &val);
3268 connman_dbus_dict_append_dict(dict, "Ethernet",
3269 append_ethernet, service);
3271 case CONNMAN_SERVICE_TYPE_WIFI:
3272 #if defined TIZEN_EXT
3273 if (service->network != NULL)
3274 append_wifi_ext_info(dict, service->network);
3276 connman_dbus_dict_append_dict(dict, "Ethernet",
3277 append_ethernet, service);
3279 connman_dbus_dict_append_basic(dict, "DisconnectReason",
3280 DBUS_TYPE_INT32, &service->disconnect_reason);
3284 case CONNMAN_SERVICE_TYPE_ETHERNET:
3285 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
3286 case CONNMAN_SERVICE_TYPE_GADGET:
3287 connman_dbus_dict_append_dict(dict, "Ethernet",
3288 append_ethernet, service);
3292 connman_dbus_dict_append_dict(dict, "IPv4", append_ipv4, service);
3294 connman_dbus_dict_append_dict(dict, "IPv4.Configuration",
3295 append_ipv4config, service);
3297 connman_dbus_dict_append_dict(dict, "IPv6", append_ipv6, service);
3299 connman_dbus_dict_append_dict(dict, "IPv6.Configuration",
3300 append_ipv6config, service);
3302 connman_dbus_dict_append_array(dict, "Nameservers",
3303 DBUS_TYPE_STRING, append_dns, service);
3305 connman_dbus_dict_append_array(dict, "Nameservers.Configuration",
3306 DBUS_TYPE_STRING, append_dnsconfig, service);
3308 if (service->state == CONNMAN_SERVICE_STATE_READY ||
3309 service->state == CONNMAN_SERVICE_STATE_ONLINE)
3310 list = __connman_timeserver_get_all(service);
3314 connman_dbus_dict_append_array(dict, "Timeservers",
3315 DBUS_TYPE_STRING, append_ts, list);
3317 g_slist_free_full(list, g_free);
3319 connman_dbus_dict_append_array(dict, "Timeservers.Configuration",
3320 DBUS_TYPE_STRING, append_tsconfig, service);
3322 connman_dbus_dict_append_array(dict, "Domains",
3323 DBUS_TYPE_STRING, append_domain, service);
3325 connman_dbus_dict_append_array(dict, "Domains.Configuration",
3326 DBUS_TYPE_STRING, append_domainconfig, service);
3328 connman_dbus_dict_append_dict(dict, "Proxy", append_proxy, service);
3330 connman_dbus_dict_append_dict(dict, "Proxy.Configuration",
3331 append_proxyconfig, service);
3333 connman_dbus_dict_append_dict(dict, "Provider",
3334 append_provider, service);
3337 static void append_struct_service(DBusMessageIter *iter,
3338 connman_dbus_append_cb_t function,
3339 struct connman_service *service)
3341 DBusMessageIter entry, dict;
3343 dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &entry);
3345 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
3348 connman_dbus_dict_open(&entry, &dict);
3350 function(&dict, service);
3351 connman_dbus_dict_close(&entry, &dict);
3353 dbus_message_iter_close_container(iter, &entry);
3356 static void append_dict_properties(DBusMessageIter *dict, void *user_data)
3358 struct connman_service *service = user_data;
3360 append_properties(dict, TRUE, service);
3363 static void append_struct(gpointer value, gpointer user_data)
3365 struct connman_service *service = value;
3366 DBusMessageIter *iter = user_data;
3371 append_struct_service(iter, append_dict_properties, service);
3374 void __connman_service_list_struct(DBusMessageIter *iter)
3376 g_list_foreach(service_list, append_struct, iter);
3379 bool __connman_service_is_hidden(struct connman_service *service)
3381 return service->hidden;
3385 __connman_service_is_split_routing(struct connman_service *service)
3387 return service->do_split_routing;
3390 bool __connman_service_index_is_split_routing(int index)
3392 struct connman_service *service;
3397 service = __connman_service_lookup_from_index(index);
3401 return __connman_service_is_split_routing(service);
3404 int __connman_service_get_index(struct connman_service *service)
3409 if (service->network)
3410 return connman_network_get_index(service->network);
3411 else if (service->provider)
3412 return connman_provider_get_index(service->provider);
3417 void __connman_service_set_hidden(struct connman_service *service)
3419 if (!service || service->hidden)
3422 service->hidden_service = true;
3425 void __connman_service_set_hostname(struct connman_service *service,
3426 const char *hostname)
3428 if (!service || service->hidden)
3431 g_free(service->hostname);
3432 service->hostname = g_strdup(hostname);
3435 const char *__connman_service_get_hostname(struct connman_service *service)
3440 return service->hostname;
3443 void __connman_service_set_domainname(struct connman_service *service,
3444 const char *domainname)
3446 if (!service || service->hidden)
3449 g_free(service->domainname);
3450 service->domainname = g_strdup(domainname);
3452 domain_changed(service);
3455 const char *connman_service_get_domainname(struct connman_service *service)
3460 if (service->domains)
3461 return service->domains[0];
3463 return service->domainname;
3466 char **connman_service_get_nameservers(struct connman_service *service)
3471 if (service->nameservers_config)
3472 return g_strdupv(service->nameservers_config);
3473 else if (service->nameservers ||
3474 service->nameservers_auto) {
3475 int len = 0, len_auto = 0, i;
3478 if (service->nameservers)
3479 len = g_strv_length(service->nameservers);
3480 if (service->nameservers_auto)
3481 len_auto = g_strv_length(service->nameservers_auto);
3483 nameservers = g_try_new0(char *, len + len_auto + 1);
3487 for (i = 0; i < len; i++)
3488 nameservers[i] = g_strdup(service->nameservers[i]);
3490 for (i = 0; i < len_auto; i++)
3491 nameservers[i + len] =
3492 g_strdup(service->nameservers_auto[i]);
3497 return g_strdupv(connman_setting_get_string_list("FallbackNameservers"));
3500 char **connman_service_get_timeservers_config(struct connman_service *service)
3505 return service->timeservers_config;
3508 char **connman_service_get_timeservers(struct connman_service *service)
3513 return service->timeservers;
3516 #if defined TIZEN_EXT
3518 * Description: Telephony plug-in requires manual PROXY setting function
3520 int connman_service_set_proxy(struct connman_service *service,
3521 const char *proxy, gboolean active)
3523 char **proxies_array = NULL;
3525 if (service == NULL)
3528 switch (service->type) {
3529 case CONNMAN_SERVICE_TYPE_CELLULAR:
3530 case CONNMAN_SERVICE_TYPE_ETHERNET:
3531 case CONNMAN_SERVICE_TYPE_WIFI:
3538 g_strfreev(service->proxies);
3539 service->proxies = NULL;
3542 proxies_array = g_strsplit(proxy, " ", 0);
3544 service->proxies = proxies_array;
3546 if (proxy == NULL) {
3547 service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
3548 DBG("proxy changed (%d)", active);
3550 service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_MANUAL;
3551 DBG("proxy chagned %s (%d)", proxy, active);
3554 if (active == TRUE) {
3555 proxy_changed(service);
3557 __connman_notifier_proxy_changed(service);
3564 void connman_service_set_proxy_method(struct connman_service *service,
3565 enum connman_service_proxy_method method)
3567 if (!service || service->hidden)
3570 service->proxy = method;
3572 proxy_changed(service);
3574 if (method != CONNMAN_SERVICE_PROXY_METHOD_AUTO)
3575 __connman_notifier_proxy_changed(service);
3578 enum connman_service_proxy_method connman_service_get_proxy_method(
3579 struct connman_service *service)
3582 return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
3584 if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN) {
3585 if (service->proxy_config == CONNMAN_SERVICE_PROXY_METHOD_AUTO &&
3587 return service->proxy;
3589 return service->proxy_config;
3592 return service->proxy;
3595 char **connman_service_get_proxy_servers(struct connman_service *service)
3597 return g_strdupv(service->proxies);
3600 char **connman_service_get_proxy_excludes(struct connman_service *service)
3602 return g_strdupv(service->excludes);
3605 const char *connman_service_get_proxy_url(struct connman_service *service)
3610 return service->pac;
3613 void __connman_service_set_proxy_autoconfig(struct connman_service *service,
3616 if (!service || service->hidden)
3619 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_AUTO;
3621 if (service->ipconfig_ipv4) {
3622 if (__connman_ipconfig_set_proxy_autoconfig(
3623 service->ipconfig_ipv4, url) < 0)
3625 } else if (service->ipconfig_ipv6) {
3626 if (__connman_ipconfig_set_proxy_autoconfig(
3627 service->ipconfig_ipv6, url) < 0)
3632 proxy_changed(service);
3634 __connman_notifier_proxy_changed(service);
3637 const char *connman_service_get_proxy_autoconfig(struct connman_service *service)
3642 if (service->ipconfig_ipv4)
3643 return __connman_ipconfig_get_proxy_autoconfig(
3644 service->ipconfig_ipv4);
3645 else if (service->ipconfig_ipv6)
3646 return __connman_ipconfig_get_proxy_autoconfig(
3647 service->ipconfig_ipv6);
3651 #if defined TIZEN_EXT
3652 int connman_service_get_ipv6_dns_method(struct connman_service *service)
3655 DBG("Service is NULL");
3659 return service->dns_config_method_ipv6;
3663 void __connman_service_set_timeservers(struct connman_service *service,
3671 g_strfreev(service->timeservers);
3672 service->timeservers = NULL;
3674 for (i = 0; timeservers && timeservers[i]; i++)
3675 __connman_service_timeserver_append(service, timeservers[i]);
3678 int __connman_service_timeserver_append(struct connman_service *service,
3679 const char *timeserver)
3683 DBG("service %p timeserver %s", service, timeserver);
3688 if (service->timeservers) {
3691 for (i = 0; service->timeservers[i]; i++)
3692 if (g_strcmp0(service->timeservers[i], timeserver) == 0)
3695 len = g_strv_length(service->timeservers);
3696 service->timeservers = g_try_renew(char *, service->timeservers,
3700 service->timeservers = g_try_new0(char *, len + 2);
3703 if (!service->timeservers)
3706 service->timeservers[len] = g_strdup(timeserver);
3707 service->timeservers[len + 1] = NULL;
3712 int __connman_service_timeserver_remove(struct connman_service *service,
3713 const char *timeserver)
3716 int len, i, j, found = 0;
3718 DBG("service %p timeserver %s", service, timeserver);
3723 if (!service->timeservers)
3726 for (i = 0; service->timeservers &&
3727 service->timeservers[i]; i++)
3728 if (g_strcmp0(service->timeservers[i], timeserver) == 0) {
3736 len = g_strv_length(service->timeservers);
3739 g_strfreev(service->timeservers);
3740 service->timeservers = NULL;
3745 servers = g_try_new0(char *, len);
3749 for (i = 0, j = 0; i < len; i++) {
3750 if (g_strcmp0(service->timeservers[i], timeserver) != 0) {
3751 servers[j] = g_strdup(service->timeservers[i]);
3757 servers[len - 1] = NULL;
3759 g_strfreev(service->timeservers);
3760 service->timeservers = servers;
3765 void __connman_service_timeserver_changed(struct connman_service *service,
3771 if (!allow_property_changed(service))
3774 connman_dbus_property_changed_array(service->path,
3775 CONNMAN_SERVICE_INTERFACE, "Timeservers",
3776 DBUS_TYPE_STRING, append_ts, ts_list);
3779 void __connman_service_set_pac(struct connman_service *service,
3782 if (service->hidden)
3784 g_free(service->pac);
3785 service->pac = g_strdup(pac);
3787 proxy_changed(service);
3790 #if defined TIZEN_EXT
3791 void __connman_service_set_proxy(struct connman_service *service,
3792 const char *proxies)
3794 char **proxies_array = NULL;
3796 g_strfreev(service->proxies);
3797 service->proxies = NULL;
3799 if (proxies != NULL)
3800 proxies_array = g_strsplit(proxies, " ", 0);
3802 service->proxies = proxies_array;
3806 void __connman_service_set_identity(struct connman_service *service,
3807 const char *identity)
3809 if (service->immutable || service->hidden)
3812 g_free(service->identity);
3813 service->identity = g_strdup(identity);
3815 if (service->network)
3816 connman_network_set_string(service->network,
3821 void __connman_service_set_agent_identity(struct connman_service *service,
3822 const char *agent_identity)
3824 if (service->hidden)
3826 g_free(service->agent_identity);
3827 service->agent_identity = g_strdup(agent_identity);
3829 if (service->network)
3830 connman_network_set_string(service->network,
3831 "WiFi.AgentIdentity",
3832 service->agent_identity);
3835 static int check_passphrase(enum connman_service_security security,
3836 const char *passphrase)
3844 length = strlen(passphrase);
3847 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
3848 case CONNMAN_SERVICE_SECURITY_NONE:
3849 case CONNMAN_SERVICE_SECURITY_WPA:
3850 #if !defined TIZEN_EXT
3851 case CONNMAN_SERVICE_SECURITY_RSN:
3854 DBG("service security '%s' (%d) not handled",
3855 security2string(security), security);
3859 case CONNMAN_SERVICE_SECURITY_PSK:
3860 #if defined TIZEN_EXT
3861 case CONNMAN_SERVICE_SECURITY_RSN:
3863 /* A raw key is always 64 bytes length,
3864 * its content is in hex representation.
3865 * A PSK key must be between [8..63].
3868 for (i = 0; i < 64; i++)
3869 if (!isxdigit((unsigned char)
3872 } else if (length < 8 || length > 63)
3875 case CONNMAN_SERVICE_SECURITY_WEP:
3876 /* length of WEP key is 10 or 26
3877 * length of WEP passphrase is 5 or 13
3879 if (length == 10 || length == 26) {
3880 for (i = 0; i < length; i++)
3881 if (!isxdigit((unsigned char)
3884 } else if (length != 5 && length != 13)
3888 case CONNMAN_SERVICE_SECURITY_8021X:
3895 int __connman_service_set_passphrase(struct connman_service *service,
3896 const char *passphrase)
3900 if (service->hidden)
3903 if (service->immutable &&
3904 service->security != CONNMAN_SERVICE_SECURITY_8021X)
3907 err = check_passphrase(service->security, passphrase);
3912 g_free(service->passphrase);
3913 service->passphrase = g_strdup(passphrase);
3915 if (service->network)
3916 connman_network_set_string(service->network, "WiFi.Passphrase",
3917 service->passphrase);
3922 const char *__connman_service_get_passphrase(struct connman_service *service)
3927 return service->passphrase;
3930 static DBusMessage *get_properties(DBusConnection *conn,
3931 DBusMessage *msg, void *user_data)
3933 struct connman_service *service = user_data;
3935 DBusMessageIter array, dict;
3937 DBG("service %p", service);
3939 reply = dbus_message_new_method_return(msg);
3943 dbus_message_iter_init_append(reply, &array);
3945 connman_dbus_dict_open(&array, &dict);
3946 append_properties(&dict, FALSE, service);
3947 connman_dbus_dict_close(&array, &dict);
3952 static int update_proxy_configuration(struct connman_service *service,
3953 DBusMessageIter *array)
3955 DBusMessageIter dict;
3956 enum connman_service_proxy_method method;
3957 GString *servers_str = NULL;
3958 GString *excludes_str = NULL;
3959 const char *url = NULL;
3961 method = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
3963 dbus_message_iter_recurse(array, &dict);
3965 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
3966 DBusMessageIter entry, variant;
3970 dbus_message_iter_recurse(&dict, &entry);
3972 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
3975 dbus_message_iter_get_basic(&entry, &key);
3976 dbus_message_iter_next(&entry);
3978 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
3981 dbus_message_iter_recurse(&entry, &variant);
3983 type = dbus_message_iter_get_arg_type(&variant);
3985 if (g_str_equal(key, "Method")) {
3988 if (type != DBUS_TYPE_STRING)
3991 dbus_message_iter_get_basic(&variant, &val);
3992 method = string2proxymethod(val);
3993 } else if (g_str_equal(key, "URL")) {
3994 if (type != DBUS_TYPE_STRING)
3997 dbus_message_iter_get_basic(&variant, &url);
3998 } else if (g_str_equal(key, "Servers")) {
3999 DBusMessageIter str_array;
4001 if (type != DBUS_TYPE_ARRAY)
4004 servers_str = g_string_new(NULL);
4008 dbus_message_iter_recurse(&variant, &str_array);
4010 while (dbus_message_iter_get_arg_type(&str_array) ==
4014 dbus_message_iter_get_basic(&str_array, &val);
4016 if (servers_str->len > 0)
4017 g_string_append_printf(servers_str,
4020 g_string_append(servers_str, val);
4022 dbus_message_iter_next(&str_array);
4024 } else if (g_str_equal(key, "Excludes")) {
4025 DBusMessageIter str_array;
4027 if (type != DBUS_TYPE_ARRAY)
4030 excludes_str = g_string_new(NULL);
4034 dbus_message_iter_recurse(&variant, &str_array);
4036 while (dbus_message_iter_get_arg_type(&str_array) ==
4040 dbus_message_iter_get_basic(&str_array, &val);
4042 if (excludes_str->len > 0)
4043 g_string_append_printf(excludes_str,
4046 g_string_append(excludes_str, val);
4048 dbus_message_iter_next(&str_array);
4052 dbus_message_iter_next(&dict);
4056 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
4058 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
4059 if (!servers_str && !service->proxies)
4063 g_strfreev(service->proxies);
4065 if (servers_str->len > 0)
4066 service->proxies = g_strsplit_set(
4067 servers_str->str, " ", 0);
4069 service->proxies = NULL;
4073 g_strfreev(service->excludes);
4075 if (excludes_str->len > 0)
4076 service->excludes = g_strsplit_set(
4077 excludes_str->str, " ", 0);
4079 service->excludes = NULL;
4082 if (!service->proxies)
4083 method = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
4086 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
4087 g_free(service->pac);
4089 if (url && strlen(url) > 0)
4090 service->pac = g_strdup(url);
4092 service->pac = NULL;
4094 /* if we are connected:
4095 - if service->pac == NULL
4096 - if __connman_ipconfig_get_proxy_autoconfig(
4097 service->ipconfig) == NULL
4098 --> We should start WPAD */
4101 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
4106 g_string_free(servers_str, TRUE);
4109 g_string_free(excludes_str, TRUE);
4111 service->proxy_config = method;
4117 g_string_free(servers_str, TRUE);
4120 g_string_free(excludes_str, TRUE);
4125 int __connman_service_reset_ipconfig(struct connman_service *service,
4126 enum connman_ipconfig_type type, DBusMessageIter *array,
4127 enum connman_service_state *new_state)
4129 struct connman_ipconfig *ipconfig, *new_ipconfig;
4130 enum connman_ipconfig_method old_method, new_method;
4131 enum connman_service_state state;
4134 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
4135 ipconfig = service->ipconfig_ipv4;
4136 state = service->state_ipv4;
4137 new_method = CONNMAN_IPCONFIG_METHOD_DHCP;
4138 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
4139 ipconfig = service->ipconfig_ipv6;
4140 state = service->state_ipv6;
4141 new_method = CONNMAN_IPCONFIG_METHOD_AUTO;
4148 old_method = __connman_ipconfig_get_method(ipconfig);
4149 index = __connman_ipconfig_get_index(ipconfig);
4151 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4152 new_ipconfig = create_ip4config(service, index,
4153 CONNMAN_IPCONFIG_METHOD_UNKNOWN);
4155 new_ipconfig = create_ip6config(service, index);
4158 err = __connman_ipconfig_set_config(new_ipconfig, array);
4160 __connman_ipconfig_unref(new_ipconfig);
4164 new_method = __connman_ipconfig_get_method(new_ipconfig);
4167 if (is_connecting_state(service, state) ||
4168 is_connected_state(service, state))
4169 __connman_network_clear_ipconfig(service->network, ipconfig);
4171 __connman_ipconfig_unref(ipconfig);
4173 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4174 service->ipconfig_ipv4 = new_ipconfig;
4175 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
4176 service->ipconfig_ipv6 = new_ipconfig;
4178 if (is_connecting_state(service, state) ||
4179 is_connected_state(service, state))
4180 __connman_ipconfig_enable(new_ipconfig);
4182 if (new_state && new_method != old_method) {
4183 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4184 *new_state = service->state_ipv4;
4186 *new_state = service->state_ipv6;
4188 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
4191 DBG("err %d ipconfig %p type %d method %d state %s", err,
4192 new_ipconfig, type, new_method,
4193 !new_state ? "-" : state2string(*new_state));
4198 static DBusMessage *set_property(DBusConnection *conn,
4199 DBusMessage *msg, void *user_data)
4201 struct connman_service *service = user_data;
4202 DBusMessageIter iter, value;
4206 DBG("service %p", service);
4208 if (!dbus_message_iter_init(msg, &iter))
4209 return __connman_error_invalid_arguments(msg);
4211 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
4212 return __connman_error_invalid_arguments(msg);
4214 if (service->type == CONNMAN_SERVICE_TYPE_WIFI && is_connected(service)) {
4216 if (connman_dbus_get_connection_unix_user_sync(conn,
4217 dbus_message_get_sender(msg),
4219 DBG("Can not get unix user id!");
4220 return __connman_error_permission_denied(msg);
4223 if (!connman_service_is_user_allowed(service, uid)) {
4224 DBG("Not allow this user to operate this wifi service now!");
4225 return __connman_error_permission_denied(msg);
4229 dbus_message_iter_get_basic(&iter, &name);
4230 dbus_message_iter_next(&iter);
4232 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
4233 return __connman_error_invalid_arguments(msg);
4235 dbus_message_iter_recurse(&iter, &value);
4237 type = dbus_message_iter_get_arg_type(&value);
4239 if (g_str_equal(name, "AutoConnect")) {
4240 dbus_bool_t autoconnect;
4242 if (type != DBUS_TYPE_BOOLEAN)
4243 return __connman_error_invalid_arguments(msg);
4245 if (!service->favorite)
4246 return __connman_error_invalid_service(msg);
4248 dbus_message_iter_get_basic(&value, &autoconnect);
4250 if (service->autoconnect == autoconnect)
4251 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
4253 service->autoconnect = autoconnect;
4255 autoconnect_changed(service);
4258 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
4260 service_save(service);
4261 } else if (g_str_equal(name, "Nameservers.Configuration")) {
4262 DBusMessageIter entry;
4266 #if defined TIZEN_EXT
4267 enum connman_ipconfig_type ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4271 if (__connman_provider_is_immutable(service->provider) ||
4273 return __connman_error_not_supported(msg);
4275 if (type != DBUS_TYPE_ARRAY)
4276 return __connman_error_invalid_arguments(msg);
4278 str = g_string_new(NULL);
4280 return __connman_error_invalid_arguments(msg);
4282 index = __connman_service_get_index(service);
4283 gw = __connman_ipconfig_get_gateway_from_index(index,
4284 CONNMAN_IPCONFIG_TYPE_ALL);
4286 if (gw && strlen(gw))
4287 __connman_service_nameserver_del_routes(service,
4288 CONNMAN_IPCONFIG_TYPE_ALL);
4290 dbus_message_iter_recurse(&value, &entry);
4292 #if defined TIZEN_EXT
4293 /* IPv4/IPv6 Last DNS config method */
4294 int last_dns_ipv4 = service->dns_config_method_ipv4;
4295 int last_dns_ipv6 = service->dns_config_method_ipv6;
4296 DBG("Last DNS Config Method IPv4: %d IPv6: %d", last_dns_ipv4, last_dns_ipv6);
4299 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
4301 dbus_message_iter_get_basic(&entry, &val);
4302 dbus_message_iter_next(&entry);
4304 /* First unpack the DNS Config Method */
4305 DBG("DNS Config Method: %s", val);
4306 if((g_strcmp0(val, "ipv4.manual") == 0)) {
4307 service->dns_config_method_ipv4 =
4308 CONNMAN_DNSCONFIG_METHOD_MANUAL;
4310 if(last_dns_ipv4 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
4311 if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
4312 ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
4314 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4317 } else if(g_strcmp0(val, "ipv4.dhcp") == 0) {
4318 service->dns_config_method_ipv4 =
4319 CONNMAN_DNSCONFIG_METHOD_DHCP;
4320 if(last_dns_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
4321 ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
4324 } else if(g_strcmp0(val, "ipv6.manual") == 0) {
4325 service->dns_config_method_ipv6 =
4326 CONNMAN_DNSCONFIG_METHOD_MANUAL;
4327 if(last_dns_ipv6 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
4328 if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
4329 ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
4331 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4334 } else if(g_strcmp0(val, "ipv6.dhcp") == 0) {
4335 service->dns_config_method_ipv6 =
4336 CONNMAN_DNSCONFIG_METHOD_DHCP;
4337 if(last_dns_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
4338 ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
4343 if (connman_inet_check_ipaddress(val) > 0) {
4345 g_string_append_printf(str, " %s", val);
4347 g_string_append(str, val);
4351 #if defined TIZEN_EXT
4352 if (service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_DHCP &&
4353 service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_DHCP) {
4354 DBG("Both IPv4 and IPv6 DNS Method DHCP");
4355 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4357 if (gw && strlen(gw))
4358 __connman_service_nameserver_del_routes(service,
4361 DBG("%s ip_type: %d nameserver remove all", name, ip_type);
4362 nameserver_remove_all(service, ip_type);
4364 nameserver_remove_all(service);
4366 g_strfreev(service->nameservers_config);
4369 service->nameservers_config =
4370 g_strsplit_set(str->str, " ", 0);
4372 service->nameservers_config = NULL;
4375 g_string_free(str, TRUE);
4377 if (gw && strlen(gw))
4378 __connman_service_nameserver_add_routes(service, gw);
4380 #if defined TIZEN_EXT
4381 DBG("%s ip_type: %d nameserver add all", name, ip_type);
4382 nameserver_add_all(service, ip_type);
4384 nameserver_add_all(service);
4386 dns_configuration_changed(service);
4388 if (__connman_service_is_connected_state(service,
4389 CONNMAN_IPCONFIG_TYPE_IPV4))
4390 __connman_wispr_start(service,
4391 CONNMAN_IPCONFIG_TYPE_IPV4);
4393 if (__connman_service_is_connected_state(service,
4394 CONNMAN_IPCONFIG_TYPE_IPV6))
4395 __connman_wispr_start(service,
4396 CONNMAN_IPCONFIG_TYPE_IPV6);
4398 service_save(service);
4399 } else if (g_str_equal(name, "Timeservers.Configuration")) {
4400 DBusMessageIter entry;
4401 GSList *list = NULL;
4404 if (service->immutable)
4405 return __connman_error_not_supported(msg);
4407 if (type != DBUS_TYPE_ARRAY)
4408 return __connman_error_invalid_arguments(msg);
4410 dbus_message_iter_recurse(&value, &entry);
4412 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
4416 dbus_message_iter_get_basic(&entry, &val);
4418 new_head = __connman_timeserver_add_list(list, val);
4419 if (list != new_head) {
4424 dbus_message_iter_next(&entry);
4427 g_strfreev(service->timeservers_config);
4428 service->timeservers_config = NULL;
4431 service->timeservers_config = g_new0(char *, count+1);
4435 service->timeservers_config[count] = list->data;
4436 list = g_slist_delete_link(list, list);
4440 service_save(service);
4441 timeservers_configuration_changed(service);
4443 if (service == __connman_service_get_default())
4444 __connman_timeserver_sync(service);
4446 } else if (g_str_equal(name, "Domains.Configuration")) {
4447 DBusMessageIter entry;
4450 if (service->immutable)
4451 return __connman_error_not_supported(msg);
4453 if (type != DBUS_TYPE_ARRAY)
4454 return __connman_error_invalid_arguments(msg);
4456 str = g_string_new(NULL);
4458 return __connman_error_invalid_arguments(msg);
4460 dbus_message_iter_recurse(&value, &entry);
4462 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
4464 dbus_message_iter_get_basic(&entry, &val);
4465 dbus_message_iter_next(&entry);
4467 g_string_append_printf(str, " %s", val);
4469 g_string_append(str, val);
4472 searchdomain_remove_all(service);
4473 g_strfreev(service->domains);
4476 service->domains = g_strsplit_set(str->str, " ", 0);
4478 service->domains = NULL;
4480 g_string_free(str, TRUE);
4482 searchdomain_add_all(service);
4483 domain_configuration_changed(service);
4484 domain_changed(service);
4486 service_save(service);
4487 } else if (g_str_equal(name, "Proxy.Configuration")) {
4490 if (service->immutable)
4491 return __connman_error_not_supported(msg);
4493 if (type != DBUS_TYPE_ARRAY)
4494 return __connman_error_invalid_arguments(msg);
4496 err = update_proxy_configuration(service, &value);
4499 return __connman_error_failed(msg, -err);
4501 proxy_configuration_changed(service);
4503 __connman_notifier_proxy_changed(service);
4505 service_save(service);
4506 } else if (g_str_equal(name, "IPv4.Configuration") ||
4507 g_str_equal(name, "IPv6.Configuration")) {
4509 enum connman_service_state state =
4510 CONNMAN_SERVICE_STATE_UNKNOWN;
4511 enum connman_ipconfig_type type =
4512 CONNMAN_IPCONFIG_TYPE_UNKNOWN;
4515 if (service->type == CONNMAN_SERVICE_TYPE_VPN ||
4517 return __connman_error_not_supported(msg);
4521 if (!service->ipconfig_ipv4 &&
4522 !service->ipconfig_ipv6)
4523 return __connman_error_invalid_property(msg);
4525 if (g_str_equal(name, "IPv4.Configuration"))
4526 type = CONNMAN_IPCONFIG_TYPE_IPV4;
4528 type = CONNMAN_IPCONFIG_TYPE_IPV6;
4530 err = __connman_service_reset_ipconfig(service, type, &value,
4534 if (is_connected_state(service, state) ||
4535 is_connecting_state(service, state)) {
4536 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4537 __connman_network_enable_ipconfig(service->network,
4538 service->ipconfig_ipv4);
4540 __connman_network_enable_ipconfig(service->network,
4541 service->ipconfig_ipv6);
4544 return __connman_error_failed(msg, -err);
4547 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4548 ipv4_configuration_changed(service);
4550 ipv6_configuration_changed(service);
4552 if (is_connecting(service) || is_connected(service)) {
4553 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4554 __connman_network_enable_ipconfig(service->network,
4555 service->ipconfig_ipv4);
4557 __connman_network_enable_ipconfig(service->network,
4558 service->ipconfig_ipv6);
4561 service_save(service);
4563 return __connman_error_invalid_property(msg);
4565 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
4568 static void set_error(struct connman_service *service,
4569 enum connman_service_error error)
4573 if (service->error == error)
4576 service->error = error;
4581 #if !defined TIZEN_EXT
4582 if (!allow_property_changed(service))
4586 str = error2string(service->error);
4591 connman_dbus_property_changed_basic(service->path,
4592 CONNMAN_SERVICE_INTERFACE, "Error",
4593 DBUS_TYPE_STRING, &str);
4596 static void set_idle(struct connman_service *service)
4598 service->state = service->state_ipv4 = service->state_ipv6 =
4599 CONNMAN_SERVICE_STATE_IDLE;
4600 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
4601 state_changed(service);
4604 static DBusMessage *clear_property(DBusConnection *conn,
4605 DBusMessage *msg, void *user_data)
4607 struct connman_service *service = user_data;
4610 DBG("service %p", service);
4612 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
4615 if (g_str_equal(name, "Error")) {
4616 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
4618 g_get_current_time(&service->modified);
4619 service_save(service);
4621 return __connman_error_invalid_property(msg);
4623 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
4626 static bool is_ipconfig_usable(struct connman_service *service)
4628 if (!__connman_ipconfig_is_usable(service->ipconfig_ipv4) &&
4629 !__connman_ipconfig_is_usable(service->ipconfig_ipv6))
4635 static bool is_ignore(struct connman_service *service)
4637 if (!service->autoconnect)
4640 if (service->roaming)
4643 if (service->ignore)
4646 if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
4649 if (!is_ipconfig_usable(service))
4655 static void disconnect_on_last_session(enum connman_service_type type)
4659 for (list = service_list; list; list = list->next) {
4660 struct connman_service *service = list->data;
4662 if (service->type != type)
4665 if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_SESSION)
4668 __connman_service_disconnect(service);
4673 static int active_sessions[MAX_CONNMAN_SERVICE_TYPES] = {};
4674 static int active_count = 0;
4676 void __connman_service_set_active_session(bool enable, GSList *list)
4686 while (list != NULL) {
4687 enum connman_service_type type = GPOINTER_TO_INT(list->data);
4690 case CONNMAN_SERVICE_TYPE_ETHERNET:
4691 case CONNMAN_SERVICE_TYPE_WIFI:
4692 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
4693 case CONNMAN_SERVICE_TYPE_CELLULAR:
4694 case CONNMAN_SERVICE_TYPE_GADGET:
4696 active_sessions[type]++;
4698 active_sessions[type]--;
4701 case CONNMAN_SERVICE_TYPE_UNKNOWN:
4702 case CONNMAN_SERVICE_TYPE_SYSTEM:
4703 case CONNMAN_SERVICE_TYPE_GPS:
4704 case CONNMAN_SERVICE_TYPE_VPN:
4705 case CONNMAN_SERVICE_TYPE_P2P:
4709 if (active_sessions[type] == 0)
4710 disconnect_on_last_session(type);
4712 list = g_slist_next(list);
4715 DBG("eth %d wifi %d bt %d cellular %d gadget %d sessions %d",
4716 active_sessions[CONNMAN_SERVICE_TYPE_ETHERNET],
4717 active_sessions[CONNMAN_SERVICE_TYPE_WIFI],
4718 active_sessions[CONNMAN_SERVICE_TYPE_BLUETOOTH],
4719 active_sessions[CONNMAN_SERVICE_TYPE_CELLULAR],
4720 active_sessions[CONNMAN_SERVICE_TYPE_GADGET],
4724 struct preferred_tech_data {
4725 GList *preferred_list;
4726 enum connman_service_type type;
4729 static void preferred_tech_add_by_type(gpointer data, gpointer user_data)
4731 struct connman_service *service = data;
4732 struct preferred_tech_data *tech_data = user_data;
4734 if (service->type == tech_data->type) {
4735 tech_data->preferred_list =
4736 g_list_append(tech_data->preferred_list, service);
4738 DBG("type %d service %p %s", tech_data->type, service,
4743 static GList *preferred_tech_list_get(void)
4745 unsigned int *tech_array;
4746 struct preferred_tech_data tech_data = { 0, };
4749 tech_array = connman_setting_get_uint_list("PreferredTechnologies");
4753 if (connman_setting_get_bool("SingleConnectedTechnology")) {
4755 for (list = service_list; list; list = list->next) {
4756 struct connman_service *service = list->data;
4758 if (!is_connected(service))
4761 if (service->connect_reason ==
4762 CONNMAN_SERVICE_CONNECT_REASON_USER) {
4763 DBG("service %p name %s is user connected",
4764 service, service->name);
4765 #if defined TIZEN_EXT
4766 /* We can connect to a favorite service like
4767 * wifi even we have a userconnect for cellular
4768 * because we have refount for cellular service
4770 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
4773 if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
4781 for (i = 0; tech_array[i] != 0; i += 1) {
4782 tech_data.type = tech_array[i];
4783 g_list_foreach(service_list, preferred_tech_add_by_type,
4787 return tech_data.preferred_list;
4790 static bool auto_connect_service(GList *services,
4791 enum connman_service_connect_reason reason,
4794 struct connman_service *service = NULL;
4795 bool ignore[MAX_CONNMAN_SERVICE_TYPES] = { };
4796 bool autoconnecting = false;
4799 DBG("preferred %d sessions %d reason %s", preferred, active_count,
4800 reason2string(reason));
4802 ignore[CONNMAN_SERVICE_TYPE_VPN] = true;
4804 for (list = services; list; list = list->next) {
4805 service = list->data;
4807 if (ignore[service->type]) {
4808 DBG("service %p type %s ignore", service,
4809 __connman_service_type2string(service->type));
4813 #if defined TIZEN_EXT
4814 DBG("service %p %s %s %s, favorite(%d), ignore(%d), hidden(%d, %d)",
4815 service, service->name,
4816 state2string(service->state),
4817 __connman_service_type2string(service->type),
4818 service->favorite, is_ignore(service),
4819 service->hidden, service->hidden_service);
4821 /* Tizen takes Wi-Fi as the highest priority into consideration. */
4822 if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
4823 if (is_connecting(service) == TRUE || is_connected(service) == TRUE)
4827 if (service->pending ||
4828 is_connecting(service) ||
4829 is_connected(service)) {
4833 ignore[service->type] = true;
4834 autoconnecting = true;
4836 DBG("service %p type %s busy", service,
4837 __connman_service_type2string(service->type));
4842 if (!service->favorite) {
4846 #if defined TIZEN_EXT
4847 DBG("Service is not favorite, autoconnecting %d",
4850 return autoconnecting;
4853 #if defined TIZEN_EXT
4854 DBG("service %p identifier %s roaming %d ignore %d "
4855 "ipconfig_usable %d autoconnect %d state %d",
4857 service->identifier, service->roaming,
4858 service->ignore, is_ipconfig_usable(service),
4859 service->autoconnect, service->state);
4861 if (is_ignore(service) || service->state !=
4862 CONNMAN_SERVICE_STATE_IDLE)
4865 if (autoconnecting && !active_sessions[service->type]) {
4866 DBG("service %p type %s has no users", service,
4867 __connman_service_type2string(service->type));
4871 if (!is_service_owner_user_login(service)) {
4872 DBG("favorite user not login, wifi auto connect denied");
4876 DBG("service %p %s %s", service, service->name,
4877 (preferred) ? "preferred" : reason2string(reason));
4879 __connman_service_connect(service, reason);
4884 ignore[service->type] = true;
4887 return autoconnecting;
4890 static gboolean run_auto_connect(gpointer data)
4892 enum connman_service_connect_reason reason = GPOINTER_TO_UINT(data);
4893 bool autoconnecting = false;
4894 GList *preferred_tech;
4896 autoconnect_timeout = 0;
4900 preferred_tech = preferred_tech_list_get();
4901 if (preferred_tech) {
4902 autoconnecting = auto_connect_service(preferred_tech, reason,
4904 g_list_free(preferred_tech);
4907 if (!autoconnecting || active_count)
4908 auto_connect_service(service_list, reason, false);
4913 void __connman_service_auto_connect(enum connman_service_connect_reason reason)
4917 if (autoconnect_timeout != 0)
4920 if (!__connman_session_policy_autoconnect(reason))
4923 #if defined TIZEN_EXT
4924 /* Adding Timeout of 500ms before trying to auto connect.
4925 * This is done because of below scenario
4926 * 1. Device is connected to AP1
4927 * 2. WPS Connection request is initiated for AP2
4928 * 3. Immediately WPS Connection is Cancelled
4929 * When WPS Connection Connection is initiated for AP2 then
4930 * sometimes there is a scenario where connman gets in ASSOCIATED
4931 * state with AP1 due to autoconnect and subsequently the connection
4932 * initiated by AP1 fails and connman service for AP1 comes in
4933 * FAILURE state due to this when connection with AP2 is cancelled
4934 * then autoconnect with AP1 doesn't works because its autoconnection
4935 * is ignored as its last state was FAILURE rather than IDLE */
4936 autoconnect_timeout = g_timeout_add(500, run_auto_connect,
4938 autoconnect_timeout = g_timeout_add_seconds(0, run_auto_connect,
4940 GUINT_TO_POINTER(reason));
4943 static gboolean run_vpn_auto_connect(gpointer data) {
4945 bool need_split = false;
4947 vpn_autoconnect_timeout = 0;
4949 for (list = service_list; list; list = list->next) {
4950 struct connman_service *service = list->data;
4953 if (service->type != CONNMAN_SERVICE_TYPE_VPN)
4956 if (is_connected(service) || is_connecting(service)) {
4957 if (!service->do_split_routing)
4962 if (is_ignore(service) || !service->favorite)
4965 if (need_split && !service->do_split_routing) {
4966 DBG("service %p no split routing", service);
4970 DBG("service %p %s %s", service, service->name,
4971 service->do_split_routing ?
4972 "split routing" : "");
4974 res = __connman_service_connect(service,
4975 CONNMAN_SERVICE_CONNECT_REASON_AUTO);
4976 if (res < 0 && res != -EINPROGRESS)
4979 if (!service->do_split_routing)
4986 static void vpn_auto_connect(void)
4988 if (vpn_autoconnect_timeout)
4991 vpn_autoconnect_timeout =
4992 g_timeout_add_seconds(0, run_vpn_auto_connect, NULL);
4995 static void remove_timeout(struct connman_service *service)
4997 if (service->timeout > 0) {
4998 g_source_remove(service->timeout);
4999 service->timeout = 0;
5003 static void reply_pending(struct connman_service *service, int error)
5005 remove_timeout(service);
5007 if (service->pending) {
5008 connman_dbus_reply_pending(service->pending, error, NULL);
5009 service->pending = NULL;
5012 if (service->provider_pending) {
5013 connman_dbus_reply_pending(service->provider_pending,
5014 error, service->path);
5015 service->provider_pending = NULL;
5020 __connman_service_is_provider_pending(struct connman_service *service)
5025 if (service->provider_pending)
5031 void __connman_service_set_provider_pending(struct connman_service *service,
5034 if (service->provider_pending) {
5035 DBG("service %p provider pending msg %p already exists",
5036 service, service->provider_pending);
5040 service->provider_pending = msg;
5044 static void check_pending_msg(struct connman_service *service)
5046 if (!service->pending)
5049 DBG("service %p pending msg %p already exists", service,
5051 dbus_message_unref(service->pending);
5054 void __connman_service_set_hidden_data(struct connman_service *service,
5057 DBusMessage *pending = user_data;
5059 DBG("service %p pending %p", service, pending);
5064 check_pending_msg(service);
5066 service->pending = pending;
5069 void __connman_service_return_error(struct connman_service *service,
5070 int error, gpointer user_data)
5072 DBG("service %p error %d user_data %p", service, error, user_data);
5074 __connman_service_set_hidden_data(service, user_data);
5076 reply_pending(service, error);
5079 static gboolean connect_timeout(gpointer user_data)
5081 struct connman_service *service = user_data;
5082 bool autoconnect = false;
5084 DBG("service %p", service);
5086 service->timeout = 0;
5088 if (service->network)
5089 __connman_network_disconnect(service->network);
5090 else if (service->provider)
5091 connman_provider_disconnect(service->provider);
5093 __connman_ipconfig_disable(service->ipconfig_ipv4);
5094 __connman_ipconfig_disable(service->ipconfig_ipv6);
5096 __connman_stats_service_unregister(service);
5098 if (service->pending) {
5101 reply = __connman_error_operation_timeout(service->pending);
5103 g_dbus_send_message(connection, reply);
5105 dbus_message_unref(service->pending);
5106 service->pending = NULL;
5110 __connman_service_ipconfig_indicate_state(service,
5111 CONNMAN_SERVICE_STATE_FAILURE,
5112 CONNMAN_IPCONFIG_TYPE_IPV4);
5113 __connman_service_ipconfig_indicate_state(service,
5114 CONNMAN_SERVICE_STATE_FAILURE,
5115 CONNMAN_IPCONFIG_TYPE_IPV6);
5118 service->connect_reason !=
5119 CONNMAN_SERVICE_CONNECT_REASON_USER)
5120 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
5125 static DBusMessage *connect_service(DBusConnection *conn,
5126 DBusMessage *msg, void *user_data)
5128 struct connman_service *service = user_data;
5129 #if defined TIZEN_EXT
5136 DBG("service %p", service);
5138 #if defined TIZEN_EXT
5140 * Description: TIZEN implements system global connection management.
5142 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
5143 connman_service_user_pdn_connection_ref(service);
5146 if (service->pending)
5147 return __connman_error_in_progress(msg);
5149 if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
5151 if (connman_dbus_get_connection_unix_user_sync(conn,
5152 dbus_message_get_sender(msg),
5154 DBG("Can not get unix user id!");
5155 return __connman_error_permission_denied(msg);
5158 if (!__connman_service_is_user_allowed(CONNMAN_SERVICE_TYPE_WIFI, uid)) {
5159 DBG("Not allow this user to connect this wifi service now!");
5160 return __connman_error_permission_denied(msg);
5163 if (uid != USER_ROOT && uid != service->user.favorite_user)
5164 service->request_passphrase_input = true;
5166 service->user.current_user = uid;
5168 if (!service->passphrase && uid == service->user.favorite_user) {
5169 DBG("Now load this favorite user's passphrase.");
5170 service_load_passphrase(service);
5174 #if !defined TIZEN_EXT
5175 index = __connman_service_get_index(service);
5177 for (list = service_list; list; list = list->next) {
5178 struct connman_service *temp = list->data;
5180 #if defined TIZEN_EXT
5181 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
5184 if (!is_connecting(temp) && !is_connected(temp))
5187 if (service == temp)
5190 if (service->type != temp->type)
5193 if (__connman_service_get_index(temp) == index &&
5194 __connman_service_disconnect(temp) == -EINPROGRESS)
5198 if (err == -EINPROGRESS)
5199 return __connman_error_operation_timeout(msg);
5202 service->ignore = false;
5204 service->pending = dbus_message_ref(msg);
5206 err = __connman_service_connect(service,
5207 CONNMAN_SERVICE_CONNECT_REASON_USER);
5209 if (err == -EINPROGRESS)
5212 if (service->pending) {
5213 dbus_message_unref(service->pending);
5214 service->pending = NULL;
5218 return __connman_error_failed(msg, -err);
5220 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5223 static DBusMessage *disconnect_service(DBusConnection *conn,
5224 DBusMessage *msg, void *user_data)
5226 struct connman_service *service = user_data;
5229 DBG("service %p", service);
5231 #if defined TIZEN_EXT
5233 * Description: TIZEN implements system global connection management.
5235 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
5236 if (connman_service_user_pdn_connection_unref_and_test(service) != TRUE)
5237 return __connman_error_failed(msg, EISCONN);
5239 if (is_connected(service) == TRUE &&
5240 service == connman_service_get_default_connection())
5241 return __connman_error_failed(msg, EISCONN);
5245 if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
5247 if (connman_dbus_get_connection_unix_user_sync(conn,
5248 dbus_message_get_sender(msg),
5250 DBG("Can not get unix user id!");
5251 return __connman_error_permission_denied(msg);
5254 if (!connman_service_is_user_allowed(service, uid)) {
5255 DBG("Not allow this user to disconnect this wifi service now!");
5256 return __connman_error_permission_denied(msg);
5260 service->ignore = true;
5262 err = __connman_service_disconnect(service);
5263 if (err < 0 && err != -EINPROGRESS)
5264 return __connman_error_failed(msg, -err);
5266 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5269 #if defined TIZEN_EXT
5270 static void __connman_service_cleanup_network_8021x(struct connman_service *service)
5272 if (service == NULL)
5275 DBG("service %p ", service);
5277 connman_network_set_string(service->network, "WiFi.EAP", NULL);
5278 connman_network_set_string(service->network, "WiFi.Identity", NULL);
5279 connman_network_set_string(service->network, "WiFi.CACertFile", NULL);
5280 connman_network_set_string(service->network, "WiFi.ClientCertFile", NULL);
5281 connman_network_set_string(service->network, "WiFi.PrivateKeyFile", NULL);
5282 connman_network_set_string(service->network, "WiFi.PrivateKeyPassphrase", NULL);
5283 connman_network_set_string(service->network, "WiFi.Phase2", NULL);
5287 bool __connman_service_remove(struct connman_service *service)
5289 if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET ||
5290 service->type == CONNMAN_SERVICE_TYPE_GADGET)
5293 if (service->immutable || service->hidden ||
5294 __connman_provider_is_immutable(service->provider))
5297 #if !defined TIZEN_EXT
5298 if (!service->favorite && service->state !=
5299 CONNMAN_SERVICE_STATE_FAILURE)
5303 __connman_service_disconnect(service);
5305 g_free(service->passphrase);
5306 service->passphrase = NULL;
5308 g_free(service->identity);
5309 service->identity = NULL;
5311 g_free(service->agent_identity);
5312 service->agent_identity = NULL;
5314 g_free(service->eap);
5315 service->eap = NULL;
5317 #if defined TIZEN_EXT
5318 g_free(service->ca_cert_file);
5319 service->ca_cert_file = NULL;
5321 g_free(service->client_cert_file);
5322 service->client_cert_file = NULL;
5324 g_free(service->private_key_file);
5325 service->private_key_file = NULL;
5327 g_free(service->private_key_passphrase);
5328 service->private_key_passphrase = NULL;
5330 g_free(service->phase2);
5331 service->phase2 = NULL;
5333 __connman_service_cleanup_network_8021x(service);
5335 __connman_ipconfig_set_method(service->ipconfig_ipv4, CONNMAN_IPCONFIG_METHOD_DHCP);
5336 __connman_ipconfig_set_method(service->ipconfig_ipv6, CONNMAN_IPCONFIG_METHOD_AUTO);
5337 connman_service_set_proxy(service, NULL, false);
5339 __connman_service_nameserver_clear(service);
5341 g_strfreev(service->nameservers_config);
5342 service->nameservers_config = NULL;
5346 #if defined TIZEN_EXT
5347 if (service->security != CONNMAN_SERVICE_SECURITY_8021X)
5351 service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
5353 service->user.favorite_user = USER_NONE;
5355 __connman_service_set_favorite(service, false);
5357 __connman_ipconfig_ipv6_reset_privacy(service->ipconfig_ipv6);
5359 #if defined TIZEN_EXT
5360 /* Reset IP Method and DNS Method to DHCP */
5361 __connman_ipconfig_set_method(service->ipconfig_ipv4,
5362 CONNMAN_IPCONFIG_METHOD_DHCP);
5363 service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
5364 g_strfreev(service->nameservers_config);
5365 service->nameservers_config = NULL;
5368 #if defined TIZEN_EXT
5369 __connman_storage_remove_service(service->identifier);
5371 service_save(service);
5377 static DBusMessage *remove_service(DBusConnection *conn,
5378 DBusMessage *msg, void *user_data)
5380 struct connman_service *service = user_data;
5382 DBG("service %p", service);
5384 if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
5386 if (connman_dbus_get_connection_unix_user_sync(conn,
5387 dbus_message_get_sender(msg),
5389 DBG("Can not get unix user id!");
5390 return __connman_error_permission_denied(msg);
5393 #if !defined TIZEN_EXT
5394 if (!connman_service_is_user_allowed(service, uid)) {
5395 DBG("Not allow this user to remove this wifi service now!");
5396 return __connman_error_permission_denied(msg);
5401 if (!__connman_service_remove(service))
5402 return __connman_error_not_supported(msg);
5404 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5407 static bool check_suitable_state(enum connman_service_state a,
5408 enum connman_service_state b)
5411 * Special check so that "ready" service can be moved before
5414 if ((a == CONNMAN_SERVICE_STATE_ONLINE &&
5415 b == CONNMAN_SERVICE_STATE_READY) ||
5416 (b == CONNMAN_SERVICE_STATE_ONLINE &&
5417 a == CONNMAN_SERVICE_STATE_READY))
5423 static void downgrade_state(struct connman_service *service)
5428 DBG("service %p state4 %d state6 %d", service, service->state_ipv4,
5429 service->state_ipv6);
5431 if (service->state_ipv4 == CONNMAN_SERVICE_STATE_ONLINE)
5432 __connman_service_ipconfig_indicate_state(service,
5433 CONNMAN_SERVICE_STATE_READY,
5434 CONNMAN_IPCONFIG_TYPE_IPV4);
5436 if (service->state_ipv6 == CONNMAN_SERVICE_STATE_ONLINE)
5437 __connman_service_ipconfig_indicate_state(service,
5438 CONNMAN_SERVICE_STATE_READY,
5439 CONNMAN_IPCONFIG_TYPE_IPV6);
5442 static void apply_relevant_default_downgrade(struct connman_service *service)
5444 struct connman_service *def_service;
5446 def_service = __connman_service_get_default();
5450 if (def_service == service &&
5451 def_service->state == CONNMAN_SERVICE_STATE_ONLINE) {
5452 def_service->state = CONNMAN_SERVICE_STATE_READY;
5453 __connman_notifier_leave_online(def_service->type);
5454 state_changed(def_service);
5458 static void switch_default_service(struct connman_service *default_service,
5459 struct connman_service *downgrade_service)
5461 struct connman_service *service;
5464 apply_relevant_default_downgrade(default_service);
5465 src = g_list_find(service_list, downgrade_service);
5466 dst = g_list_find(service_list, default_service);
5469 if (src == dst || src->next == dst)
5472 service = src->data;
5473 service_list = g_list_delete_link(service_list, src);
5474 service_list = g_list_insert_before(service_list, dst, service);
5476 downgrade_state(downgrade_service);
5479 static DBusMessage *move_service(DBusConnection *conn,
5480 DBusMessage *msg, void *user_data,
5483 struct connman_service *service = user_data;
5484 struct connman_service *target;
5486 enum connman_ipconfig_method target4, target6;
5487 enum connman_ipconfig_method service4, service6;
5489 DBG("service %p", service);
5491 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
5494 if (!service->favorite)
5495 return __connman_error_not_supported(msg);
5497 target = find_service(path);
5498 if (!target || !target->favorite || target == service)
5499 return __connman_error_invalid_service(msg);
5501 if (target->type == CONNMAN_SERVICE_TYPE_VPN) {
5503 * We only allow VPN route splitting if there are
5504 * routes defined for a given VPN.
5506 if (!__connman_provider_check_routes(target->provider)) {
5507 connman_info("Cannot move service. "
5508 "No routes defined for provider %s",
5509 __connman_provider_get_ident(target->provider));
5510 return __connman_error_invalid_service(msg);
5513 target->do_split_routing = true;
5515 target->do_split_routing = false;
5517 service->do_split_routing = false;
5519 target4 = __connman_ipconfig_get_method(target->ipconfig_ipv4);
5520 target6 = __connman_ipconfig_get_method(target->ipconfig_ipv6);
5521 service4 = __connman_ipconfig_get_method(service->ipconfig_ipv4);
5522 service6 = __connman_ipconfig_get_method(service->ipconfig_ipv6);
5524 DBG("target %s method %d/%d state %d/%d split %d", target->identifier,
5525 target4, target6, target->state_ipv4, target->state_ipv6,
5526 target->do_split_routing);
5528 DBG("service %s method %d/%d state %d/%d", service->identifier,
5530 service->state_ipv4, service->state_ipv6);
5533 * If method is OFF, then we do not need to check the corresponding
5536 if (target4 == CONNMAN_IPCONFIG_METHOD_OFF) {
5537 if (service6 != CONNMAN_IPCONFIG_METHOD_OFF) {
5538 if (!check_suitable_state(target->state_ipv6,
5539 service->state_ipv6))
5540 return __connman_error_invalid_service(msg);
5544 if (target6 == CONNMAN_IPCONFIG_METHOD_OFF) {
5545 if (service4 != CONNMAN_IPCONFIG_METHOD_OFF) {
5546 if (!check_suitable_state(target->state_ipv4,
5547 service->state_ipv4))
5548 return __connman_error_invalid_service(msg);
5552 if (service4 == CONNMAN_IPCONFIG_METHOD_OFF) {
5553 if (target6 != CONNMAN_IPCONFIG_METHOD_OFF) {
5554 if (!check_suitable_state(target->state_ipv6,
5555 service->state_ipv6))
5556 return __connman_error_invalid_service(msg);
5560 if (service6 == CONNMAN_IPCONFIG_METHOD_OFF) {
5561 if (target4 != CONNMAN_IPCONFIG_METHOD_OFF) {
5562 if (!check_suitable_state(target->state_ipv4,
5563 service->state_ipv4))
5564 return __connman_error_invalid_service(msg);
5568 g_get_current_time(&service->modified);
5569 service_save(service);
5570 service_save(target);
5573 * If the service which goes down is the default service and is
5574 * online, we downgrade directly its state to ready so:
5575 * the service which goes up, needs to recompute its state which
5576 * is triggered via downgrading it - if relevant - to state ready.
5579 switch_default_service(target, service);
5581 switch_default_service(service, target);
5583 __connman_connection_update_gateway();
5585 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5588 static DBusMessage *move_before(DBusConnection *conn,
5589 DBusMessage *msg, void *user_data)
5591 return move_service(conn, msg, user_data, true);
5594 static DBusMessage *move_after(DBusConnection *conn,
5595 DBusMessage *msg, void *user_data)
5597 return move_service(conn, msg, user_data, false);
5600 static DBusMessage *reset_counters(DBusConnection *conn,
5601 DBusMessage *msg, void *user_data)
5603 struct connman_service *service = user_data;
5605 reset_stats(service);
5607 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5610 static DBusMessage *get_user_favorite(DBusConnection *conn,
5611 DBusMessage *msg, void *user_data)
5614 uid_t uid = USER_NONE;
5615 dbus_bool_t user_favorite = false;
5616 struct connman_service *service = user_data;
5618 connman_dbus_get_connection_unix_user_sync(conn,
5619 dbus_message_get_sender(msg),
5621 if (uid == USER_ROOT)
5622 user_favorite = service->favorite;
5623 else if (uid != USER_NONE && uid == service->user.favorite_user) {
5624 DBG("The service is favorite to this user!");
5625 user_favorite = true;
5628 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5629 dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN,
5630 &user_favorite, DBUS_TYPE_INVALID);
5634 static struct _services_notify {
5640 static void service_append_added_foreach(gpointer data, gpointer user_data)
5642 struct connman_service *service = data;
5643 DBusMessageIter *iter = user_data;
5645 if (!service || !service->path) {
5646 #if !defined TIZEN_EXT
5647 DBG("service %p or path is NULL", service);
5652 if (g_hash_table_lookup(services_notify->add, service->path)) {
5653 #if !defined TIZEN_EXT
5654 DBG("new %s", service->path);
5657 append_struct(service, iter);
5658 g_hash_table_remove(services_notify->add, service->path);
5660 #if !defined TIZEN_EXT
5661 DBG("changed %s", service->path);
5664 append_struct_service(iter, NULL, service);
5668 static void service_append_ordered(DBusMessageIter *iter, void *user_data)
5670 g_list_foreach(service_list, service_append_added_foreach, iter);
5673 static void append_removed(gpointer key, gpointer value, gpointer user_data)
5675 char *objpath = key;
5676 DBusMessageIter *iter = user_data;
5678 DBG("removed %s", objpath);
5679 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &objpath);
5682 static void service_append_removed(DBusMessageIter *iter, void *user_data)
5684 g_hash_table_foreach(services_notify->remove, append_removed, iter);
5687 static gboolean service_send_changed(gpointer data)
5689 DBusMessage *signal;
5693 services_notify->id = 0;
5695 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
5696 CONNMAN_MANAGER_INTERFACE, "ServicesChanged");
5700 __connman_dbus_append_objpath_dict_array(signal,
5701 service_append_ordered, NULL);
5702 __connman_dbus_append_objpath_array(signal,
5703 service_append_removed, NULL);
5705 dbus_connection_send(connection, signal, NULL);
5706 dbus_message_unref(signal);
5708 g_hash_table_remove_all(services_notify->remove);
5709 g_hash_table_remove_all(services_notify->add);
5714 static void service_schedule_changed(void)
5716 if (services_notify->id != 0)
5719 services_notify->id = g_timeout_add(100, service_send_changed, NULL);
5722 static void service_schedule_added(struct connman_service *service)
5724 DBG("service %p", service);
5726 g_hash_table_remove(services_notify->remove, service->path);
5727 g_hash_table_replace(services_notify->add, service->path, service);
5729 service_schedule_changed();
5732 static void service_schedule_removed(struct connman_service *service)
5734 if (!service || !service->path) {
5735 DBG("service %p or path is NULL", service);
5739 DBG("service %p %s", service, service->path);
5741 g_hash_table_remove(services_notify->add, service->path);
5742 g_hash_table_replace(services_notify->remove, g_strdup(service->path),
5745 service_schedule_changed();
5748 static bool allow_property_changed(struct connman_service *service)
5750 #if defined TIZEN_EXT
5751 if (service->path == NULL)
5754 if (g_hash_table_lookup_extended(services_notify->add, service->path,
5756 DBG("no property updates for service %p", service);
5763 static const GDBusMethodTable service_methods[] = {
5764 { GDBUS_DEPRECATED_METHOD("GetProperties",
5765 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
5767 { GDBUS_METHOD("SetProperty",
5768 GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
5769 NULL, set_property) },
5770 { GDBUS_METHOD("ClearProperty",
5771 GDBUS_ARGS({ "name", "s" }), NULL,
5773 { GDBUS_ASYNC_METHOD("Connect", NULL, NULL,
5775 { GDBUS_METHOD("Disconnect", NULL, NULL,
5776 disconnect_service) },
5777 { GDBUS_METHOD("Remove", NULL, NULL, remove_service) },
5778 { GDBUS_METHOD("MoveBefore",
5779 GDBUS_ARGS({ "service", "o" }), NULL,
5781 { GDBUS_METHOD("MoveAfter",
5782 GDBUS_ARGS({ "service", "o" }), NULL,
5784 { GDBUS_METHOD("ResetCounters", NULL, NULL, reset_counters) },
5785 { GDBUS_METHOD("GetUserFavorite",
5786 NULL, GDBUS_ARGS({ "value", "v" }),
5787 get_user_favorite) },
5791 static const GDBusSignalTable service_signals[] = {
5792 { GDBUS_SIGNAL("PropertyChanged",
5793 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
5797 static void service_free(gpointer user_data)
5799 struct connman_service *service = user_data;
5800 char *path = service->path;
5802 DBG("service %p", service);
5804 reply_pending(service, ENOENT);
5806 __connman_notifier_service_remove(service);
5807 service_schedule_removed(service);
5809 __connman_wispr_stop(service);
5810 stats_stop(service);
5812 service->path = NULL;
5815 __connman_connection_update_gateway();
5817 g_dbus_unregister_interface(connection, path,
5818 CONNMAN_SERVICE_INTERFACE);
5822 g_hash_table_destroy(service->counter_table);
5824 if (service->network) {
5825 __connman_network_disconnect(service->network);
5826 connman_network_unref(service->network);
5827 service->network = NULL;
5830 if (service->provider)
5831 connman_provider_unref(service->provider);
5833 if (service->ipconfig_ipv4) {
5834 __connman_ipconfig_set_ops(service->ipconfig_ipv4, NULL);
5835 __connman_ipconfig_set_data(service->ipconfig_ipv4, NULL);
5836 __connman_ipconfig_unref(service->ipconfig_ipv4);
5837 service->ipconfig_ipv4 = NULL;
5840 if (service->ipconfig_ipv6) {
5841 __connman_ipconfig_set_ops(service->ipconfig_ipv6, NULL);
5842 __connman_ipconfig_set_data(service->ipconfig_ipv6, NULL);
5843 __connman_ipconfig_unref(service->ipconfig_ipv6);
5844 service->ipconfig_ipv6 = NULL;
5847 g_strfreev(service->timeservers);
5848 g_strfreev(service->timeservers_config);
5849 g_strfreev(service->nameservers);
5850 g_strfreev(service->nameservers_config);
5851 g_strfreev(service->nameservers_auto);
5852 g_strfreev(service->domains);
5853 g_strfreev(service->proxies);
5854 g_strfreev(service->excludes);
5856 g_free(service->hostname);
5857 g_free(service->domainname);
5858 g_free(service->pac);
5859 g_free(service->name);
5860 g_free(service->passphrase);
5861 g_free(service->identifier);
5862 g_free(service->eap);
5863 g_free(service->identity);
5864 g_free(service->agent_identity);
5865 g_free(service->ca_cert_file);
5866 g_free(service->client_cert_file);
5867 g_free(service->private_key_file);
5868 g_free(service->private_key_passphrase);
5869 g_free(service->phase2);
5870 g_free(service->config_file);
5871 g_free(service->config_entry);
5873 if (service->stats.timer)
5874 g_timer_destroy(service->stats.timer);
5875 if (service->stats_roaming.timer)
5876 g_timer_destroy(service->stats_roaming.timer);
5878 if (current_default == service)
5879 current_default = NULL;
5884 static void stats_init(struct connman_service *service)
5887 service->stats.valid = false;
5888 service->stats.enabled = false;
5889 service->stats.timer = g_timer_new();
5892 service->stats_roaming.valid = false;
5893 service->stats_roaming.enabled = false;
5894 service->stats_roaming.timer = g_timer_new();
5897 static void service_initialize(struct connman_service *service)
5899 DBG("service %p", service);
5901 service->refcount = 1;
5903 service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
5905 service->type = CONNMAN_SERVICE_TYPE_UNKNOWN;
5906 service->security = CONNMAN_SERVICE_SECURITY_UNKNOWN;
5908 service->state = CONNMAN_SERVICE_STATE_UNKNOWN;
5909 service->state_ipv4 = CONNMAN_SERVICE_STATE_UNKNOWN;
5910 service->state_ipv6 = CONNMAN_SERVICE_STATE_UNKNOWN;
5912 service->favorite = false;
5913 service->immutable = false;
5914 service->hidden = false;
5916 service->ignore = false;
5918 service->user.favorite_user = USER_NONE;
5919 service->user.current_user = USER_NONE;
5921 service->request_passphrase_input = false;
5923 service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
5927 stats_init(service);
5929 service->provider = NULL;
5931 service->wps = false;
5932 #if defined TIZEN_EXT
5933 service->storage_reload = false;
5935 * Description: TIZEN implements system global connection management.
5937 service->user_pdn_connection_refcount = 0;
5938 __sync_synchronize();
5943 * connman_service_create:
5945 * Allocate a new service.
5947 * Returns: a newly-allocated #connman_service structure
5949 struct connman_service *connman_service_create(void)
5952 struct connman_stats_counter *counters;
5953 const char *counter;
5955 struct connman_service *service;
5957 service = g_try_new0(struct connman_service, 1);
5961 DBG("service %p", service);
5963 service->counter_table = g_hash_table_new_full(g_str_hash,
5964 g_str_equal, NULL, g_free);
5966 for (list = counter_list; list; list = list->next) {
5967 counter = list->data;
5969 counters = g_try_new0(struct connman_stats_counter, 1);
5971 g_hash_table_destroy(service->counter_table);
5976 counters->append_all = true;
5978 g_hash_table_replace(service->counter_table, (gpointer)counter,
5982 service_initialize(service);
5988 * connman_service_ref:
5989 * @service: service structure
5991 * Increase reference counter of service
5993 struct connman_service *
5994 connman_service_ref_debug(struct connman_service *service,
5995 const char *file, int line, const char *caller)
5997 DBG("%p ref %d by %s:%d:%s()", service, service->refcount + 1,
5998 file, line, caller);
6000 __sync_fetch_and_add(&service->refcount, 1);
6006 * connman_service_unref:
6007 * @service: service structure
6009 * Decrease reference counter of service and release service if no
6012 void connman_service_unref_debug(struct connman_service *service,
6013 const char *file, int line, const char *caller)
6015 DBG("%p ref %d by %s:%d:%s()", service, service->refcount - 1,
6016 file, line, caller);
6018 if (__sync_fetch_and_sub(&service->refcount, 1) != 1)
6021 service_list = g_list_remove(service_list, service);
6023 __connman_service_disconnect(service);
6025 g_hash_table_remove(service_hash, service->identifier);
6028 static gint service_compare(gconstpointer a, gconstpointer b)
6030 struct connman_service *service_a = (void *) a;
6031 struct connman_service *service_b = (void *) b;
6032 enum connman_service_state state_a, state_b;
6033 bool a_connected, b_connected;
6036 state_a = service_a->state;
6037 state_b = service_b->state;
6038 a_connected = is_connected(service_a);
6039 b_connected = is_connected(service_b);
6041 if (a_connected && b_connected) {
6042 if (service_a->order > service_b->order)
6045 if (service_a->order < service_b->order)
6049 if (state_a != state_b) {
6050 if (a_connected && b_connected) {
6051 /* We prefer online over ready state */
6052 if (state_a == CONNMAN_SERVICE_STATE_ONLINE)
6055 if (state_b == CONNMAN_SERVICE_STATE_ONLINE)
6064 if (is_connecting(service_a))
6066 if (is_connecting(service_b))
6070 if (service_a->favorite && !service_b->favorite)
6073 if (!service_a->favorite && service_b->favorite)
6076 if (service_a->type != service_b->type) {
6078 if (service_a->type == CONNMAN_SERVICE_TYPE_ETHERNET)
6080 if (service_b->type == CONNMAN_SERVICE_TYPE_ETHERNET)
6083 if (service_a->type == CONNMAN_SERVICE_TYPE_WIFI)
6085 if (service_b->type == CONNMAN_SERVICE_TYPE_WIFI)
6088 if (service_a->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6090 if (service_b->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6093 if (service_a->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
6095 if (service_b->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
6098 if (service_a->type == CONNMAN_SERVICE_TYPE_VPN)
6100 if (service_b->type == CONNMAN_SERVICE_TYPE_VPN)
6103 if (service_a->type == CONNMAN_SERVICE_TYPE_GADGET)
6105 if (service_b->type == CONNMAN_SERVICE_TYPE_GADGET)
6109 strength = (gint) service_b->strength - (gint) service_a->strength;
6113 return g_strcmp0(service_a->name, service_b->name);
6116 static void service_list_sort(void)
6118 if (service_list && service_list->next) {
6119 service_list = g_list_sort(service_list, service_compare);
6120 service_schedule_changed();
6125 * connman_service_get_type:
6126 * @service: service structure
6128 * Get the type of service
6130 enum connman_service_type connman_service_get_type(struct connman_service *service)
6133 return CONNMAN_SERVICE_TYPE_UNKNOWN;
6135 return service->type;
6139 * connman_service_get_interface:
6140 * @service: service structure
6142 * Get network interface of service
6144 char *connman_service_get_interface(struct connman_service *service)
6151 index = __connman_service_get_index(service);
6153 return connman_inet_ifname(index);
6157 * __connman_service_is_user_allowed:
6158 * @type: service type
6161 * Check a user is allowed to operate a type of service
6163 bool __connman_service_is_user_allowed(enum connman_service_type type,
6167 uid_t owner_user = USER_NONE;
6169 for (list = service_list; list; list = list->next) {
6170 struct connman_service *service = list->data;
6172 if (service->type != type)
6175 if (is_connected(service)) {
6176 owner_user = service->user.favorite_user;
6181 if (uid == USER_NONE ||
6182 (uid != USER_ROOT &&
6183 owner_user != USER_NONE &&
6191 * connman_service_get_network:
6192 * @service: service structure
6194 * Get the service network
6196 struct connman_network *
6197 __connman_service_get_network(struct connman_service *service)
6202 return service->network;
6205 struct connman_ipconfig *
6206 __connman_service_get_ip4config(struct connman_service *service)
6211 return service->ipconfig_ipv4;
6214 struct connman_ipconfig *
6215 __connman_service_get_ip6config(struct connman_service *service)
6220 return service->ipconfig_ipv6;
6223 struct connman_ipconfig *
6224 __connman_service_get_ipconfig(struct connman_service *service, int family)
6226 if (family == AF_INET)
6227 return __connman_service_get_ip4config(service);
6228 else if (family == AF_INET6)
6229 return __connman_service_get_ip6config(service);
6235 bool __connman_service_is_connected_state(struct connman_service *service,
6236 enum connman_ipconfig_type type)
6242 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
6244 case CONNMAN_IPCONFIG_TYPE_IPV4:
6245 return is_connected_state(service, service->state_ipv4);
6246 case CONNMAN_IPCONFIG_TYPE_IPV6:
6247 return is_connected_state(service, service->state_ipv6);
6248 case CONNMAN_IPCONFIG_TYPE_ALL:
6249 return is_connected_state(service,
6250 CONNMAN_IPCONFIG_TYPE_IPV4) &&
6251 is_connected_state(service,
6252 CONNMAN_IPCONFIG_TYPE_IPV6);
6257 enum connman_service_security __connman_service_get_security(
6258 struct connman_service *service)
6261 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
6263 return service->security;
6266 const char *__connman_service_get_phase2(struct connman_service *service)
6271 return service->phase2;
6274 bool __connman_service_wps_enabled(struct connman_service *service)
6279 return service->wps;
6282 void __connman_service_mark_dirty(void)
6284 services_dirty = true;
6287 #if defined TIZEN_EXT
6289 * Returns profile count if there is any connected profiles
6290 * that use same interface
6292 int __connman_service_get_connected_count_of_iface(
6293 struct connman_service *service)
6302 index1 = __connman_service_get_index(service);
6307 for (list = service_list; list; list = list->next) {
6308 struct connman_service *service2 = list->data;
6310 if (service == service2)
6313 index2 = __connman_service_get_index(service2);
6315 if (is_connected(service2) && index2 > 0 && index1 == index2)
6321 DBG("Interface index %d, count %d", index1, count);
6326 void __connman_service_set_storage_reload(struct connman_service *service,
6327 bool storage_reload)
6329 if (service != NULL)
6330 service->storage_reload = storage_reload;
6335 * __connman_service_set_favorite_delayed:
6336 * @service: service structure
6337 * @favorite: favorite value
6338 * @delay_ordering: do not order service sequence
6340 * Change the favorite setting of service
6342 int __connman_service_set_favorite_delayed(struct connman_service *service,
6344 bool delay_ordering)
6346 #if defined TIZEN_EXT
6347 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6350 if (service->hidden)
6353 if (service->favorite == favorite)
6356 service->favorite = favorite;
6358 if (!delay_ordering)
6359 __connman_service_get_order(service);
6361 favorite_changed(service);
6363 if (!delay_ordering) {
6365 service_list_sort();
6367 __connman_connection_update_gateway();
6374 * __connman_service_set_favorite:
6375 * @service: service structure
6376 * @favorite: favorite value
6378 * Change the favorite setting of service
6380 int __connman_service_set_favorite(struct connman_service *service,
6383 return __connman_service_set_favorite_delayed(service, favorite,
6387 bool connman_service_get_favorite(struct connman_service *service)
6389 return service->favorite;
6392 bool connman_service_get_autoconnect(struct connman_service *service)
6394 return service->autoconnect;
6397 int __connman_service_set_immutable(struct connman_service *service,
6400 if (service->hidden)
6403 if (service->immutable == immutable)
6406 service->immutable = immutable;
6408 immutable_changed(service);
6413 int __connman_service_set_ignore(struct connman_service *service,
6419 service->ignore = ignore;
6424 void __connman_service_set_string(struct connman_service *service,
6425 const char *key, const char *value)
6427 if (service->hidden)
6429 if (g_str_equal(key, "EAP")) {
6430 g_free(service->eap);
6431 service->eap = g_strdup(value);
6432 } else if (g_str_equal(key, "Identity")) {
6433 g_free(service->identity);
6434 service->identity = g_strdup(value);
6435 } else if (g_str_equal(key, "CACertFile")) {
6436 g_free(service->ca_cert_file);
6437 service->ca_cert_file = g_strdup(value);
6438 } else if (g_str_equal(key, "ClientCertFile")) {
6439 g_free(service->client_cert_file);
6440 service->client_cert_file = g_strdup(value);
6441 } else if (g_str_equal(key, "PrivateKeyFile")) {
6442 g_free(service->private_key_file);
6443 service->private_key_file = g_strdup(value);
6444 } else if (g_str_equal(key, "PrivateKeyPassphrase")) {
6445 g_free(service->private_key_passphrase);
6446 service->private_key_passphrase = g_strdup(value);
6447 } else if (g_str_equal(key, "Phase2")) {
6448 g_free(service->phase2);
6449 service->phase2 = g_strdup(value);
6450 } else if (g_str_equal(key, "Passphrase"))
6451 __connman_service_set_passphrase(service, value);
6454 void __connman_service_set_search_domains(struct connman_service *service,
6457 searchdomain_remove_all(service);
6459 if (service->domains)
6460 g_strfreev(service->domains);
6462 service->domains = g_strdupv(domains);
6464 searchdomain_add_all(service);
6467 static void service_complete(struct connman_service *service)
6469 reply_pending(service, EIO);
6471 if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
6472 __connman_service_auto_connect(service->connect_reason);
6474 g_get_current_time(&service->modified);
6475 service_save(service);
6478 static void report_error_cb(void *user_context, bool retry,
6481 struct connman_service *service = user_context;
6484 __connman_service_connect(service,
6485 CONNMAN_SERVICE_CONNECT_REASON_USER);
6487 /* It is not relevant to stay on Failure state
6488 * when failing is due to wrong user input */
6489 __connman_service_clear_error(service);
6490 #if defined TIZEN_EXT
6491 /* Reseting the state back in case of failure state */
6492 service->state_ipv4 = service->state_ipv6 =
6493 CONNMAN_SERVICE_STATE_IDLE;
6495 if (service->error != CONNMAN_SERVICE_ERROR_AUTH_FAILED)
6496 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
6498 service_complete(service);
6499 __connman_connection_update_gateway();
6503 static int check_wpspin(struct connman_service *service, const char *wpspin)
6511 length = strlen(wpspin);
6513 /* If 0, it will mean user wants to use PBC method */
6515 connman_network_set_string(service->network,
6516 "WiFi.PinWPS", NULL);
6520 /* A WPS PIN is always 8 chars length,
6521 * its content is in digit representation.
6526 for (i = 0; i < 8; i++)
6527 if (!isdigit((unsigned char) wpspin[i]))
6530 connman_network_set_string(service->network, "WiFi.PinWPS", wpspin);
6535 static void request_input_cb(struct connman_service *service,
6536 bool values_received,
6537 const char *name, int name_len,
6538 const char *identity, const char *passphrase,
6539 bool wps, const char *wpspin,
6540 const char *error, void *user_data)
6542 struct connman_device *device;
6543 const char *security;
6546 DBG("RequestInput return, %p", service);
6549 DBG("error: %s", error);
6551 if (g_strcmp0(error,
6552 "net.connman.Agent.Error.Canceled") == 0) {
6555 if (service->hidden)
6556 __connman_service_return_error(service,
6557 ECANCELED, user_data);
6560 if (service->hidden)
6561 __connman_service_return_error(service,
6562 ETIMEDOUT, user_data);
6566 if (service->hidden && name_len > 0 && name_len <= 32) {
6567 device = connman_network_get_device(service->network);
6568 security = connman_network_get_string(service->network,
6570 err = __connman_device_request_hidden_scan(device,
6572 identity, passphrase,
6573 security, user_data);
6575 __connman_service_return_error(service, -err,
6579 if (!values_received || service->hidden) {
6584 if (wps && service->network) {
6585 err = check_wpspin(service, wpspin);
6589 connman_network_set_bool(service->network, "WiFi.UseWPS", wps);
6593 __connman_service_set_agent_identity(service, identity);
6596 err = __connman_service_set_passphrase(service, passphrase);
6600 /* We forget any previous error. */
6601 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
6603 __connman_service_connect(service,
6604 CONNMAN_SERVICE_CONNECT_REASON_USER);
6606 } else if (err == -ENOKEY) {
6607 __connman_service_indicate_error(service,
6608 CONNMAN_SERVICE_ERROR_INVALID_KEY);
6610 /* It is not relevant to stay on Failure state
6611 * when failing is due to wrong user input */
6612 service->state = CONNMAN_SERVICE_STATE_IDLE;
6614 if (!service->hidden) {
6616 * If there was a real error when requesting
6617 * hidden scan, then that error is returned already
6618 * to the user somewhere above so do not try to
6621 __connman_service_return_error(service, -err,
6625 service_complete(service);
6626 __connman_connection_update_gateway();
6630 static void downgrade_connected_services(void)
6632 struct connman_service *up_service;
6635 for (list = service_list; list; list = list->next) {
6636 up_service = list->data;
6638 if (!is_connected(up_service))
6641 if (up_service->state == CONNMAN_SERVICE_STATE_ONLINE)
6644 downgrade_state(up_service);
6648 static int service_update_preferred_order(struct connman_service *default_service,
6649 struct connman_service *new_service,
6650 enum connman_service_state new_state)
6652 unsigned int *tech_array;
6655 if (!default_service || default_service == new_service ||
6656 default_service->state != new_state)
6659 tech_array = connman_setting_get_uint_list("PreferredTechnologies");
6662 for (i = 0; tech_array[i] != 0; i += 1) {
6663 if (default_service->type == tech_array[i])
6666 if (new_service->type == tech_array[i]) {
6667 switch_default_service(default_service,
6669 __connman_connection_update_gateway();
6678 #if defined TIZEN_EXT
6679 static gboolean __connman_service_can_drop(struct connman_service *service)
6681 if (is_connected(service) == TRUE || is_connecting(service) == TRUE) {
6682 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR)
6684 else if (connman_service_is_no_ref_user_pdn_connection(service) == TRUE)
6690 static struct connman_device *default_connecting_device = NULL;
6692 static void __connman_service_disconnect_default(struct connman_service *service)
6694 struct connman_device *default_device = NULL;
6696 if (default_connecting_device == NULL)
6699 default_device = connman_network_get_device(
6700 __connman_service_get_network(service));
6702 DBG("Disconnecting service %p %s", service, service->path);
6703 DBG("Disconnecting device %p %p %s",
6704 default_connecting_device,
6706 connman_device_get_string(default_device, "Name"));
6708 if (default_connecting_device == default_device)
6709 default_connecting_device = NULL;
6712 static void __connman_service_connect_default(struct connman_service *current)
6716 bool default_internet;
6717 struct connman_service *service;
6718 struct connman_service *default_service = NULL;
6719 struct connman_device *default_device = NULL;
6721 if (current->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
6722 switch (current->state) {
6723 case CONNMAN_SERVICE_STATE_UNKNOWN:
6724 case CONNMAN_SERVICE_STATE_ASSOCIATION:
6725 case CONNMAN_SERVICE_STATE_CONFIGURATION:
6731 if (default_connecting_device &&
6732 __connman_service_is_internet_profile(current) == TRUE) {
6733 if (current->network == NULL)
6736 default_device = connman_network_get_device(current->network);
6737 if (default_connecting_device == default_device) {
6738 DBG("Cellular service[%s] %p %s",
6739 state2string(current->state), current, current->path);
6740 DBG("Cellular device %p %p %s",
6741 default_connecting_device, default_device,
6742 connman_device_get_string(default_device, "Name"));
6744 default_connecting_device = NULL;
6749 } else if (is_connected(current) == TRUE || is_connecting(current) == TRUE)
6752 /* Always-on: keep default cellular connection as possible */
6753 for (list = service_list; list; list = list->next) {
6754 service = list->data;
6756 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
6757 __connman_service_is_internet_profile(service) != TRUE ||
6758 service->network == NULL) {
6763 connman_network_get_bool(service->network, "DefaultInternet");
6765 DBG("service: %p %s %s %s (default: %d)", service, service->name,
6766 __connman_service_type2string(service->type),
6767 state2string(service->state), default_internet);
6769 if (default_internet) {
6770 default_service = service;
6771 if (is_connected(default_service) == TRUE ||
6772 is_connecting(default_service) == TRUE)
6775 default_device = connman_network_get_device(default_service->network);
6776 if (default_connecting_device == default_device) {
6777 DBG("Device is connecting (%p)", default_connecting_device);
6781 default_connecting_device = default_device;
6782 default_service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_USER;
6784 err = __connman_network_connect(default_service->network);
6785 DBG("Connecting default service %p %s [%d]",
6786 default_service, default_service->path, err);
6787 DBG("Connecting device %p %s", default_connecting_device,
6788 connman_device_get_string(default_connecting_device, "Name"));
6789 if (err < 0 && err != -EINPROGRESS) {
6790 default_connecting_device = NULL;
6798 static void single_connected_tech(struct connman_service *allowed)
6800 struct connman_service *service;
6801 GSList *services = NULL, *list;
6804 DBG("keeping %p %s", allowed, allowed->path);
6806 #if defined TIZEN_EXT
6807 if (!allowed || allowed->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6811 for (iter = service_list; iter; iter = iter->next) {
6812 service = iter->data;
6814 #if defined TIZEN_EXT
6815 if (service != allowed && service->type != allowed->type &&
6816 __connman_service_can_drop(service) == TRUE)
6818 if (!is_connected(service))
6821 if (service == allowed)
6824 services = g_slist_prepend(services, service);
6827 for (list = services; list; list = list->next) {
6828 service = list->data;
6830 DBG("disconnecting %p %s", service, service->path);
6831 #if defined TIZEN_EXT
6832 __connman_service_disconnect_default(service);
6834 __connman_service_disconnect(service);
6837 g_slist_free(services);
6840 #if defined TIZEN_EXT
6841 static void set_priority_connected_service(void)
6843 struct connman_service *service;
6846 for (list = service_list; list; list = list->next) {
6847 service = list->data;
6849 if (is_connected(service) == FALSE)
6857 static const char *get_dbus_sender(struct connman_service *service)
6859 if (!service->pending)
6862 return dbus_message_get_sender(service->pending);
6865 static int service_indicate_state(struct connman_service *service)
6867 enum connman_service_state old_state, new_state;
6868 struct connman_service *def_service;
6869 enum connman_ipconfig_method method;
6875 old_state = service->state;
6876 new_state = combine_state(service->state_ipv4, service->state_ipv6);
6878 DBG("service %p old %s - new %s/%s => %s",
6880 state2string(old_state),
6881 state2string(service->state_ipv4),
6882 state2string(service->state_ipv6),
6883 state2string(new_state));
6885 if (old_state == new_state)
6888 def_service = __connman_service_get_default();
6890 if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
6891 result = service_update_preferred_order(def_service,
6892 service, new_state);
6893 if (result == -EALREADY)
6897 if (old_state == CONNMAN_SERVICE_STATE_ONLINE)
6898 __connman_notifier_leave_online(service->type);
6900 if (is_connected_state(service, old_state) &&
6901 !is_connected_state(service, new_state))
6902 searchdomain_remove_all(service);
6904 service->state = new_state;
6905 state_changed(service);
6908 case CONNMAN_SERVICE_STATE_UNKNOWN:
6912 case CONNMAN_SERVICE_STATE_IDLE:
6913 if (old_state != CONNMAN_SERVICE_STATE_DISCONNECT)
6914 __connman_service_disconnect(service);
6918 case CONNMAN_SERVICE_STATE_ASSOCIATION:
6922 case CONNMAN_SERVICE_STATE_CONFIGURATION:
6923 if (!service->new_service &&
6924 __connman_stats_service_register(service) == 0) {
6926 * For new services the statistics are updated after
6927 * we have successfully connected.
6929 __connman_stats_get(service, false,
6930 &service->stats.data);
6931 __connman_stats_get(service, true,
6932 &service->stats_roaming.data);
6937 case CONNMAN_SERVICE_STATE_READY:
6938 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
6940 if (service->new_service &&
6941 __connman_stats_service_register(service) == 0) {
6943 * This is normally done after configuring state
6944 * but for new service do this after we have connected
6947 __connman_stats_get(service, false,
6948 &service->stats.data);
6949 __connman_stats_get(service, true,
6950 &service->stats_roaming.data);
6953 service->new_service = false;
6957 def_service = __connman_service_get_default();
6959 service_update_preferred_order(def_service, service, new_state);
6961 __connman_service_set_favorite(service, true);
6963 reply_pending(service, 0);
6965 g_get_current_time(&service->modified);
6966 service_save(service);
6968 searchdomain_add_all(service);
6969 dns_changed(service);
6970 domain_changed(service);
6971 proxy_changed(service);
6973 if (old_state != CONNMAN_SERVICE_STATE_ONLINE)
6974 __connman_notifier_connect(service->type);
6976 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
6977 connman_network_get_bool(service->network,
6981 pass = connman_network_get_string(service->network,
6984 __connman_service_set_passphrase(service, pass);
6986 connman_network_set_bool(service->network,
6987 "WiFi.UseWPS", false);
6990 method = __connman_ipconfig_get_method(service->ipconfig_ipv6);
6991 if (method == CONNMAN_IPCONFIG_METHOD_OFF)
6992 __connman_ipconfig_disable_ipv6(
6993 service->ipconfig_ipv6);
6995 if (connman_setting_get_bool("SingleConnectedTechnology"))
6996 single_connected_tech(service);
6997 else if (service->type != CONNMAN_SERVICE_TYPE_VPN)
7000 #if defined TIZEN_EXT
7001 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
7002 set_priority_connected_service();
7007 case CONNMAN_SERVICE_STATE_ONLINE:
7011 case CONNMAN_SERVICE_STATE_DISCONNECT:
7012 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
7014 reply_pending(service, ECONNABORTED);
7016 def_service = __connman_service_get_default();
7017 service->disconnect_reason = connman_network_get_disconnect_reason(service->network);
7019 if (!__connman_notifier_is_connected() &&
7021 def_service->provider)
7022 connman_provider_disconnect(def_service->provider);
7026 __connman_wispr_stop(service);
7028 __connman_wpad_stop(service);
7030 #if defined TIZEN_EXT
7032 * Skip the functions if there is any connected profiles
7033 * that use same interface
7035 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
7036 __connman_service_get_connected_count_of_iface(
7039 dns_changed(service);
7040 domain_changed(service);
7041 proxy_changed(service);
7042 #if defined TIZEN_EXT
7047 * Previous services which are connected and which states
7048 * are set to online should reset relevantly ipconfig_state
7049 * to ready so wispr/portal will be rerun on those
7051 downgrade_connected_services();
7053 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
7056 case CONNMAN_SERVICE_STATE_FAILURE:
7057 #if defined TIZEN_EXT
7058 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
7060 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
7062 if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER &&
7063 connman_agent_report_error(service, service->path,
7064 error2string(service->error),
7066 get_dbus_sender(service),
7067 NULL) == -EINPROGRESS)
7069 service_complete(service);
7074 service_list_sort();
7076 #if defined TIZEN_EXT
7077 __connman_service_connect_default(service);
7080 __connman_connection_update_gateway();
7082 if ((old_state == CONNMAN_SERVICE_STATE_ONLINE &&
7083 new_state != CONNMAN_SERVICE_STATE_READY) ||
7084 (old_state == CONNMAN_SERVICE_STATE_READY &&
7085 new_state != CONNMAN_SERVICE_STATE_ONLINE)) {
7086 __connman_notifier_disconnect(service->type);
7089 if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
7090 __connman_notifier_enter_online(service->type);
7094 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
7095 service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER &&
7096 (new_state == CONNMAN_SERVICE_STATE_READY ||
7097 new_state == CONNMAN_SERVICE_STATE_ONLINE)) {
7098 if (service->user.favorite_user != service->user.current_user) {
7099 DBG("Now set service favorite user id from %d to %d",
7100 service->user.favorite_user, service->user.current_user);
7102 service->user.favorite_user = service->user.current_user;
7104 service_save(service);
7111 int __connman_service_indicate_error(struct connman_service *service,
7112 enum connman_service_error error)
7114 DBG("service %p error %d", service, error);
7119 if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
7122 set_error(service, error);
7124 /* default internet service: fix not cleared if pdp activation*/
7125 #if defined TIZEN_EXT
7127 * If connection failed for default service(DefaultInternet),
7128 * default_connecting_device should be cleared.
7130 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
7131 service->error == CONNMAN_SERVICE_ERROR_CONNECT_FAILED)
7132 __connman_service_disconnect_default(service);
7134 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
7135 service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) {
7136 g_free(service->passphrase);
7137 service->passphrase = NULL;
7141 __connman_service_ipconfig_indicate_state(service,
7142 CONNMAN_SERVICE_STATE_FAILURE,
7143 CONNMAN_IPCONFIG_TYPE_IPV4);
7144 __connman_service_ipconfig_indicate_state(service,
7145 CONNMAN_SERVICE_STATE_FAILURE,
7146 CONNMAN_IPCONFIG_TYPE_IPV6);
7150 int __connman_service_clear_error(struct connman_service *service)
7152 DBusMessage *pending, *provider_pending;
7154 DBG("service %p", service);
7159 if (service->state != CONNMAN_SERVICE_STATE_FAILURE)
7162 pending = service->pending;
7163 service->pending = NULL;
7164 provider_pending = service->provider_pending;
7165 service->provider_pending = NULL;
7167 __connman_service_ipconfig_indicate_state(service,
7168 CONNMAN_SERVICE_STATE_IDLE,
7169 CONNMAN_IPCONFIG_TYPE_IPV6);
7171 __connman_service_ipconfig_indicate_state(service,
7172 CONNMAN_SERVICE_STATE_IDLE,
7173 CONNMAN_IPCONFIG_TYPE_IPV4);
7175 service->pending = pending;
7176 service->provider_pending = provider_pending;
7181 int __connman_service_indicate_default(struct connman_service *service)
7183 DBG("service %p state %s", service, state2string(service->state));
7185 if (!is_connected(service)) {
7187 * If service is not yet fully connected, then we must not
7188 * change the default yet. The default gw will be changed
7189 * after the service state is in ready.
7191 return -EINPROGRESS;
7199 enum connman_service_state __connman_service_ipconfig_get_state(
7200 struct connman_service *service,
7201 enum connman_ipconfig_type type)
7204 return CONNMAN_SERVICE_STATE_UNKNOWN;
7206 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
7207 return service->state_ipv4;
7209 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
7210 return service->state_ipv6;
7212 return CONNMAN_SERVICE_STATE_UNKNOWN;
7215 static void check_proxy_setup(struct connman_service *service)
7218 * We start WPAD if we haven't got a PAC URL from DHCP and
7219 * if our proxy manual configuration is either empty or set
7220 * to AUTO with an empty URL.
7223 if (service->proxy != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN)
7226 if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN &&
7227 (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_AUTO ||
7231 if (__connman_wpad_start(service) < 0) {
7232 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
7233 __connman_notifier_proxy_changed(service);
7240 __connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
7243 #if defined TIZEN_EXT
7244 void connman_check_proxy_setup_and_wispr_start(struct connman_service *service){
7246 DBG("check the proxy and start wispr");
7247 check_proxy_setup(service);
7253 * How many networks are connected at the same time. If more than 1,
7254 * then set the rp_filter setting properly (loose mode routing) so that network
7255 * connectivity works ok. This is only done for IPv4 networks as IPv6
7256 * does not have rp_filter knob.
7258 static int connected_networks_count;
7259 static int original_rp_filter;
7261 static void service_rp_filter(struct connman_service *service,
7264 enum connman_ipconfig_method method;
7266 method = __connman_ipconfig_get_method(service->ipconfig_ipv4);
7269 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
7270 case CONNMAN_IPCONFIG_METHOD_OFF:
7271 case CONNMAN_IPCONFIG_METHOD_AUTO:
7273 case CONNMAN_IPCONFIG_METHOD_FIXED:
7274 case CONNMAN_IPCONFIG_METHOD_MANUAL:
7275 case CONNMAN_IPCONFIG_METHOD_DHCP:
7280 if (connected_networks_count == 1) {
7282 filter_value = __connman_ipconfig_set_rp_filter();
7283 if (filter_value < 0)
7286 original_rp_filter = filter_value;
7288 connected_networks_count++;
7291 if (connected_networks_count == 2)
7292 __connman_ipconfig_unset_rp_filter(original_rp_filter);
7294 connected_networks_count--;
7295 if (connected_networks_count < 0)
7296 connected_networks_count = 0;
7299 DBG("%s %s ipconfig %p method %d count %d filter %d",
7300 connected ? "connected" : "disconnected", service->identifier,
7301 service->ipconfig_ipv4, method,
7302 connected_networks_count, original_rp_filter);
7305 static gboolean redo_wispr(gpointer user_data)
7307 struct connman_service *service = user_data;
7308 int refcount = service->refcount - 1;
7310 connman_service_unref(service);
7311 if (refcount == 0) {
7312 DBG("Service %p already removed", service);
7316 __connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV6);
7321 int __connman_service_online_check_failed(struct connman_service *service,
7322 enum connman_ipconfig_type type)
7324 DBG("service %p type %d count %d", service, type,
7325 service->online_check_count);
7327 /* currently we only retry IPv6 stuff */
7328 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 ||
7329 service->online_check_count != 1) {
7330 connman_warn("Online check failed for %p %s", service,
7335 service->online_check_count = 0;
7338 * We set the timeout to 1 sec so that we have a chance to get
7339 * necessary IPv6 router advertisement messages that might have
7342 g_timeout_add_seconds(1, redo_wispr, connman_service_ref(service));
7347 int __connman_service_ipconfig_indicate_state(struct connman_service *service,
7348 enum connman_service_state new_state,
7349 enum connman_ipconfig_type type)
7351 struct connman_ipconfig *ipconfig = NULL;
7352 enum connman_service_state old_state;
7353 enum connman_ipconfig_method method;
7359 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
7360 case CONNMAN_IPCONFIG_TYPE_ALL:
7363 case CONNMAN_IPCONFIG_TYPE_IPV4:
7364 old_state = service->state_ipv4;
7365 ipconfig = service->ipconfig_ipv4;
7369 case CONNMAN_IPCONFIG_TYPE_IPV6:
7370 old_state = service->state_ipv6;
7371 ipconfig = service->ipconfig_ipv6;
7380 if (old_state == new_state)
7383 #if defined TIZEN_EXT
7384 __sync_synchronize();
7385 if (service->user_pdn_connection_refcount > 0 &&
7386 service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
7387 if (new_state == CONNMAN_SERVICE_STATE_FAILURE ||
7388 new_state == CONNMAN_SERVICE_STATE_DISCONNECT ||
7389 new_state == CONNMAN_SERVICE_STATE_IDLE) {
7390 service->user_pdn_connection_refcount = 0;
7391 __sync_synchronize();
7395 DBG("service %p (%s) old state %d (%s) new state %d (%s) type %d (%s)",
7396 service, service ? service->identifier : NULL,
7397 old_state, state2string(old_state),
7398 new_state, state2string(new_state),
7399 type, __connman_ipconfig_type2string(type));
7401 switch (new_state) {
7402 case CONNMAN_SERVICE_STATE_UNKNOWN:
7403 case CONNMAN_SERVICE_STATE_IDLE:
7404 case CONNMAN_SERVICE_STATE_ASSOCIATION:
7406 case CONNMAN_SERVICE_STATE_CONFIGURATION:
7407 __connman_ipconfig_enable(ipconfig);
7409 case CONNMAN_SERVICE_STATE_READY:
7410 #if defined TIZEN_EXT
7411 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
7412 __connman_service_is_internet_profile(service) != TRUE) {
7413 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
7414 service_rp_filter(service, TRUE);
7419 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
7420 #if !defined TIZEN_EXT
7421 check_proxy_setup(service);
7423 service_rp_filter(service, true);
7425 service->online_check_count = 1;
7426 __connman_wispr_start(service, type);
7429 case CONNMAN_SERVICE_STATE_ONLINE:
7431 case CONNMAN_SERVICE_STATE_DISCONNECT:
7432 if (service->state == CONNMAN_SERVICE_STATE_IDLE)
7435 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
7436 service_rp_filter(service, false);
7439 case CONNMAN_SERVICE_STATE_FAILURE:
7443 /* Keep that state, but if the ipconfig method is OFF, then we set
7444 the state to IDLE so that it will not affect the combined state
7447 method = __connman_ipconfig_get_method(ipconfig);
7449 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
7450 case CONNMAN_IPCONFIG_METHOD_OFF:
7451 new_state = CONNMAN_SERVICE_STATE_IDLE;
7454 case CONNMAN_IPCONFIG_METHOD_FIXED:
7455 case CONNMAN_IPCONFIG_METHOD_MANUAL:
7456 case CONNMAN_IPCONFIG_METHOD_DHCP:
7457 case CONNMAN_IPCONFIG_METHOD_AUTO:
7462 if (is_connected_state(service, old_state) &&
7463 !is_connected_state(service, new_state))
7464 #if defined TIZEN_EXT
7466 DBG("nameserver remove all, type: %d", type);
7467 nameserver_remove_all(service, type);
7469 nameserver_remove_all(service);
7471 #if defined TIZEN_EXT
7475 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
7476 service->state_ipv4 = new_state;
7478 service->state_ipv6 = new_state;
7480 if (!is_connected_state(service, old_state) &&
7481 is_connected_state(service, new_state))
7482 #if defined TIZEN_EXT
7484 DBG("nameserver add all, type: %d", type);
7485 nameserver_add_all(service, type);
7487 nameserver_add_all(service);
7489 #if defined TIZEN_EXT
7493 #if defined TIZEN_EXT
7494 int ret = service_indicate_state(service);
7495 /*Sent the Ready changed signal again in case IPv4 IP set
7498 if(ret == -EALREADY && type == CONNMAN_IPCONFIG_TYPE_IPV4
7499 && new_state == CONNMAN_SERVICE_STATE_READY) {
7500 DBG("Notify IPv4 state new/old %d/%d", new_state,old_state);
7501 state_changed(service);
7506 return service_indicate_state(service);
7509 static bool prepare_network(struct connman_service *service)
7511 enum connman_network_type type;
7512 unsigned int ssid_len;
7514 type = connman_network_get_type(service->network);
7517 case CONNMAN_NETWORK_TYPE_UNKNOWN:
7518 case CONNMAN_NETWORK_TYPE_VENDOR:
7520 case CONNMAN_NETWORK_TYPE_WIFI:
7521 if (!connman_network_get_blob(service->network, "WiFi.SSID",
7525 if (service->passphrase)
7526 connman_network_set_string(service->network,
7527 "WiFi.Passphrase", service->passphrase);
7529 case CONNMAN_NETWORK_TYPE_ETHERNET:
7530 case CONNMAN_NETWORK_TYPE_GADGET:
7531 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
7532 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
7533 case CONNMAN_NETWORK_TYPE_CELLULAR:
7540 static void prepare_8021x(struct connman_service *service)
7543 connman_network_set_string(service->network, "WiFi.EAP",
7546 if (service->identity)
7547 connman_network_set_string(service->network, "WiFi.Identity",
7550 if (service->ca_cert_file)
7551 connman_network_set_string(service->network, "WiFi.CACertFile",
7552 service->ca_cert_file);
7554 if (service->client_cert_file)
7555 connman_network_set_string(service->network,
7556 "WiFi.ClientCertFile",
7557 service->client_cert_file);
7559 if (service->private_key_file)
7560 connman_network_set_string(service->network,
7561 "WiFi.PrivateKeyFile",
7562 service->private_key_file);
7564 if (service->private_key_passphrase)
7565 connman_network_set_string(service->network,
7566 "WiFi.PrivateKeyPassphrase",
7567 service->private_key_passphrase);
7569 if (service->phase2)
7570 connman_network_set_string(service->network, "WiFi.Phase2",
7574 static int service_connect(struct connman_service *service)
7578 if (service->hidden)
7581 #if defined TIZEN_EXT
7585 index = __connman_service_get_index(service);
7587 for (list = service_list; list; list = list->next) {
7588 struct connman_service *temp = list->data;
7590 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
7593 if (!is_connecting(temp) && !is_connected(temp))
7596 if (service == temp)
7599 if (service->type != temp->type)
7602 if (__connman_service_get_index(temp) == index &&
7603 __connman_service_disconnect(temp) == -EINPROGRESS)
7604 return -EINPROGRESS;
7608 switch (service->type) {
7609 case CONNMAN_SERVICE_TYPE_UNKNOWN:
7610 case CONNMAN_SERVICE_TYPE_SYSTEM:
7611 case CONNMAN_SERVICE_TYPE_GPS:
7612 case CONNMAN_SERVICE_TYPE_P2P:
7614 case CONNMAN_SERVICE_TYPE_ETHERNET:
7615 case CONNMAN_SERVICE_TYPE_GADGET:
7616 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
7617 case CONNMAN_SERVICE_TYPE_CELLULAR:
7618 case CONNMAN_SERVICE_TYPE_VPN:
7620 case CONNMAN_SERVICE_TYPE_WIFI:
7621 switch (service->security) {
7622 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
7623 case CONNMAN_SERVICE_SECURITY_NONE:
7625 case CONNMAN_SERVICE_SECURITY_WEP:
7626 case CONNMAN_SERVICE_SECURITY_PSK:
7627 case CONNMAN_SERVICE_SECURITY_WPA:
7628 case CONNMAN_SERVICE_SECURITY_RSN:
7629 if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
7632 if (service->request_passphrase_input) {
7633 DBG("Now try to connect other user's favorite service");
7634 service->request_passphrase_input = false;
7636 } else if (!service->passphrase) {
7637 if (!service->network)
7640 if (!service->wps ||
7641 !connman_network_get_bool(service->network, "WiFi.UseWPS"))
7646 case CONNMAN_SERVICE_SECURITY_8021X:
7650 #if defined TIZEN_EXT
7652 * never request credentials if using EAP-TLS, EAP-SIM
7653 * or EAP-AKA (EAP-TLS, EAP-SIM and EAP-AKA networks
7654 * need to be fully provisioned)
7656 if (g_str_equal(service->eap, "tls") ||
7657 g_str_equal(service->eap, "sim") ||
7658 g_str_equal(service->eap, "aka"))
7662 * never request credentials if using EAP-TLS
7663 * (EAP-TLS networks need to be fully provisioned)
7665 if (g_str_equal(service->eap, "tls"))
7669 * Return -ENOKEY if either identity or passphrase is
7670 * missing. Agent provided credentials can be used as
7671 * fallback if needed.
7673 if (((!service->identity &&
7674 !service->agent_identity) ||
7675 !service->passphrase) ||
7676 service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
7684 if (service->network) {
7685 if (!prepare_network(service))
7688 switch (service->security) {
7689 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
7690 case CONNMAN_SERVICE_SECURITY_NONE:
7691 case CONNMAN_SERVICE_SECURITY_WEP:
7692 case CONNMAN_SERVICE_SECURITY_PSK:
7693 case CONNMAN_SERVICE_SECURITY_WPA:
7694 case CONNMAN_SERVICE_SECURITY_RSN:
7696 case CONNMAN_SERVICE_SECURITY_8021X:
7697 prepare_8021x(service);
7701 if (__connman_stats_service_register(service) == 0) {
7702 __connman_stats_get(service, false,
7703 &service->stats.data);
7704 __connman_stats_get(service, true,
7705 &service->stats_roaming.data);
7708 if (service->ipconfig_ipv4)
7709 __connman_ipconfig_enable(service->ipconfig_ipv4);
7710 if (service->ipconfig_ipv6)
7711 __connman_ipconfig_enable(service->ipconfig_ipv6);
7713 err = __connman_network_connect(service->network);
7714 } else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
7716 err = __connman_provider_connect(service->provider);
7721 if (err != -EINPROGRESS) {
7722 __connman_ipconfig_disable(service->ipconfig_ipv4);
7723 __connman_ipconfig_disable(service->ipconfig_ipv6);
7724 __connman_stats_service_unregister(service);
7731 int __connman_service_connect(struct connman_service *service,
7732 enum connman_service_connect_reason reason)
7736 DBG("service %p state %s connect reason %s -> %s",
7737 service, state2string(service->state),
7738 reason2string(service->connect_reason),
7739 reason2string(reason));
7741 if (is_connected(service))
7744 if (is_connecting(service))
7747 switch (service->type) {
7748 case CONNMAN_SERVICE_TYPE_UNKNOWN:
7749 case CONNMAN_SERVICE_TYPE_SYSTEM:
7750 case CONNMAN_SERVICE_TYPE_GPS:
7751 case CONNMAN_SERVICE_TYPE_P2P:
7754 case CONNMAN_SERVICE_TYPE_ETHERNET:
7755 case CONNMAN_SERVICE_TYPE_GADGET:
7756 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
7757 case CONNMAN_SERVICE_TYPE_CELLULAR:
7758 case CONNMAN_SERVICE_TYPE_VPN:
7759 case CONNMAN_SERVICE_TYPE_WIFI:
7763 if (!is_ipconfig_usable(service))
7766 __connman_service_clear_error(service);
7768 err = service_connect(service);
7770 service->connect_reason = reason;
7774 if (err == -EINPROGRESS) {
7775 if (service->timeout == 0)
7776 service->timeout = g_timeout_add_seconds(
7777 CONNECT_TIMEOUT, connect_timeout, service);
7779 return -EINPROGRESS;
7782 if (service->network)
7783 __connman_network_disconnect(service->network);
7784 else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
7786 connman_provider_disconnect(service->provider);
7788 if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
7789 if (err == -ENOKEY || err == -EPERM) {
7790 DBusMessage *pending = NULL;
7793 * We steal the reply here. The idea is that the
7794 * connecting client will see the connection status
7795 * after the real hidden network is connected or
7796 * connection failed.
7798 if (service->hidden) {
7799 pending = service->pending;
7800 service->pending = NULL;
7803 err = __connman_agent_request_passphrase_input(service,
7805 get_dbus_sender(service),
7807 if (service->hidden && err != -EINPROGRESS)
7808 service->pending = pending;
7812 reply_pending(service, -err);
7818 int __connman_service_disconnect(struct connman_service *service)
7822 DBG("service %p", service);
7824 service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
7825 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
7827 connman_agent_cancel(service);
7829 reply_pending(service, ECONNABORTED);
7831 if (service->network) {
7832 err = __connman_network_disconnect(service->network);
7833 } else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
7835 err = connman_provider_disconnect(service->provider);
7839 if (err < 0 && err != -EINPROGRESS)
7842 __connman_6to4_remove(service->ipconfig_ipv4);
7844 if (service->ipconfig_ipv4)
7845 __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv4,
7848 __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv6,
7851 #if defined TIZEN_EXT
7853 * Skip the functions If there is any connected profiles
7854 * that use same interface
7856 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
7857 __connman_service_get_connected_count_of_iface(service) <= 0) {
7859 __connman_ipconfig_address_remove(service->ipconfig_ipv4);
7860 settings_changed(service, service->ipconfig_ipv4);
7862 __connman_ipconfig_address_remove(service->ipconfig_ipv6);
7863 settings_changed(service, service->ipconfig_ipv6);
7865 __connman_ipconfig_disable(service->ipconfig_ipv4);
7866 __connman_ipconfig_disable(service->ipconfig_ipv6);
7867 #if defined TIZEN_EXT
7871 __connman_stats_service_unregister(service);
7876 int __connman_service_disconnect_all(void)
7878 struct connman_service *service;
7879 GSList *services = NULL, *list;
7884 for (iter = service_list; iter; iter = iter->next) {
7885 service = iter->data;
7887 if (!is_connected(service))
7890 services = g_slist_prepend(services, service);
7893 for (list = services; list; list = list->next) {
7894 struct connman_service *service = list->data;
7896 service->ignore = true;
7898 __connman_service_disconnect(service);
7901 g_slist_free(services);
7907 * lookup_by_identifier:
7908 * @identifier: service identifier
7910 * Look up a service by identifier (reference count will not be increased)
7912 static struct connman_service *lookup_by_identifier(const char *identifier)
7914 return g_hash_table_lookup(service_hash, identifier);
7917 struct provision_user_data {
7922 static void provision_changed(gpointer value, gpointer user_data)
7924 struct connman_service *service = value;
7925 struct provision_user_data *data = user_data;
7926 const char *path = data->ident;
7929 ret = __connman_config_provision_service_ident(service, path,
7930 service->config_file, service->config_entry);
7935 int __connman_service_provision_changed(const char *ident)
7937 struct provision_user_data data = {
7942 g_list_foreach(service_list, provision_changed, (void *)&data);
7945 * Because the provision_changed() might have set some services
7946 * as favorite, we must sort the sequence now.
7948 if (services_dirty) {
7949 services_dirty = false;
7951 service_list_sort();
7953 __connman_connection_update_gateway();
7959 void __connman_service_set_config(struct connman_service *service,
7960 const char *file_id, const char *entry)
7965 g_free(service->config_file);
7966 service->config_file = g_strdup(file_id);
7968 g_free(service->config_entry);
7969 service->config_entry = g_strdup(entry);
7973 * __connman_service_get:
7974 * @identifier: service identifier
7976 * Look up a service by identifier or create a new one if not found
7978 static struct connman_service *service_get(const char *identifier)
7980 struct connman_service *service;
7982 service = g_hash_table_lookup(service_hash, identifier);
7984 connman_service_ref(service);
7988 service = connman_service_create();
7992 DBG("service %p", service);
7994 service->identifier = g_strdup(identifier);
7996 service_list = g_list_insert_sorted(service_list, service,
7999 g_hash_table_insert(service_hash, service->identifier, service);
8004 static int service_register(struct connman_service *service)
8006 DBG("service %p", service);
8011 service->path = g_strdup_printf("%s/service/%s", CONNMAN_PATH,
8012 service->identifier);
8014 DBG("path %s", service->path);
8016 if (__connman_config_provision_service(service) < 0)
8017 service_load(service);
8019 g_dbus_register_interface(connection, service->path,
8020 CONNMAN_SERVICE_INTERFACE,
8021 service_methods, service_signals,
8022 NULL, service, NULL);
8024 service_list_sort();
8026 __connman_connection_update_gateway();
8031 static void service_up(struct connman_ipconfig *ipconfig,
8034 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8036 DBG("%s up", ifname);
8038 link_changed(service);
8040 service->stats.valid = false;
8041 service->stats_roaming.valid = false;
8044 static void service_down(struct connman_ipconfig *ipconfig,
8047 DBG("%s down", ifname);
8050 static void service_lower_up(struct connman_ipconfig *ipconfig,
8053 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8055 DBG("%s lower up", ifname);
8057 stats_start(service);
8060 static void service_lower_down(struct connman_ipconfig *ipconfig,
8063 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8065 DBG("%s lower down", ifname);
8067 if (!is_idle_state(service, service->state_ipv4))
8068 __connman_ipconfig_disable(service->ipconfig_ipv4);
8070 if (!is_idle_state(service, service->state_ipv6))
8071 __connman_ipconfig_disable(service->ipconfig_ipv6);
8073 stats_stop(service);
8074 service_save(service);
8077 static void service_ip_bound(struct connman_ipconfig *ipconfig,
8080 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8081 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
8082 enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
8083 #if defined TIZEN_EXT
8087 DBG("%s ip bound", ifname);
8089 type = __connman_ipconfig_get_config_type(ipconfig);
8090 method = __connman_ipconfig_get_method(ipconfig);
8092 DBG("service %p ipconfig %p type %d method %d", service, ipconfig,
8095 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
8096 method == CONNMAN_IPCONFIG_METHOD_AUTO)
8097 #if defined TIZEN_EXT
8099 err = __connman_ipconfig_gateway_add(ipconfig, service);
8102 __connman_connection_gateway_activate(service,
8103 CONNMAN_IPCONFIG_TYPE_IPV6);
8106 __connman_service_ipconfig_indicate_state(service,
8107 CONNMAN_SERVICE_STATE_READY,
8108 CONNMAN_IPCONFIG_TYPE_IPV6);
8111 settings_changed(service, ipconfig);
8114 static void service_ip_release(struct connman_ipconfig *ipconfig,
8117 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8118 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
8119 enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
8121 DBG("%s ip release", ifname);
8123 type = __connman_ipconfig_get_config_type(ipconfig);
8124 method = __connman_ipconfig_get_method(ipconfig);
8126 DBG("service %p ipconfig %p type %d method %d", service, ipconfig,
8129 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
8130 method == CONNMAN_IPCONFIG_METHOD_OFF)
8131 __connman_service_ipconfig_indicate_state(service,
8132 CONNMAN_SERVICE_STATE_DISCONNECT,
8133 CONNMAN_IPCONFIG_TYPE_IPV6);
8135 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
8136 method == CONNMAN_IPCONFIG_METHOD_OFF)
8137 __connman_service_ipconfig_indicate_state(service,
8138 CONNMAN_SERVICE_STATE_DISCONNECT,
8139 CONNMAN_IPCONFIG_TYPE_IPV4);
8141 settings_changed(service, ipconfig);
8144 static void service_route_changed(struct connman_ipconfig *ipconfig,
8147 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8149 DBG("%s route changed", ifname);
8151 settings_changed(service, ipconfig);
8154 static const struct connman_ipconfig_ops service_ops = {
8156 .down = service_down,
8157 .lower_up = service_lower_up,
8158 .lower_down = service_lower_down,
8159 .ip_bound = service_ip_bound,
8160 .ip_release = service_ip_release,
8161 .route_set = service_route_changed,
8162 .route_unset = service_route_changed,
8165 static struct connman_ipconfig *create_ip4config(struct connman_service *service,
8166 int index, enum connman_ipconfig_method method)
8168 struct connman_ipconfig *ipconfig_ipv4;
8170 ipconfig_ipv4 = __connman_ipconfig_create(index,
8171 CONNMAN_IPCONFIG_TYPE_IPV4);
8175 __connman_ipconfig_set_method(ipconfig_ipv4, method);
8177 __connman_ipconfig_set_data(ipconfig_ipv4, service);
8179 __connman_ipconfig_set_ops(ipconfig_ipv4, &service_ops);
8181 return ipconfig_ipv4;
8184 static struct connman_ipconfig *create_ip6config(struct connman_service *service,
8187 struct connman_ipconfig *ipconfig_ipv6;
8189 ipconfig_ipv6 = __connman_ipconfig_create(index,
8190 CONNMAN_IPCONFIG_TYPE_IPV6);
8194 __connman_ipconfig_set_data(ipconfig_ipv6, service);
8196 __connman_ipconfig_set_ops(ipconfig_ipv6, &service_ops);
8198 return ipconfig_ipv6;
8201 void __connman_service_read_ip4config(struct connman_service *service)
8205 if (!service->ipconfig_ipv4)
8208 keyfile = connman_storage_load_service(service->identifier);
8212 __connman_ipconfig_load(service->ipconfig_ipv4, keyfile,
8213 service->identifier, "IPv4.");
8215 g_key_file_free(keyfile);
8218 void connman_service_create_ip4config(struct connman_service *service,
8221 DBG("ipv4 %p", service->ipconfig_ipv4);
8223 if (service->ipconfig_ipv4)
8226 service->ipconfig_ipv4 = create_ip4config(service, index,
8227 CONNMAN_IPCONFIG_METHOD_DHCP);
8228 __connman_service_read_ip4config(service);
8231 void __connman_service_read_ip6config(struct connman_service *service)
8235 if (!service->ipconfig_ipv6)
8238 keyfile = connman_storage_load_service(service->identifier);
8242 __connman_ipconfig_load(service->ipconfig_ipv6, keyfile,
8243 service->identifier, "IPv6.");
8245 g_key_file_free(keyfile);
8248 void connman_service_create_ip6config(struct connman_service *service,
8251 DBG("ipv6 %p", service->ipconfig_ipv6);
8253 if (service->ipconfig_ipv6)
8256 service->ipconfig_ipv6 = create_ip6config(service, index);
8258 __connman_service_read_ip6config(service);
8262 * connman_service_lookup_from_network:
8263 * @network: network structure
8265 * Look up a service by network (reference count will not be increased)
8267 struct connman_service *connman_service_lookup_from_network(struct connman_network *network)
8269 struct connman_service *service;
8270 const char *ident, *group;
8276 ident = __connman_network_get_ident(network);
8280 group = connman_network_get_group(network);
8284 name = g_strdup_printf("%s_%s_%s",
8285 __connman_network_get_type(network), ident, group);
8286 service = lookup_by_identifier(name);
8292 struct connman_service *__connman_service_lookup_from_index(int index)
8294 struct connman_service *service;
8297 for (list = service_list; list; list = list->next) {
8298 service = list->data;
8300 if (__connman_ipconfig_get_index(service->ipconfig_ipv4)
8304 if (__connman_ipconfig_get_index(service->ipconfig_ipv6)
8312 struct connman_service *__connman_service_lookup_from_ident(const char *identifier)
8314 return lookup_by_identifier(identifier);
8317 const char *__connman_service_get_ident(struct connman_service *service)
8319 return service->identifier;
8322 const char *__connman_service_get_path(struct connman_service *service)
8324 return service->path;
8327 const char *__connman_service_get_name(struct connman_service *service)
8329 return service->name;
8332 enum connman_service_state __connman_service_get_state(struct connman_service *service)
8334 return service->state;
8337 unsigned int __connman_service_get_order(struct connman_service *service)
8339 unsigned int order = 0;
8346 if (!service->favorite)
8349 #if defined TIZEN_EXT
8350 if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
8351 service->do_split_routing == FALSE)
8353 else if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
8354 if (service->order < 5)
8356 } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
8358 else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
8360 else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
8361 __connman_service_is_internet_profile(service) == TRUE)
8363 else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
8364 __connman_service_is_tethering_profile(service) == TRUE)
8366 else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
8371 if (service == service_list->data)
8374 if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
8375 !service->do_split_routing) {
8376 service->order = 10;
8380 DBG("service %p name %s order %d split %d", service, service->name,
8381 order, service->do_split_routing);
8386 void __connman_service_update_ordering(void)
8388 if (service_list && service_list->next)
8389 service_list = g_list_sort(service_list, service_compare);
8392 static enum connman_service_type convert_network_type(struct connman_network *network)
8394 enum connman_network_type type = connman_network_get_type(network);
8397 case CONNMAN_NETWORK_TYPE_UNKNOWN:
8398 case CONNMAN_NETWORK_TYPE_VENDOR:
8400 case CONNMAN_NETWORK_TYPE_ETHERNET:
8401 return CONNMAN_SERVICE_TYPE_ETHERNET;
8402 case CONNMAN_NETWORK_TYPE_WIFI:
8403 return CONNMAN_SERVICE_TYPE_WIFI;
8404 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
8405 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
8406 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
8407 case CONNMAN_NETWORK_TYPE_CELLULAR:
8408 return CONNMAN_SERVICE_TYPE_CELLULAR;
8409 case CONNMAN_NETWORK_TYPE_GADGET:
8410 return CONNMAN_SERVICE_TYPE_GADGET;
8413 return CONNMAN_SERVICE_TYPE_UNKNOWN;
8416 static enum connman_service_security convert_wifi_security(const char *security)
8419 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
8420 else if (g_str_equal(security, "none"))
8421 return CONNMAN_SERVICE_SECURITY_NONE;
8422 else if (g_str_equal(security, "wep"))
8423 return CONNMAN_SERVICE_SECURITY_WEP;
8424 else if (g_str_equal(security, "psk"))
8425 return CONNMAN_SERVICE_SECURITY_PSK;
8426 else if (g_str_equal(security, "ieee8021x"))
8427 return CONNMAN_SERVICE_SECURITY_8021X;
8428 else if (g_str_equal(security, "wpa"))
8429 return CONNMAN_SERVICE_SECURITY_WPA;
8430 else if (g_str_equal(security, "rsn"))
8431 return CONNMAN_SERVICE_SECURITY_RSN;
8432 #if defined TIZEN_EXT
8433 else if (g_str_equal(security, "ft_psk") == TRUE)
8434 return CONNMAN_SERVICE_SECURITY_PSK;
8435 else if (g_str_equal(security, "ft_ieee8021x") == TRUE)
8436 return CONNMAN_SERVICE_SECURITY_8021X;
8439 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
8442 static void update_from_network(struct connman_service *service,
8443 struct connman_network *network)
8445 uint8_t strength = service->strength;
8448 DBG("service %p network %p", service, network);
8450 if (is_connected(service))
8453 if (is_connecting(service))
8456 str = connman_network_get_string(network, "Name");
8458 g_free(service->name);
8459 service->name = g_strdup(str);
8460 service->hidden = false;
8462 g_free(service->name);
8463 service->name = NULL;
8464 service->hidden = true;
8467 service->strength = connman_network_get_strength(network);
8468 service->roaming = connman_network_get_bool(network, "Roaming");
8470 if (service->strength == 0) {
8472 * Filter out 0-values; it's unclear what they mean
8473 * and they cause anomalous sorting of the priority list.
8475 service->strength = strength;
8478 str = connman_network_get_string(network, "WiFi.Security");
8479 service->security = convert_wifi_security(str);
8481 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
8482 service->wps = connman_network_get_bool(network, "WiFi.WPS");
8484 if (service->strength > strength && service->network) {
8485 connman_network_unref(service->network);
8486 service->network = connman_network_ref(network);
8488 strength_changed(service);
8491 if (!service->network)
8492 service->network = connman_network_ref(network);
8494 service_list_sort();
8498 * __connman_service_create_from_network:
8499 * @network: network structure
8501 * Look up service by network and if not found, create one
8503 struct connman_service * __connman_service_create_from_network(struct connman_network *network)
8505 struct connman_service *service;
8506 struct connman_device *device;
8507 const char *ident, *group;
8509 unsigned int *auto_connect_types;
8512 DBG("network %p", network);
8517 ident = __connman_network_get_ident(network);
8521 group = connman_network_get_group(network);
8525 name = g_strdup_printf("%s_%s_%s",
8526 __connman_network_get_type(network), ident, group);
8527 service = service_get(name);
8533 if (__connman_network_get_weakness(network))
8536 if (service->path) {
8537 update_from_network(service, network);
8538 __connman_connection_update_gateway();
8542 service->type = convert_network_type(network);
8544 auto_connect_types = connman_setting_get_uint_list("DefaultAutoConnectTechnologies");
8545 service->autoconnect = false;
8546 for (i = 0; auto_connect_types &&
8547 auto_connect_types[i] != 0; i++) {
8548 if (service->type == auto_connect_types[i]) {
8549 service->autoconnect = true;
8554 switch (service->type) {
8555 case CONNMAN_SERVICE_TYPE_UNKNOWN:
8556 case CONNMAN_SERVICE_TYPE_SYSTEM:
8557 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
8558 case CONNMAN_SERVICE_TYPE_GPS:
8559 case CONNMAN_SERVICE_TYPE_VPN:
8560 case CONNMAN_SERVICE_TYPE_GADGET:
8561 case CONNMAN_SERVICE_TYPE_WIFI:
8562 case CONNMAN_SERVICE_TYPE_CELLULAR:
8563 case CONNMAN_SERVICE_TYPE_P2P:
8565 case CONNMAN_SERVICE_TYPE_ETHERNET:
8566 service->favorite = true;
8570 service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
8571 service->state = combine_state(service->state_ipv4, service->state_ipv6);
8573 update_from_network(service, network);
8575 index = connman_network_get_index(network);
8577 if (!service->ipconfig_ipv4)
8578 service->ipconfig_ipv4 = create_ip4config(service, index,
8579 CONNMAN_IPCONFIG_METHOD_DHCP);
8581 if (!service->ipconfig_ipv6)
8582 service->ipconfig_ipv6 = create_ip6config(service, index);
8584 service_register(service);
8586 if (service->favorite) {
8587 device = connman_network_get_device(service->network);
8588 if (device && !connman_device_get_scanning(device)) {
8590 switch (service->type) {
8591 case CONNMAN_SERVICE_TYPE_UNKNOWN:
8592 case CONNMAN_SERVICE_TYPE_SYSTEM:
8593 case CONNMAN_SERVICE_TYPE_P2P:
8596 case CONNMAN_SERVICE_TYPE_GADGET:
8597 case CONNMAN_SERVICE_TYPE_ETHERNET:
8598 if (service->autoconnect) {
8599 __connman_service_connect(service,
8600 CONNMAN_SERVICE_CONNECT_REASON_AUTO);
8605 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
8606 case CONNMAN_SERVICE_TYPE_GPS:
8607 case CONNMAN_SERVICE_TYPE_VPN:
8608 case CONNMAN_SERVICE_TYPE_WIFI:
8609 case CONNMAN_SERVICE_TYPE_CELLULAR:
8610 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
8615 #if defined TIZEN_EXT
8616 /* TIZEN synchronizes below information when the service creates */
8617 if (service->eap != NULL)
8618 connman_network_set_string(service->network, "WiFi.EAP",
8620 if (service->identity != NULL)
8621 connman_network_set_string(service->network, "WiFi.Identity",
8623 if (service->phase2 != NULL)
8624 connman_network_set_string(service->network, "WiFi.Phase2",
8629 __connman_notifier_service_add(service, service->name);
8630 service_schedule_added(service);
8635 void __connman_service_update_from_network(struct connman_network *network)
8637 bool need_sort = false;
8638 struct connman_service *service;
8644 service = connman_service_lookup_from_network(network);
8648 if (!service->network)
8651 #if defined TIZEN_EXT
8652 if (service->storage_reload) {
8653 service_load(service);
8654 __connman_service_set_storage_reload(service, false);
8658 name = connman_network_get_string(service->network, "Name");
8659 if (g_strcmp0(service->name, name) != 0) {
8660 g_free(service->name);
8661 service->name = g_strdup(name);
8663 if (allow_property_changed(service))
8664 connman_dbus_property_changed_basic(service->path,
8665 CONNMAN_SERVICE_INTERFACE, "Name",
8666 DBUS_TYPE_STRING, &service->name);
8669 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
8670 service->wps = connman_network_get_bool(network, "WiFi.WPS");
8672 strength = connman_network_get_strength(service->network);
8673 if (strength == service->strength)
8676 service->strength = strength;
8679 strength_changed(service);
8682 roaming = connman_network_get_bool(service->network, "Roaming");
8683 if (roaming == service->roaming)
8686 stats_enable = stats_enabled(service);
8688 stats_stop(service);
8690 service->roaming = roaming;
8694 stats_start(service);
8696 roaming_changed(service);
8700 service_list_sort();
8704 void __connman_service_remove_from_network(struct connman_network *network)
8706 struct connman_service *service;
8708 service = connman_service_lookup_from_network(network);
8710 DBG("network %p service %p", network, service);
8715 service->ignore = true;
8717 __connman_connection_gateway_remove(service,
8718 CONNMAN_IPCONFIG_TYPE_ALL);
8720 connman_service_unref(service);
8724 * __connman_service_create_from_provider:
8725 * @provider: provider structure
8727 * Look up service by provider and if not found, create one
8729 struct connman_service *
8730 __connman_service_create_from_provider(struct connman_provider *provider)
8732 struct connman_service *service;
8733 const char *ident, *str;
8735 int index = connman_provider_get_index(provider);
8737 DBG("provider %p", provider);
8739 ident = __connman_provider_get_ident(provider);
8743 name = g_strdup_printf("vpn_%s", ident);
8744 service = service_get(name);
8750 service->type = CONNMAN_SERVICE_TYPE_VPN;
8751 service->provider = connman_provider_ref(provider);
8752 service->autoconnect = false;
8753 service->favorite = true;
8755 service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
8756 service->state = combine_state(service->state_ipv4, service->state_ipv6);
8758 str = connman_provider_get_string(provider, "Name");
8760 g_free(service->name);
8761 service->name = g_strdup(str);
8762 service->hidden = false;
8764 g_free(service->name);
8765 service->name = NULL;
8766 service->hidden = true;
8769 service->strength = 0;
8771 if (!service->ipconfig_ipv4)
8772 service->ipconfig_ipv4 = create_ip4config(service, index,
8773 CONNMAN_IPCONFIG_METHOD_MANUAL);
8775 if (!service->ipconfig_ipv6)
8776 service->ipconfig_ipv6 = create_ip6config(service, index);
8778 service_register(service);
8780 __connman_notifier_service_add(service, service->name);
8781 service_schedule_added(service);
8786 static void remove_unprovisioned_services(void)
8789 GKeyFile *keyfile, *configkeyfile;
8790 char *file, *section;
8793 services = connman_storage_get_services();
8797 for (; services[i]; i++) {
8798 file = section = NULL;
8799 keyfile = configkeyfile = NULL;
8801 keyfile = connman_storage_load_service(services[i]);
8805 file = g_key_file_get_string(keyfile, services[i],
8806 "Config.file", NULL);
8810 section = g_key_file_get_string(keyfile, services[i],
8811 "Config.ident", NULL);
8815 configkeyfile = __connman_storage_load_config(file);
8816 if (!configkeyfile) {
8818 * Config file is missing, remove the provisioned
8821 __connman_storage_remove_service(services[i]);
8825 if (!g_key_file_has_group(configkeyfile, section))
8827 * Config section is missing, remove the provisioned
8830 __connman_storage_remove_service(services[i]);
8834 g_key_file_free(keyfile);
8837 g_key_file_free(configkeyfile);
8843 g_strfreev(services);
8846 static int agent_probe(struct connman_agent *agent)
8848 DBG("agent %p", agent);
8852 static void agent_remove(struct connman_agent *agent)
8854 DBG("agent %p", agent);
8857 static void *agent_context_ref(void *context)
8859 struct connman_service *service = context;
8861 return (void *)connman_service_ref(service);
8864 static void agent_context_unref(void *context)
8866 struct connman_service *service = context;
8868 connman_service_unref(service);
8871 static struct connman_agent_driver agent_driver = {
8873 .interface = CONNMAN_AGENT_INTERFACE,
8874 .probe = agent_probe,
8875 .remove = agent_remove,
8876 .context_ref = agent_context_ref,
8877 .context_unref = agent_context_unref,
8880 int __connman_service_init(void)
8886 err = connman_agent_driver_register(&agent_driver);
8888 connman_error("Cannot register agent driver for %s",
8893 connection = connman_dbus_get_connection();
8895 service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
8896 NULL, service_free);
8898 services_notify = g_new0(struct _services_notify, 1);
8899 services_notify->remove = g_hash_table_new_full(g_str_hash,
8900 g_str_equal, g_free, NULL);
8901 services_notify->add = g_hash_table_new(g_str_hash, g_str_equal);
8903 remove_unprovisioned_services();
8908 void __connman_service_cleanup(void)
8912 if (vpn_autoconnect_timeout) {
8913 g_source_remove(vpn_autoconnect_timeout);
8914 vpn_autoconnect_timeout = 0;
8917 if (autoconnect_timeout != 0) {
8918 g_source_remove(autoconnect_timeout);
8919 autoconnect_timeout = 0;
8922 connman_agent_driver_unregister(&agent_driver);
8924 g_list_free(service_list);
8925 service_list = NULL;
8927 g_hash_table_destroy(service_hash);
8928 service_hash = NULL;
8930 g_slist_free(counter_list);
8931 counter_list = NULL;
8933 if (services_notify->id != 0) {
8934 g_source_remove(services_notify->id);
8935 service_send_changed(NULL);
8936 g_hash_table_destroy(services_notify->remove);
8937 g_hash_table_destroy(services_notify->add);
8939 g_free(services_notify);
8941 dbus_connection_unref(connection);