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
35 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
38 #include <connman/storage.h>
39 #include <connman/setting.h>
40 #include <connman/agent.h>
42 #include "src/shared/util.h"
46 #define CONNECT_TIMEOUT 120
49 #define WIFI_BSSID_STR_LEN 18
50 #define MAX_WIFI_PROFILES 200
52 #define FREQ_RANGE_24GHZ_CHANNEL_1 2412
53 #define FREQ_RANGE_24GHZ_CHANNEL_14 2484
54 #define FREQ_RANGE_5GHZ_CHANNEL_32 5160
55 #define FREQ_RANGE_5GHZ_CHANNEL_165 5825
57 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
58 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
60 #define VPN_AUTOCONNECT_TIMEOUT_DEFAULT 1
61 #define VPN_AUTOCONNECT_TIMEOUT_STEP 30
62 #define VPN_AUTOCONNECT_TIMEOUT_ATTEMPTS_THRESHOLD 270
64 static DBusConnection *connection = NULL;
66 static GList *service_list = NULL;
67 static GHashTable *service_hash = NULL;
68 static GSList *counter_list = NULL;
69 static unsigned int autoconnect_id = 0;
70 static unsigned int vpn_autoconnect_id = 0;
71 static struct connman_service *current_default = NULL;
72 static bool services_dirty = false;
73 static bool enable_online_to_ready_transition = false;
74 static unsigned int online_check_initial_interval = 0;
75 static unsigned int online_check_max_interval = 0;
78 static bool auto_connect_mode = TRUE;
80 struct saved_profiles {
85 #if defined TIZEN_EXT_INS
86 static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = {
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
91 #if defined TIZEN_EXT && defined TIZEN_EXT_INS
92 enum connman_ins_preferred_freq {
93 CONNMAN_INS_PREFERRED_FREQ_UNKNOWN,
94 CONNMAN_INS_PREFERRED_FREQ_24GHZ,
95 CONNMAN_INS_PREFERRED_FREQ_5GHZ,
98 struct connman_ins_settings {
99 bool last_user_selection;
100 unsigned int last_user_selection_time;
101 unsigned int last_user_selection_score;
103 unsigned int last_connected_score;
104 enum connman_ins_preferred_freq preferred_freq;
105 unsigned int preferred_freq_score;
106 unsigned int security_priority[CONNMAN_SERVICE_SECURITY_MAX];
107 unsigned int security_priority_count;
108 unsigned int security_priority_score;
111 unsigned int internet_score;
112 int signal_level3_5ghz;
113 int signal_level3_24ghz;
116 static struct connman_ins_settings ins_settings;
117 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
119 struct connman_stats {
122 struct connman_stats_data data_last;
123 struct connman_stats_data data;
127 struct connman_stats_counter {
129 struct connman_stats stats;
130 struct connman_stats stats_roaming;
133 struct connman_service {
137 enum connman_service_type type;
138 enum connman_service_security security;
139 enum connman_service_state state;
140 enum connman_service_state state_ipv4;
141 enum connman_service_state state_ipv6;
142 enum connman_service_error error;
143 enum connman_service_connect_reason connect_reason;
150 struct timeval modified;
155 struct connman_ipconfig *ipconfig_ipv4;
156 struct connman_ipconfig *ipconfig_ipv6;
157 struct connman_network *network;
158 struct connman_provider *provider;
160 char **nameservers_config;
161 char **nameservers_auto;
162 int nameservers_timeout;
169 char **timeservers_config;
170 /* 802.1x settings from the config files */
173 char *anonymous_identity;
174 char *agent_identity;
177 char *altsubject_match;
178 char *domain_suffix_match;
180 char *client_cert_file;
181 char *private_key_file;
182 char *private_key_passphrase;
184 DBusMessage *pending;
185 DBusMessage *provider_pending;
187 struct connman_stats stats;
188 struct connman_stats stats_roaming;
189 GHashTable *counter_table;
190 enum connman_service_proxy_method proxy;
191 enum connman_service_proxy_method proxy_config;
196 bool wps_advertizing;
197 guint online_timeout;
198 unsigned int online_check_interval_ipv4;
199 unsigned int online_check_interval_ipv6;
200 bool do_split_routing;
205 #if defined TIZEN_EXT
207 * Description: TIZEN implements system global connection management.
208 * It's only for PDP (cellular) bearer. Wi-Fi is managed
209 * by ConnMan automatically. Reference count can help to
210 * manage open/close connection requests by each application.
212 int user_pdn_connection_refcount;
215 * Description: In case of EAP security type,
216 * user can select the keymgmt type for roaming(802.11r).
217 * - FT, CCKM, OKC, ...
220 int disconnect_reason;
221 int assoc_status_code;
223 * Only for EAP-FAST and EAP-PEAP in EAPoL.
226 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
233 * Description: To indicate that disconnection triggered by user.
235 bool disconnection_requested;
237 enum connman_dnsconfig_method dns_config_method_ipv4;
238 enum connman_dnsconfig_method dns_config_method_ipv6;
240 #if defined TIZEN_EXT
243 char *net_access_key;
244 #if defined TIZEN_EXT_INS
245 unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
246 bool is_internet_connection;
247 int assoc_reject_count;
248 int score_last_user_selection;
249 int score_last_connected;
251 int score_security_priority;
252 int score_internet_connection;
257 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
259 * To indicate use of EAP over Ethernet.
262 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
265 static bool allow_property_changed(struct connman_service *service);
267 static struct connman_ipconfig *create_ip4config(struct connman_service *service,
268 int index, enum connman_ipconfig_method method);
269 static struct connman_ipconfig *create_ip6config(struct connman_service *service,
271 static void dns_changed(struct connman_service *service);
272 static void vpn_auto_connect(void);
276 struct connman_service *service;
279 #if defined TIZEN_EXT
280 struct assoc_reject_data {
282 GSList *reject_time_list;
286 * Public APIs to use user_pdn_connection_refcount
288 void connman_service_user_pdn_connection_ref(struct connman_service *service)
290 __sync_fetch_and_add(&service->user_pdn_connection_refcount, 1);
292 DBG("User made PDN connection referenced: %d",
293 service->user_pdn_connection_refcount);
296 gboolean connman_service_user_pdn_connection_unref_and_test(
297 struct connman_service *service)
299 __sync_synchronize();
301 DBG("User made PDN connection referenced: %d, which will be decreased",
302 service->user_pdn_connection_refcount);
304 if (service->user_pdn_connection_refcount < 1)
307 if (__sync_sub_and_fetch(&service->user_pdn_connection_refcount, 1) == 0)
313 gboolean connman_service_is_no_ref_user_pdn_connection(
314 struct connman_service *cellular)
316 if (cellular == NULL)
319 __sync_synchronize();
320 if (cellular->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
321 cellular->user_pdn_connection_refcount == 0)
328 static void compare_path(gpointer value, gpointer user_data)
330 struct connman_service *service = value;
331 struct find_data *data = user_data;
336 if (g_strcmp0(service->path, data->path) == 0)
337 data->service = service;
340 static struct connman_service *find_service(const char *path)
342 struct find_data data = { .path = path, .service = NULL };
344 DBG("path %s", path);
346 g_list_foreach(service_list, compare_path, &data);
351 static const char *reason2string(enum connman_service_connect_reason reason)
355 case CONNMAN_SERVICE_CONNECT_REASON_NONE:
357 case CONNMAN_SERVICE_CONNECT_REASON_USER:
359 case CONNMAN_SERVICE_CONNECT_REASON_AUTO:
361 case CONNMAN_SERVICE_CONNECT_REASON_SESSION:
363 case CONNMAN_SERVICE_CONNECT_REASON_NATIVE:
370 const char *__connman_service_type2string(enum connman_service_type type)
373 case CONNMAN_SERVICE_TYPE_UNKNOWN:
375 case CONNMAN_SERVICE_TYPE_SYSTEM:
377 case CONNMAN_SERVICE_TYPE_ETHERNET:
379 case CONNMAN_SERVICE_TYPE_WIFI:
381 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
383 case CONNMAN_SERVICE_TYPE_CELLULAR:
385 case CONNMAN_SERVICE_TYPE_GPS:
387 case CONNMAN_SERVICE_TYPE_VPN:
389 case CONNMAN_SERVICE_TYPE_GADGET:
391 case CONNMAN_SERVICE_TYPE_P2P:
393 #if defined TIZEN_EXT_WIFI_MESH
394 case CONNMAN_SERVICE_TYPE_MESH:
402 enum connman_service_type __connman_service_string2type(const char *str)
405 return CONNMAN_SERVICE_TYPE_UNKNOWN;
407 if (strcmp(str, "ethernet") == 0)
408 return CONNMAN_SERVICE_TYPE_ETHERNET;
409 if (strcmp(str, "gadget") == 0)
410 return CONNMAN_SERVICE_TYPE_GADGET;
411 if (strcmp(str, "wifi") == 0)
412 return CONNMAN_SERVICE_TYPE_WIFI;
413 if (strcmp(str, "cellular") == 0)
414 return CONNMAN_SERVICE_TYPE_CELLULAR;
415 if (strcmp(str, "bluetooth") == 0)
416 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
417 if (strcmp(str, "vpn") == 0)
418 return CONNMAN_SERVICE_TYPE_VPN;
419 if (strcmp(str, "gps") == 0)
420 return CONNMAN_SERVICE_TYPE_GPS;
421 if (strcmp(str, "system") == 0)
422 return CONNMAN_SERVICE_TYPE_SYSTEM;
423 if (strcmp(str, "p2p") == 0)
424 return CONNMAN_SERVICE_TYPE_P2P;
426 return CONNMAN_SERVICE_TYPE_UNKNOWN;
429 enum connman_service_security __connman_service_string2security(const char *str)
432 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
434 if (!strcmp(str, "psk"))
435 return CONNMAN_SERVICE_SECURITY_PSK;
436 if (!strcmp(str, "ieee8021x") || !strcmp(str, "8021x"))
437 return CONNMAN_SERVICE_SECURITY_8021X;
438 if (!strcmp(str, "none") || !strcmp(str, "open"))
439 return CONNMAN_SERVICE_SECURITY_NONE;
440 if (!strcmp(str, "wep"))
441 return CONNMAN_SERVICE_SECURITY_WEP;
442 #if defined TIZEN_EXT
443 if (!strcmp(str, "rsn"))
444 return CONNMAN_SERVICE_SECURITY_RSN;
445 if (!strcmp(str, "sae"))
446 return CONNMAN_SERVICE_SECURITY_SAE;
447 if (!strcmp(str, "owe"))
448 return CONNMAN_SERVICE_SECURITY_OWE;
449 if (!strcmp(str, "dpp"))
450 return CONNMAN_SERVICE_SECURITY_DPP;
453 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
456 static const char *security2string(enum connman_service_security security)
459 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
461 case CONNMAN_SERVICE_SECURITY_NONE:
463 case CONNMAN_SERVICE_SECURITY_WEP:
465 case CONNMAN_SERVICE_SECURITY_PSK:
466 case CONNMAN_SERVICE_SECURITY_WPA:
467 #if defined TIZEN_EXT
469 case CONNMAN_SERVICE_SECURITY_RSN:
471 case CONNMAN_SERVICE_SECURITY_SAE:
473 case CONNMAN_SERVICE_SECURITY_OWE:
475 case CONNMAN_SERVICE_SECURITY_DPP:
478 case CONNMAN_SERVICE_SECURITY_RSN:
481 case CONNMAN_SERVICE_SECURITY_8021X:
483 #if defined TIZEN_EXT
492 static const char *state2string(enum connman_service_state state)
495 case CONNMAN_SERVICE_STATE_UNKNOWN:
497 case CONNMAN_SERVICE_STATE_IDLE:
499 case CONNMAN_SERVICE_STATE_ASSOCIATION:
500 return "association";
501 case CONNMAN_SERVICE_STATE_CONFIGURATION:
502 return "configuration";
503 case CONNMAN_SERVICE_STATE_READY:
505 case CONNMAN_SERVICE_STATE_ONLINE:
507 case CONNMAN_SERVICE_STATE_DISCONNECT:
509 case CONNMAN_SERVICE_STATE_FAILURE:
516 static const char *error2string(enum connman_service_error error)
519 case CONNMAN_SERVICE_ERROR_UNKNOWN:
521 case CONNMAN_SERVICE_ERROR_OUT_OF_RANGE:
522 return "out-of-range";
523 case CONNMAN_SERVICE_ERROR_PIN_MISSING:
524 return "pin-missing";
525 case CONNMAN_SERVICE_ERROR_DHCP_FAILED:
526 return "dhcp-failed";
527 case CONNMAN_SERVICE_ERROR_CONNECT_FAILED:
528 return "connect-failed";
529 case CONNMAN_SERVICE_ERROR_LOGIN_FAILED:
530 return "login-failed";
531 case CONNMAN_SERVICE_ERROR_AUTH_FAILED:
532 return "auth-failed";
534 case CONNMAN_SERVICE_ERROR_ASSOC_FAILED:
535 return "assoc-failed";
537 case CONNMAN_SERVICE_ERROR_INVALID_KEY:
538 return "invalid-key";
539 case CONNMAN_SERVICE_ERROR_BLOCKED:
546 static const char *proxymethod2string(enum connman_service_proxy_method method)
549 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
551 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
553 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
555 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
562 static enum connman_service_proxy_method string2proxymethod(const char *method)
564 if (g_strcmp0(method, "direct") == 0)
565 return CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
566 else if (g_strcmp0(method, "auto") == 0)
567 return CONNMAN_SERVICE_PROXY_METHOD_AUTO;
568 else if (g_strcmp0(method, "manual") == 0)
569 return CONNMAN_SERVICE_PROXY_METHOD_MANUAL;
571 return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
575 static const char *__connman_dnsconfig_method2string(enum connman_dnsconfig_method method)
578 case CONNMAN_DNSCONFIG_METHOD_UNKNOWN:
580 case CONNMAN_DNSCONFIG_METHOD_MANUAL:
582 case CONNMAN_DNSCONFIG_METHOD_DHCP:
589 static enum connman_dnsconfig_method __connman_dnsconfig_string2method(
592 if (g_strcmp0(method, "manual") == 0)
593 return CONNMAN_DNSCONFIG_METHOD_MANUAL;
594 else if (g_strcmp0(method, "dhcp") == 0)
595 return CONNMAN_DNSCONFIG_METHOD_DHCP;
597 return CONNMAN_DNSCONFIG_METHOD_UNKNOWN;
601 void __connman_service_split_routing_changed(struct connman_service *service)
603 dbus_bool_t split_routing;
608 if (!allow_property_changed(service))
611 split_routing = service->do_split_routing;
612 if (!connman_dbus_property_changed_basic(service->path,
613 CONNMAN_SERVICE_INTERFACE, "SplitRouting",
614 DBUS_TYPE_BOOLEAN, &split_routing))
615 connman_warn("cannot send SplitRouting property change on %s",
616 service->identifier);
619 void __connman_service_set_split_routing(struct connman_service *service,
622 if (service->type != CONNMAN_SERVICE_TYPE_VPN)
625 service->do_split_routing = value;
627 if (service->do_split_routing)
633 * In order to make sure the value is propagated also when loading the
634 * VPN service signal the value regardless of the value change.
636 __connman_service_split_routing_changed(service);
639 int __connman_service_load_modifiable(struct connman_service *service)
642 GError *error = NULL;
646 DBG("service %p", service);
648 keyfile = connman_storage_load_service(service->identifier);
652 switch (service->type) {
653 case CONNMAN_SERVICE_TYPE_UNKNOWN:
654 case CONNMAN_SERVICE_TYPE_SYSTEM:
655 case CONNMAN_SERVICE_TYPE_GPS:
656 case CONNMAN_SERVICE_TYPE_P2P:
657 #if defined TIZEN_EXT_WIFI_MESH
658 case CONNMAN_SERVICE_TYPE_MESH:
661 case CONNMAN_SERVICE_TYPE_VPN:
662 __connman_service_set_split_routing(service,
663 g_key_file_get_boolean(keyfile,
665 "SplitRouting", NULL));
668 case CONNMAN_SERVICE_TYPE_WIFI:
669 case CONNMAN_SERVICE_TYPE_GADGET:
670 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
671 case CONNMAN_SERVICE_TYPE_CELLULAR:
672 case CONNMAN_SERVICE_TYPE_ETHERNET:
673 autoconnect = g_key_file_get_boolean(keyfile,
674 service->identifier, "AutoConnect", &error);
676 service->autoconnect = autoconnect;
677 g_clear_error(&error);
681 str = g_key_file_get_string(keyfile,
682 service->identifier, "Modified", NULL);
684 util_iso8601_to_timeval(str, &service->modified);
688 g_key_file_free(keyfile);
693 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
694 static void __connman_service_cleanup_8021x(struct connman_service *service)
699 DBG("service %p ", service);
701 __connman_service_set_string(service, "EAP", NULL);
702 __connman_service_set_string(service, "Identity", NULL);
703 __connman_service_set_string(service, "Passphrase", NULL);
704 __connman_service_set_string(service, "AnonymousIdentity", NULL);
705 __connman_service_set_string(service, "CACertFile", NULL);
706 __connman_service_set_string(service, "ClientCertFile", NULL);
707 __connman_service_set_string(service, "PrivateKeyFile", NULL);
708 __connman_service_set_string(service, "PrivateKeyPassphrase", NULL);
709 __connman_service_set_string(service, "Phase1", NULL);
710 __connman_service_set_string(service, "Phase2", NULL);
711 __connman_service_set_string(service, "PacFile", NULL);
714 static int connman_service_set_eapol_property(struct connman_service *service,
715 DBusMessageIter *array)
717 DBusMessageIter dict;
720 __connman_service_cleanup_8021x(service);
722 if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
725 dbus_message_iter_recurse(array, &dict);
727 while(dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
728 DBusMessageIter entry, value;
732 dbus_message_iter_recurse(&dict, &entry);
734 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
737 dbus_message_iter_get_basic(&entry, &key);
738 dbus_message_iter_next(&entry);
740 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
743 dbus_message_iter_recurse(&entry, &value);
745 type = dbus_message_iter_get_arg_type(&value);
747 if (g_str_equal(key, "UseEapol")) {
748 dbus_bool_t use_eapol;
750 if (type != DBUS_TYPE_BOOLEAN)
753 dbus_message_iter_get_basic(&value, &use_eapol);
754 service->use_eapol = use_eapol;
756 } else if (g_str_equal(key, "EAP")) {
757 if (type != DBUS_TYPE_STRING)
760 dbus_message_iter_get_basic(&value, &str);
761 __connman_service_set_string(service, "EAP", str);
763 } else if (g_str_equal(key, "Identity")) {
764 if (type != DBUS_TYPE_STRING)
767 dbus_message_iter_get_basic(&value, &str);
768 __connman_service_set_string(service, "Identity", str);
770 } else if (g_str_equal(key, "AnonymousIdentity")) {
771 if (type != DBUS_TYPE_STRING)
774 dbus_message_iter_get_basic(&value, &str);
775 __connman_service_set_string(service, "AnonymousIdentity", str);
777 } else if (g_str_equal(key, "CACertFile")) {
778 if (type != DBUS_TYPE_STRING)
781 dbus_message_iter_get_basic(&value, &str);
782 __connman_service_set_string(service, "CACertFile", str);
783 } else if (g_str_equal(key, "ClientCertFile")) {
784 if (type != DBUS_TYPE_STRING)
787 dbus_message_iter_get_basic(&value, &str);
788 __connman_service_set_string(service, "ClientCertFile", str);
789 } else if (g_str_equal(key, "PrivateKeyFile")) {
790 if (type != DBUS_TYPE_STRING)
793 dbus_message_iter_get_basic(&value, &str);
794 __connman_service_set_string(service, "PrivateKeyFile", str);
795 } else if (g_str_equal(key, "PrivateKeyPassphrase")) {
796 if (type != DBUS_TYPE_STRING)
799 dbus_message_iter_get_basic(&value, &str);
800 __connman_service_set_string(service, "PrivateKeyPassphrase", str);
801 } else if (g_str_equal(key, "Phase2")) {
802 if (type != DBUS_TYPE_STRING)
805 dbus_message_iter_get_basic(&value, &str);
806 __connman_service_set_string(service, "Phase2", str);
807 } else if (g_str_equal(key, "Phase1")) {
809 char phase1[5] = {0,};
811 if (type != DBUS_TYPE_INT32)
814 dbus_message_iter_get_basic(&value, &val);
815 sprintf(phase1, "%d", val);
816 __connman_service_set_string(service, "Phase1", phase1);
817 } else if (g_str_equal(key, "PacFile")) {
818 if (type != DBUS_TYPE_STRING)
821 dbus_message_iter_get_basic(&value, &str);
822 __connman_service_set_string(service, "PacFile", str);
825 dbus_message_iter_next(&dict);
832 #if defined TIZEN_EXT_INS
833 static void save_assoc_reject(gpointer key, gpointer value, gpointer user_data)
835 struct assoc_reject_data *assoc_rd = value;
836 GString *assoc_reject_str = user_data;
843 if (g_slist_length(assoc_rd->reject_time_list) < 1)
846 for (list = assoc_rd->reject_time_list; list; list = list->next) {
847 time_t assoc_reject_time = GPOINTER_TO_INT(list->data);
849 val_str = g_strdup_printf("%s_%ld", assoc_rd->bssid, assoc_reject_time);
851 if (assoc_reject_str->len > 0)
852 g_string_append_printf(assoc_reject_str, " %s", val_str);
854 g_string_append(assoc_reject_str, val_str);
860 static void count_assoc_reject(gpointer key, gpointer value, gpointer user_data)
862 struct assoc_reject_data *assoc_data = value;
863 int *assoc_reject_count = user_data;
866 *assoc_reject_count += g_slist_length(assoc_data->reject_time_list);
869 static bool update_assoc_reject(struct connman_service *service)
871 GHashTable *assoc_reject_table;
872 int assoc_reject_count;
874 if (!service->network)
877 assoc_reject_table = connman_network_get_assoc_reject_table(service->network);
878 if (assoc_reject_table) {
879 assoc_reject_count = 0;
880 g_hash_table_foreach(assoc_reject_table, count_assoc_reject, &assoc_reject_count);
882 DBG("assoc reject count [%d -> %d]",
883 service->assoc_reject_count, assoc_reject_count);
885 if (service->assoc_reject_count != assoc_reject_count) {
886 service->assoc_reject_count = assoc_reject_count;
894 static int service_ext_load(struct connman_service *service)
897 GHashTable *reject_table;
900 struct assoc_reject_data *reject_data;
906 struct tm* ref_timeinfo;
911 DBG("service %p", service);
913 if (!service->network)
916 if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
919 keyfile = connman_storage_load_service(service->identifier);
923 reject_table = connman_network_get_assoc_reject_table(service->network);
925 reject_list = g_key_file_get_string_list(keyfile,
926 service->identifier, "AssocReject", &reject_len, NULL);
928 if (!reject_list || reject_len == 0) {
929 g_strfreev(reject_list);
933 /* Only events that occur within one hour are appened. */
934 curr_time = time(NULL);
935 ref_timeinfo = localtime(&curr_time);
936 ref_timeinfo->tm_hour -= 1;
937 ref_time = mktime(ref_timeinfo);
939 for (i = 0; reject_list[i]; i++) {
940 bssid_time = g_strsplit(reject_list[i], "_", 0);
946 bssid = bssid_time[0];
947 reject_time = strtol(bssid_time[1], NULL, 10);
949 if (reject_time < ref_time) {
950 g_strfreev(bssid_time);
955 reject_data = g_hash_table_lookup(reject_table, bssid);
957 reject_data = g_try_new0(struct assoc_reject_data, 1);
959 g_strfreev(bssid_time);
964 reject_data->bssid = g_strdup(bssid);
965 g_hash_table_insert(reject_table, reject_data->bssid, reject_data);
968 reject_data->reject_time_list = g_slist_append(reject_data->reject_time_list,
969 GINT_TO_POINTER(reject_time));
971 DBG("assoc reject [%s_%ld]", bssid, reject_time);
973 g_strfreev(bssid_time);
976 g_strfreev(reject_list);
979 g_key_file_free(keyfile);
983 static int service_ext_save(struct connman_service *service)
986 GHashTable *reject_table;
992 DBG("service %p", service);
994 if (!service->network)
997 if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
1000 keyfile = connman_storage_load_service(service->identifier);
1005 /* Last connected BSSID */
1006 if (memcmp(service->last_connected_bssid, invalid_bssid, WIFI_BSSID_LEN_MAX)) {
1007 char *identifier = service->identifier;
1011 bssid_str = g_string_sized_new(MAC_ADDRESS_LENGTH);
1017 for (i = 0; i < WIFI_BSSID_LEN_MAX; i++) {
1018 g_string_append_printf(bssid_str,
1019 "%02x", service->last_connected_bssid[i]);
1020 if (i < WIFI_BSSID_LEN_MAX - 1)
1021 g_string_append(bssid_str, ":");
1024 g_key_file_set_string(keyfile, identifier,
1025 "LastConnectedBSSID", bssid_str->str);
1027 DBG("last connected bssid[%s]", bssid_str->str);
1029 g_string_free(bssid_str, TRUE);
1035 reject_table = connman_network_get_assoc_reject_table(service->network);
1036 if (reject_table && g_hash_table_size(reject_table) > 0) {
1037 reject_str = g_string_new(NULL);
1043 g_hash_table_foreach(reject_table, save_assoc_reject, reject_str);
1045 reject_list = g_strsplit_set(reject_str->str, " ", 0);
1046 reject_len = g_strv_length(reject_list);
1048 g_key_file_set_string_list(keyfile, service->identifier,
1049 "AssocReject", (const gchar **)reject_list, reject_len);
1051 DBG("assoc reject table [%d]", reject_len);
1053 g_strfreev(reject_list);
1054 g_string_free(reject_str, TRUE);
1056 g_key_file_remove_key(keyfile, service->identifier, "AssocReject", NULL);
1060 __connman_storage_save_service(keyfile, service->identifier);
1062 g_key_file_free(keyfile);
1065 #endif /* defined TIZEN_EXT_INS */
1067 static int service_load(struct connman_service *service)
1070 GError *error = NULL;
1074 unsigned int ssid_len;
1076 #if defined TIZEN_EXT_INS
1077 bool internet_connection;
1079 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
1082 #if defined TIZEN_EXT
1083 if (!simplified_log)
1085 DBG("service %p", service);
1087 keyfile = connman_storage_load_service(service->identifier);
1089 service->new_service = true;
1092 service->new_service = false;
1094 switch (service->type) {
1095 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1096 case CONNMAN_SERVICE_TYPE_SYSTEM:
1097 case CONNMAN_SERVICE_TYPE_GPS:
1098 case CONNMAN_SERVICE_TYPE_P2P:
1099 #if defined TIZEN_EXT_WIFI_MESH
1100 case CONNMAN_SERVICE_TYPE_MESH:
1103 case CONNMAN_SERVICE_TYPE_VPN:
1104 __connman_service_set_split_routing(service,
1105 g_key_file_get_boolean(keyfile,
1106 service->identifier,
1107 "SplitRouting", NULL));
1109 autoconnect = g_key_file_get_boolean(keyfile,
1110 service->identifier, "AutoConnect", &error);
1112 service->autoconnect = autoconnect;
1113 g_clear_error(&error);
1115 case CONNMAN_SERVICE_TYPE_WIFI:
1116 if (!service->name) {
1119 name = g_key_file_get_string(keyfile,
1120 service->identifier, "Name", NULL);
1122 g_free(service->name);
1123 service->name = name;
1126 if (service->network)
1127 connman_network_set_name(service->network,
1131 if (service->network &&
1132 !connman_network_get_blob(service->network,
1133 "WiFi.SSID", &ssid_len)) {
1136 hex_ssid = g_key_file_get_string(keyfile,
1137 service->identifier,
1142 unsigned int i, j = 0, hex;
1143 size_t hex_ssid_len = strlen(hex_ssid);
1145 ssid = g_try_malloc0(hex_ssid_len / 2);
1152 for (i = 0; i < hex_ssid_len; i += 2) {
1153 sscanf(hex_ssid + i, "%02x", &hex);
1157 connman_network_set_blob(service->network,
1158 "WiFi.SSID", ssid, hex_ssid_len / 2);
1166 #if defined TIZEN_EXT_INS
1167 /* Last connected BSSID */
1168 if (service->network) {
1170 unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
1174 bssid_str = g_key_file_get_string(keyfile,
1175 service->identifier, "LastConnectedBSSID", NULL);
1178 str_list = g_strsplit(bssid_str, ":", 0);
1181 for (i = 0; i < WIFI_BSSID_LEN_MAX; i++)
1182 last_connected_bssid[i] = strtol(str_list[i], NULL, 16);
1184 memcpy(service->last_connected_bssid,
1185 last_connected_bssid, WIFI_BSSID_LEN_MAX);
1187 connman_network_set_last_connected_bssid(service->network,
1188 last_connected_bssid);
1190 g_strfreev(str_list);
1197 /* Internet connection */
1198 internet_connection = g_key_file_get_boolean(keyfile,
1199 service->identifier, "InternetConnection", &error);
1201 service->is_internet_connection = internet_connection;
1203 g_clear_error(&error);
1204 #endif /* defined TIZEN_EXT_INS */
1207 case CONNMAN_SERVICE_TYPE_GADGET:
1208 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1209 case CONNMAN_SERVICE_TYPE_CELLULAR:
1210 service->favorite = g_key_file_get_boolean(keyfile,
1211 service->identifier, "Favorite", NULL);
1215 case CONNMAN_SERVICE_TYPE_ETHERNET:
1216 autoconnect = g_key_file_get_boolean(keyfile,
1217 service->identifier, "AutoConnect", &error);
1219 service->autoconnect = autoconnect;
1220 g_clear_error(&error);
1222 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
1223 use_eapol = g_key_file_get_boolean(keyfile,
1224 service->identifier, "UseEapol", &error);
1226 service->use_eapol = use_eapol;
1227 g_clear_error(&error);
1232 str = g_key_file_get_string(keyfile,
1233 service->identifier, "Modified", NULL);
1235 util_iso8601_to_timeval(str, &service->modified);
1239 str = g_key_file_get_string(keyfile,
1240 service->identifier, "Passphrase", NULL);
1242 char *dec = g_strcompress(str);
1244 g_free(service->passphrase);
1245 service->passphrase = dec;
1248 if (service->ipconfig_ipv4)
1249 __connman_ipconfig_load(service->ipconfig_ipv4, keyfile,
1250 service->identifier, "IPv4.");
1252 if (service->ipconfig_ipv6)
1253 __connman_ipconfig_load(service->ipconfig_ipv6, keyfile,
1254 service->identifier, "IPv6.");
1256 service->nameservers_config = g_key_file_get_string_list(keyfile,
1257 service->identifier, "Nameservers", &length, NULL);
1258 if (service->nameservers_config && length == 0) {
1259 g_strfreev(service->nameservers_config);
1260 service->nameservers_config = NULL;
1266 dns_method = g_key_file_get_string(keyfile, service->identifier,
1267 "Nameservers.IPv4method", NULL);
1269 service->dns_config_method_ipv4 = __connman_dnsconfig_string2method(dns_method);
1273 dns_method = g_key_file_get_string(keyfile, service->identifier,
1274 "Nameservers.IPv6method", NULL);
1276 service->dns_config_method_ipv6 = __connman_dnsconfig_string2method(dns_method);
1281 service->timeservers_config = g_key_file_get_string_list(keyfile,
1282 service->identifier, "Timeservers", &length, NULL);
1283 if (service->timeservers_config && length == 0) {
1284 g_strfreev(service->timeservers_config);
1285 service->timeservers_config = NULL;
1288 service->domains = g_key_file_get_string_list(keyfile,
1289 service->identifier, "Domains", &length, NULL);
1290 if (service->domains && length == 0) {
1291 g_strfreev(service->domains);
1292 service->domains = NULL;
1295 str = g_key_file_get_string(keyfile,
1296 service->identifier, "Proxy.Method", NULL);
1298 service->proxy_config = string2proxymethod(str);
1302 service->proxies = g_key_file_get_string_list(keyfile,
1303 service->identifier, "Proxy.Servers", &length, NULL);
1304 if (service->proxies && length == 0) {
1305 g_strfreev(service->proxies);
1306 service->proxies = NULL;
1309 service->excludes = g_key_file_get_string_list(keyfile,
1310 service->identifier, "Proxy.Excludes", &length, NULL);
1311 if (service->excludes && length == 0) {
1312 g_strfreev(service->excludes);
1313 service->excludes = NULL;
1316 str = g_key_file_get_string(keyfile,
1317 service->identifier, "Proxy.URL", NULL);
1319 g_free(service->pac);
1323 service->mdns_config = g_key_file_get_boolean(keyfile,
1324 service->identifier, "mDNS", NULL);
1326 service->hidden_service = g_key_file_get_boolean(keyfile,
1327 service->identifier, "Hidden", NULL);
1329 #if defined TIZEN_EXT
1330 if ((service->type == CONNMAN_SERVICE_TYPE_WIFI &&
1331 service->security == CONNMAN_SERVICE_SECURITY_8021X)
1332 #if defined TIZEN_EXT_EAP_ON_ETHERNET
1333 || (service->type == CONNMAN_SERVICE_TYPE_ETHERNET && service->use_eapol)
1336 str = g_key_file_get_string(keyfile,
1337 service->identifier, "EAP", NULL);
1339 g_free(service->eap);
1343 str = g_key_file_get_string(keyfile,
1344 service->identifier, "Phase2", NULL);
1346 g_free(service->phase2);
1347 service->phase2 = str;
1350 str = g_key_file_get_string(keyfile,
1351 service->identifier, "Identity", NULL);
1353 g_free(service->identity);
1354 service->identity = str;
1357 #if defined TIZEN_EXT_EAP_ON_ETHERNET
1358 str = g_key_file_get_string(keyfile,
1359 service->identifier, "AnonymousIdentity", NULL);
1361 g_free(service->anonymous_identity);
1362 service->anonymous_identity = str;
1365 str = g_key_file_get_string(keyfile,
1366 service->identifier, "CACertFile", NULL);
1368 g_free(service->ca_cert_file);
1369 service->ca_cert_file = str;
1372 str = g_key_file_get_string(keyfile,
1373 service->identifier, "ClientCertFile", NULL);
1375 g_free(service->client_cert_file);
1376 service->client_cert_file = str;
1379 str = g_key_file_get_string(keyfile,
1380 service->identifier, "PrivateKeyFile", NULL);
1382 g_free(service->private_key_file);
1383 service->private_key_file = str;
1386 str = g_key_file_get_string(keyfile,
1387 service->identifier, "PrivateKeyPassphrase", NULL);
1389 g_free(service->private_key_passphrase);
1390 service->private_key_passphrase = str;
1393 #if defined TIZEN_EXT_EAP_ON_ETHERNET
1394 str = g_key_file_get_string(keyfile,
1395 service->identifier, "Phase1", NULL);
1397 g_free(service->phase1);
1398 service->phase1 = str;
1401 str = g_key_file_get_string(keyfile,
1402 service->identifier, "PacFile", NULL);
1404 g_free(service->pac_file);
1405 service->pac_file = str;
1410 #if defined TIZEN_EXT
1411 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
1412 service->security == CONNMAN_SERVICE_SECURITY_DPP) {
1413 str = g_key_file_get_string(keyfile,
1414 service->identifier, "Connector", NULL);
1416 g_free(service->connector);
1417 service->connector = str;
1419 str = g_key_file_get_string(keyfile,
1420 service->identifier, "CSignKey", NULL);
1422 g_free(service->c_sign_key);
1423 service->c_sign_key = str;
1425 str = g_key_file_get_string(keyfile,
1426 service->identifier, "NetAccessKey", NULL);
1428 g_free(service->net_access_key);
1429 service->net_access_key = str;
1435 g_key_file_free(keyfile);
1440 static int service_save(struct connman_service *service)
1445 const char *cst_str = NULL;
1448 DBG("service %p new %d", service, service->new_service);
1450 if (service->new_service)
1453 keyfile = g_key_file_new();
1458 g_key_file_set_string(keyfile, service->identifier,
1459 "Name", service->name);
1461 switch (service->type) {
1462 case CONNMAN_SERVICE_TYPE_UNKNOWN:
1463 case CONNMAN_SERVICE_TYPE_SYSTEM:
1464 case CONNMAN_SERVICE_TYPE_GPS:
1465 case CONNMAN_SERVICE_TYPE_P2P:
1466 #if defined TIZEN_EXT_WIFI_MESH
1467 case CONNMAN_SERVICE_TYPE_MESH:
1470 case CONNMAN_SERVICE_TYPE_VPN:
1471 g_key_file_set_boolean(keyfile, service->identifier,
1472 "SplitRouting", service->do_split_routing);
1473 if (service->favorite)
1474 g_key_file_set_boolean(keyfile, service->identifier,
1475 "AutoConnect", service->autoconnect);
1477 case CONNMAN_SERVICE_TYPE_WIFI:
1478 if (service->network) {
1479 const unsigned char *ssid;
1480 unsigned int ssid_len = 0;
1481 #if defined TIZEN_EXT_INS
1482 GHashTable *assoc_reject_table;
1485 ssid = connman_network_get_blob(service->network,
1486 "WiFi.SSID", &ssid_len);
1488 if (ssid && ssid_len > 0 && ssid[0] != '\0') {
1489 char *identifier = service->identifier;
1493 ssid_str = g_string_sized_new(ssid_len * 2);
1499 for (i = 0; i < ssid_len; i++)
1500 g_string_append_printf(ssid_str,
1503 g_key_file_set_string(keyfile, identifier,
1504 "SSID", ssid_str->str);
1506 g_string_free(ssid_str, TRUE);
1509 freq = connman_network_get_frequency(service->network);
1510 g_key_file_set_integer(keyfile, service->identifier,
1513 #if defined TIZEN_EXT_INS
1514 /* Last connected BSSID */
1515 if (memcmp(service->last_connected_bssid, invalid_bssid, WIFI_BSSID_LEN_MAX)) {
1516 char *identifier = service->identifier;
1520 bssid_str = g_string_sized_new(18);
1526 for (i = 0; i < WIFI_BSSID_LEN_MAX; i++) {
1527 g_string_append_printf(bssid_str,
1528 "%02x", service->last_connected_bssid[i]);
1529 if (i < WIFI_BSSID_LEN_MAX - 1)
1530 g_string_append(bssid_str, ":");
1533 g_key_file_set_string(keyfile, identifier,
1534 "LastConnectedBSSID", bssid_str->str);
1536 DBG("last connected bssid[%s]", bssid_str->str);
1538 g_string_free(bssid_str, TRUE);
1542 assoc_reject_table = connman_network_get_assoc_reject_table(service->network);
1543 if (assoc_reject_table && g_hash_table_size(assoc_reject_table) > 0) {
1544 GString *assoc_reject_str;
1545 char **assoc_reject_list;
1546 guint assoc_reject_len;
1548 assoc_reject_str = g_string_new(NULL);
1549 if (!assoc_reject_str) {
1554 g_hash_table_foreach(assoc_reject_table, save_assoc_reject, assoc_reject_str);
1556 assoc_reject_list = g_strsplit_set(assoc_reject_str->str, " ", 0);
1557 assoc_reject_len = g_strv_length(assoc_reject_list);
1559 g_key_file_set_string_list(keyfile, service->identifier,
1560 "AssocReject", (const gchar **)assoc_reject_list, assoc_reject_len);
1562 DBG("assoc reject table [%d]", assoc_reject_len);
1564 g_strfreev(assoc_reject_list);
1565 g_string_free(assoc_reject_str, TRUE);
1567 g_key_file_remove_key(keyfile, service->identifier, "AssocReject", NULL);
1569 /* Internet connection */
1570 g_key_file_set_boolean(keyfile, service->identifier,
1571 "InternetConnection", service->is_internet_connection);
1573 DBG("internet connection [%s]", service->is_internet_connection ? "true" : "false");
1575 #endif /* defined TIZEN_EXT_INS */
1579 case CONNMAN_SERVICE_TYPE_GADGET:
1580 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
1581 case CONNMAN_SERVICE_TYPE_CELLULAR:
1582 g_key_file_set_boolean(keyfile, service->identifier,
1583 "Favorite", service->favorite);
1587 case CONNMAN_SERVICE_TYPE_ETHERNET:
1588 if (service->favorite)
1589 g_key_file_set_boolean(keyfile, service->identifier,
1590 "AutoConnect", service->autoconnect);
1591 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
1592 g_key_file_set_boolean(keyfile, service->identifier,
1593 "UseEapol", service->use_eapol);
1598 str = util_timeval_to_iso8601(&service->modified);
1600 g_key_file_set_string(keyfile, service->identifier,
1605 if (service->passphrase && strlen(service->passphrase) > 0) {
1606 char *enc = g_strescape(service->passphrase, NULL);
1607 g_key_file_set_string(keyfile, service->identifier,
1612 if (service->ipconfig_ipv4)
1613 __connman_ipconfig_save(service->ipconfig_ipv4, keyfile,
1614 service->identifier, "IPv4.");
1616 if (service->ipconfig_ipv6)
1617 __connman_ipconfig_save(service->ipconfig_ipv6, keyfile,
1618 service->identifier, "IPv6.");
1620 if (service->nameservers_config) {
1621 guint len = g_strv_length(service->nameservers_config);
1623 g_key_file_set_string_list(keyfile, service->identifier,
1625 (const gchar **) service->nameservers_config, len);
1628 #if defined TIZEN_EXT
1629 if(service->dns_config_method_ipv4 != 0) {
1631 method = __connman_dnsconfig_method2string(
1632 service->dns_config_method_ipv4);
1633 g_key_file_set_string(keyfile, service->identifier,
1634 "Nameservers.IPv4method", method);
1636 g_key_file_remove_key(keyfile, service->identifier,
1637 "Nameservers.IPv4method", NULL);
1639 if(service->dns_config_method_ipv6 != 0) {
1641 method = __connman_dnsconfig_method2string(
1642 service->dns_config_method_ipv6);
1643 g_key_file_set_string(keyfile, service->identifier,
1644 "Nameservers.IPv6method", method);
1646 g_key_file_remove_key(keyfile, service->identifier,
1647 "Nameservers.IPv6method", NULL);
1650 if (service->timeservers_config) {
1651 guint len = g_strv_length(service->timeservers_config);
1653 g_key_file_set_string_list(keyfile, service->identifier,
1655 (const gchar **) service->timeservers_config, len);
1658 if (service->domains) {
1659 guint len = g_strv_length(service->domains);
1661 g_key_file_set_string_list(keyfile, service->identifier,
1663 (const gchar **) service->domains, len);
1666 cst_str = proxymethod2string(service->proxy_config);
1668 g_key_file_set_string(keyfile, service->identifier,
1669 "Proxy.Method", cst_str);
1671 if (service->proxies) {
1672 guint len = g_strv_length(service->proxies);
1674 g_key_file_set_string_list(keyfile, service->identifier,
1676 (const gchar **) service->proxies, len);
1679 if (service->excludes) {
1680 guint len = g_strv_length(service->excludes);
1682 g_key_file_set_string_list(keyfile, service->identifier,
1684 (const gchar **) service->excludes, len);
1687 if (service->pac && strlen(service->pac) > 0)
1688 g_key_file_set_string(keyfile, service->identifier,
1689 "Proxy.URL", service->pac);
1691 if (service->mdns_config)
1692 g_key_file_set_boolean(keyfile, service->identifier,
1695 if (service->hidden_service)
1696 g_key_file_set_boolean(keyfile, service->identifier,
1699 if (service->config_file && strlen(service->config_file) > 0)
1700 g_key_file_set_string(keyfile, service->identifier,
1701 "Config.file", service->config_file);
1703 if (service->config_entry && strlen(service->config_entry) > 0)
1704 g_key_file_set_string(keyfile, service->identifier,
1705 "Config.ident", service->config_entry);
1707 #if defined TIZEN_EXT
1708 if ((service->type == CONNMAN_SERVICE_TYPE_WIFI &&
1709 service->security == CONNMAN_SERVICE_SECURITY_8021X)
1710 #if defined TIZEN_EXT_EAP_ON_ETHERNET
1711 || (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
1714 if (service->eap != NULL && strlen(service->eap) > 0)
1715 g_key_file_set_string(keyfile, service->identifier,
1716 "EAP", service->eap);
1718 g_key_file_remove_key(keyfile, service->identifier,
1721 if (service->phase2 != NULL && strlen(service->phase2) > 0)
1722 g_key_file_set_string(keyfile, service->identifier,
1723 "Phase2", service->phase2);
1725 g_key_file_remove_key(keyfile, service->identifier,
1728 if (service->identity != NULL && strlen(service->identity) > 0)
1729 g_key_file_set_string(keyfile, service->identifier,
1730 "Identity", service->identity);
1732 g_key_file_remove_key(keyfile, service->identifier,
1734 #if defined TIZEN_EXT_EAP_ON_ETHERNET
1735 if (service->anonymous_identity != NULL && strlen(service->anonymous_identity) > 0)
1736 g_key_file_set_string(keyfile, service->identifier,
1737 "AnonymousIdentity", service->anonymous_identity);
1739 g_key_file_remove_key(keyfile, service->identifier,
1740 "AnonymousIdentity", NULL);
1743 if (service->ca_cert_file != NULL && strlen(service->ca_cert_file) > 0)
1744 g_key_file_set_string(keyfile, service->identifier,
1745 "CACertFile", service->ca_cert_file);
1747 g_key_file_remove_key(keyfile, service->identifier,
1748 "CACertFile", NULL);
1750 if (service->client_cert_file != NULL && strlen(service->client_cert_file) > 0)
1751 g_key_file_set_string(keyfile, service->identifier,
1752 "ClientCertFile", service->client_cert_file);
1754 g_key_file_remove_key(keyfile, service->identifier,
1755 "ClientCertFile", NULL);
1757 if (service->private_key_file != NULL && strlen(service->private_key_file) > 0)
1758 g_key_file_set_string(keyfile, service->identifier,
1759 "PrivateKeyFile", service->private_key_file);
1761 g_key_file_remove_key(keyfile, service->identifier,
1762 "PrivateKeyFile", NULL);
1764 if (service->private_key_passphrase != NULL && strlen(service->private_key_passphrase) > 0)
1765 g_key_file_set_string(keyfile, service->identifier,
1766 "PrivateKeyPassphrase", service->private_key_passphrase);
1768 g_key_file_remove_key(keyfile, service->identifier,
1769 "PrivateKeyPassphrase", NULL);
1770 #if defined TIZEN_EXT_EAP_ON_ETHERNET
1771 if (service->phase1 != NULL && strlen(service->phase1) > 0)
1772 g_key_file_set_string(keyfile, service->identifier,
1773 "Phase1", service->phase1);
1775 g_key_file_remove_key(keyfile, service->identifier,
1777 if (service->pac_file != NULL && strlen(service->pac_file) > 0)
1778 g_key_file_set_string(keyfile, service->identifier,
1779 "PacFile", service->pac_file);
1781 g_key_file_remove_key(keyfile, service->identifier,
1786 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
1787 service->security == CONNMAN_SERVICE_SECURITY_DPP) {
1788 if (service->connector != NULL && strlen(service->connector) > 0)
1789 g_key_file_set_string(keyfile, service->identifier,
1790 "Connector", service->connector);
1792 g_key_file_remove_key(keyfile, service->identifier,
1795 if (service->c_sign_key != NULL && strlen(service->c_sign_key) > 0)
1796 g_key_file_set_string(keyfile, service->identifier,
1797 "CSignKey", service->c_sign_key);
1799 g_key_file_remove_key(keyfile, service->identifier,
1802 if (service->net_access_key != NULL && strlen(service->net_access_key) > 0)
1803 g_key_file_set_string(keyfile, service->identifier,
1804 "NetAccessKey", service->net_access_key);
1806 g_key_file_remove_key(keyfile, service->identifier,
1807 "NetAccessKey", NULL);
1812 __connman_storage_save_service(keyfile, service->identifier);
1814 g_key_file_free(keyfile);
1819 #if defined TIZEN_EXT
1820 static gint sort_entry(gconstpointer a, gconstpointer b, gpointer user_data)
1822 GTimeVal *aval = (GTimeVal *)a;
1823 GTimeVal *bval = (GTimeVal *)b;
1825 /* Note that the sort order is ascending */
1826 if (aval->tv_sec > bval->tv_sec)
1829 if (aval->tv_sec < bval->tv_sec)
1835 static void free_entry(gpointer data)
1837 struct saved_profiles *entry = data;
1838 g_free(entry->profile_name);
1842 static void __connman_manage_saved_profiles()
1845 gchar **services = NULL;
1847 int i, num_profiles = 0;
1848 GSequenceIter *iter;
1849 GSequence *profile_list;
1850 struct saved_profiles *entry;
1852 profile_list = g_sequence_new(free_entry);
1856 services = connman_storage_get_services();
1858 /* Check the count of saved profiles */
1859 for (i = 0; services && services[i]; i++) {
1860 if (strncmp(services[i], "wifi_", 5) != 0)
1863 keyfile = connman_storage_load_service(services[i]);
1867 gchar *str = g_key_file_get_string(keyfile,
1868 services[i], "Modified", NULL);
1870 g_key_file_free(keyfile);
1874 g_time_val_from_iso8601(str, &modified);
1877 entry = g_try_new(struct saved_profiles, 1);
1879 g_sequence_free(profile_list);
1880 g_key_file_free(keyfile);
1881 g_strfreev(services);
1885 entry->modified = modified;
1886 entry->profile_name = g_strdup(services[i]);
1888 g_sequence_insert_sorted(profile_list, entry,
1893 DBG("number of profiles: %d", num_profiles);
1895 if (num_profiles > MAX_WIFI_PROFILES) {
1896 iter = g_sequence_get_begin_iter(profile_list);
1898 entry = g_sequence_get(iter);
1900 if (__connman_storage_remove_service(entry->profile_name) == false)
1901 DBG("Failed to remove service profile: %s", entry->profile_name);
1904 g_sequence_free(profile_list);
1905 g_strfreev(services);
1909 void __connman_service_save(struct connman_service *service)
1914 service_save(service);
1915 #if defined TIZEN_EXT
1917 * Description: Manage the wireless profiles saved in connman.
1918 * If the number of saved profiles is more than 200, remove the
1919 * profile that is not updated for longer duration.
1921 __connman_manage_saved_profiles();
1925 static enum connman_service_state combine_state(
1926 enum connman_service_state state_a,
1927 enum connman_service_state state_b)
1929 enum connman_service_state result;
1931 if (state_a == state_b) {
1936 if (state_a == CONNMAN_SERVICE_STATE_UNKNOWN) {
1941 if (state_b == CONNMAN_SERVICE_STATE_UNKNOWN) {
1946 if (state_a == CONNMAN_SERVICE_STATE_IDLE) {
1951 if (state_b == CONNMAN_SERVICE_STATE_IDLE) {
1956 if (state_a == CONNMAN_SERVICE_STATE_ONLINE) {
1961 if (state_b == CONNMAN_SERVICE_STATE_ONLINE) {
1966 if (state_a == CONNMAN_SERVICE_STATE_READY) {
1971 if (state_b == CONNMAN_SERVICE_STATE_READY) {
1976 if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION) {
1981 if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION) {
1986 if (state_a == CONNMAN_SERVICE_STATE_ASSOCIATION) {
1991 if (state_b == CONNMAN_SERVICE_STATE_ASSOCIATION) {
1996 if (state_a == CONNMAN_SERVICE_STATE_DISCONNECT) {
2001 if (state_b == CONNMAN_SERVICE_STATE_DISCONNECT) {
2006 result = CONNMAN_SERVICE_STATE_FAILURE;
2012 static bool is_connecting(enum connman_service_state state)
2015 case CONNMAN_SERVICE_STATE_UNKNOWN:
2016 case CONNMAN_SERVICE_STATE_IDLE:
2017 case CONNMAN_SERVICE_STATE_FAILURE:
2018 case CONNMAN_SERVICE_STATE_DISCONNECT:
2019 case CONNMAN_SERVICE_STATE_READY:
2020 case CONNMAN_SERVICE_STATE_ONLINE:
2022 case CONNMAN_SERVICE_STATE_ASSOCIATION:
2023 case CONNMAN_SERVICE_STATE_CONFIGURATION:
2030 static bool is_connected(enum connman_service_state state)
2033 case CONNMAN_SERVICE_STATE_UNKNOWN:
2034 case CONNMAN_SERVICE_STATE_IDLE:
2035 case CONNMAN_SERVICE_STATE_ASSOCIATION:
2036 case CONNMAN_SERVICE_STATE_CONFIGURATION:
2037 case CONNMAN_SERVICE_STATE_DISCONNECT:
2038 case CONNMAN_SERVICE_STATE_FAILURE:
2040 case CONNMAN_SERVICE_STATE_READY:
2041 case CONNMAN_SERVICE_STATE_ONLINE:
2048 static bool is_idle(enum connman_service_state state)
2051 case CONNMAN_SERVICE_STATE_IDLE:
2052 case CONNMAN_SERVICE_STATE_DISCONNECT:
2053 case CONNMAN_SERVICE_STATE_FAILURE:
2055 case CONNMAN_SERVICE_STATE_UNKNOWN:
2056 case CONNMAN_SERVICE_STATE_ASSOCIATION:
2057 case CONNMAN_SERVICE_STATE_CONFIGURATION:
2058 case CONNMAN_SERVICE_STATE_READY:
2059 case CONNMAN_SERVICE_STATE_ONLINE:
2066 static int nameservers_changed_cb(void *user_data)
2068 struct connman_service *service = user_data;
2070 DBG("service %p", service);
2072 service->nameservers_timeout = 0;
2073 if ((is_idle(service->state) && !service->nameservers) ||
2074 is_connected(service->state))
2075 dns_changed(service);
2080 static void nameservers_changed(struct connman_service *service)
2082 if (!service->nameservers_timeout)
2083 service->nameservers_timeout = g_idle_add(nameservers_changed_cb,
2087 static bool nameserver_available(struct connman_service *service,
2088 enum connman_ipconfig_type type,
2093 family = connman_inet_check_ipaddress(ns);
2095 if (family == AF_INET) {
2096 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
2099 return is_connected(service->state_ipv4);
2102 if (family == AF_INET6) {
2103 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
2106 return is_connected(service->state_ipv6);
2112 static int searchdomain_add_all(struct connman_service *service)
2116 if (!is_connected(service->state))
2119 index = __connman_service_get_index(service);
2123 if (service->domains) {
2124 while (service->domains[i]) {
2125 connman_resolver_append(index, service->domains[i],
2133 if (service->domainname)
2134 connman_resolver_append(index, service->domainname, NULL);
2140 static int searchdomain_remove_all(struct connman_service *service)
2144 if (!is_connected(service->state))
2147 index = __connman_service_get_index(service);
2151 while (service->domains && service->domains[i]) {
2152 connman_resolver_remove(index, service->domains[i], NULL);
2156 if (service->domainname)
2157 connman_resolver_remove(index, service->domainname, NULL);
2162 static int nameserver_add(struct connman_service *service,
2163 enum connman_ipconfig_type type,
2164 const char *nameserver)
2168 if (!nameserver_available(service, type, nameserver))
2171 index = __connman_service_get_index(service);
2175 #if defined TIZEN_EXT
2176 DBG("Resolver append nameserver: %s", nameserver);
2178 ret = connman_resolver_append(index, NULL, nameserver);
2180 nameservers_changed(service);
2185 static int nameserver_add_all(struct connman_service *service,
2186 enum connman_ipconfig_type type)
2190 if (service->nameservers_config) {
2191 while (service->nameservers_config[i]) {
2192 #if defined TIZEN_EXT
2193 DBG("type %d add service->nameservers_config[%d]:%s",type,
2194 i, service->nameservers_config[i]);
2195 if(strncmp(service->nameservers_config[i], "::", 2) == 0) {
2196 DBG("Invalid nameserver");
2202 case CONNMAN_IPCONFIG_TYPE_IPV4:
2203 if (connman_inet_check_ipaddress(
2204 service->nameservers_config[i]) == AF_INET &&
2205 service->dns_config_method_ipv4 ==
2206 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2207 nameserver_add(service, type,
2208 service->nameservers_config[i]);
2211 case CONNMAN_IPCONFIG_TYPE_IPV6:
2212 if (connman_inet_check_ipaddress(
2213 service->nameservers_config[i]) == AF_INET6 &&
2214 service->dns_config_method_ipv6 ==
2215 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2216 nameserver_add(service, type,
2217 service->nameservers_config[i]);
2220 case CONNMAN_IPCONFIG_TYPE_ALL:
2221 if (connman_inet_check_ipaddress(
2222 service->nameservers_config[i]) == AF_INET &&
2223 service->dns_config_method_ipv4 ==
2224 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2225 nameserver_add(service, type,
2226 service->nameservers_config[i]);
2228 if (connman_inet_check_ipaddress(
2229 service->nameservers_config[i]) == AF_INET6 &&
2230 service->dns_config_method_ipv6 ==
2231 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2232 nameserver_add(service, type,
2233 service->nameservers_config[i]);
2236 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2237 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
2240 DBG("default case do nothing");
2244 nameserver_add(service, type,
2245 service->nameservers_config[i]);
2249 } else if (service->nameservers) {
2250 while (service->nameservers[i]) {
2251 #if defined TIZEN_EXT
2252 DBG("type %d service->nameservers[%d]: %s",type,
2253 i, service->nameservers[i]);
2256 case CONNMAN_IPCONFIG_TYPE_IPV4:
2257 if (connman_inet_check_ipaddress(
2258 service->nameservers[i]) == AF_INET &&
2259 service->dns_config_method_ipv4 ==
2260 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2261 nameserver_add(service, type,
2262 service->nameservers[i]);
2265 case CONNMAN_IPCONFIG_TYPE_IPV6:
2266 if (connman_inet_check_ipaddress(
2267 service->nameservers[i]) == AF_INET6 &&
2268 service->dns_config_method_ipv6 ==
2269 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2270 nameserver_add(service, type,
2271 service->nameservers[i]);
2274 case CONNMAN_IPCONFIG_TYPE_ALL:
2275 if (connman_inet_check_ipaddress(
2276 service->nameservers[i]) == AF_INET &&
2277 service->dns_config_method_ipv4 ==
2278 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2279 nameserver_add(service, type,
2280 service->nameservers[i]);
2282 if (connman_inet_check_ipaddress(
2283 service->nameservers[i]) == AF_INET6 &&
2284 service->dns_config_method_ipv6 ==
2285 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2286 nameserver_add(service, type,
2287 service->nameservers[i]);
2290 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2291 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
2294 DBG("default case do nothing");
2298 nameserver_add(service, type,
2299 service->nameservers[i]);
2306 __connman_resolver_append_fallback_nameservers();
2308 #if defined TIZEN_EXT
2309 const char *global_dns = connman_setting_get_string("GlobalNameserver");
2311 nameserver_add(service, type, global_dns);
2314 searchdomain_add_all(service);
2319 static int nameserver_remove(struct connman_service *service,
2320 enum connman_ipconfig_type type,
2321 const char *nameserver)
2325 if (!nameserver_available(service, type, nameserver))
2328 index = __connman_service_get_index(service);
2332 #if defined TIZEN_EXT
2333 DBG("Resolver remove nameserver: %s", nameserver);
2335 ret = connman_resolver_remove(index, NULL, nameserver);
2337 nameservers_changed(service);
2342 static int nameserver_remove_all(struct connman_service *service,
2343 enum connman_ipconfig_type type)
2345 #if defined TIZEN_EXT
2347 * Skip this function if there is any connected profiles
2348 * that use same interface
2350 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
2351 __connman_service_get_connected_count_of_iface(service) > 0)
2356 index = __connman_service_get_index(service);
2360 while (service->nameservers_config && service->nameservers_config[i]) {
2362 #if defined TIZEN_EXT
2363 DBG("type %d Remove service->nameservers_config[%d]: %s",
2364 type, i, service->nameservers_config[i]);
2366 case CONNMAN_IPCONFIG_TYPE_IPV4:
2367 if (connman_inet_check_ipaddress(
2368 service->nameservers_config[i]) == AF_INET &&
2369 (service->dns_config_method_ipv4 ==
2370 CONNMAN_DNSCONFIG_METHOD_DHCP ||
2371 service->dns_config_method_ipv4 ==
2372 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
2373 nameserver_remove(service, type,
2374 service->nameservers_config[i]);
2377 case CONNMAN_IPCONFIG_TYPE_IPV6:
2378 if (connman_inet_check_ipaddress(
2379 service->nameservers_config[i]) == AF_INET6 &&
2380 (service->dns_config_method_ipv6 ==
2381 CONNMAN_DNSCONFIG_METHOD_DHCP ||
2382 service->dns_config_method_ipv6 ==
2383 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
2384 nameserver_remove(service, type,
2385 service->nameservers_config[i]);
2388 case CONNMAN_IPCONFIG_TYPE_ALL:
2389 if (connman_inet_check_ipaddress(
2390 service->nameservers_config[i]) == AF_INET &&
2391 (service->dns_config_method_ipv4 ==
2392 CONNMAN_DNSCONFIG_METHOD_DHCP ||
2393 service->dns_config_method_ipv4 ==
2394 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
2395 nameserver_remove(service, type,
2396 service->nameservers_config[i]);
2398 if (connman_inet_check_ipaddress(
2399 service->nameservers_config[i]) == AF_INET6 &&
2400 (service->dns_config_method_ipv6 ==
2401 CONNMAN_DNSCONFIG_METHOD_DHCP ||
2402 service->dns_config_method_ipv6 ==
2403 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
2404 nameserver_remove(service, type,
2405 service->nameservers_config[i]);
2408 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2409 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
2412 DBG("default case do nothing");
2416 nameserver_remove(service, type,
2417 service->nameservers_config[i]);
2423 while (service->nameservers && service->nameservers[i]) {
2424 #if defined TIZEN_EXT
2425 DBG("type %d Remove service->nameservers[%d]: %s",type, i,
2426 service->nameservers[i]);
2428 case CONNMAN_IPCONFIG_TYPE_IPV4:
2429 if (connman_inet_check_ipaddress(
2430 service->nameservers[i]) == AF_INET &&
2431 (service->dns_config_method_ipv4 ==
2432 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
2433 service->dns_config_method_ipv4 ==
2434 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
2435 nameserver_remove(service, type,
2436 service->nameservers[i]);
2439 case CONNMAN_IPCONFIG_TYPE_IPV6:
2440 if (connman_inet_check_ipaddress(
2441 service->nameservers[i]) == AF_INET6 &&
2442 (service->dns_config_method_ipv6 ==
2443 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
2444 service->dns_config_method_ipv6 ==
2445 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
2446 nameserver_remove(service, type,
2447 service->nameservers[i]);
2450 case CONNMAN_IPCONFIG_TYPE_ALL:
2451 if (connman_inet_check_ipaddress(
2452 service->nameservers[i]) == AF_INET &&
2453 (service->dns_config_method_ipv4 ==
2454 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
2455 service->dns_config_method_ipv4 ==
2456 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
2457 nameserver_remove(service, type,
2458 service->nameservers[i]);
2460 if (connman_inet_check_ipaddress(
2461 service->nameservers[i]) == AF_INET6 &&
2462 (service->dns_config_method_ipv6 ==
2463 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
2464 service->dns_config_method_ipv6 ==
2465 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
2466 nameserver_remove(service, type,
2467 service->nameservers[i]);
2470 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
2471 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
2474 DBG("default case do nothing");
2478 nameserver_remove(service, type, service->nameservers[i]);
2483 #if defined TIZEN_EXT
2484 const char *global_dns = connman_setting_get_string("GlobalNameserver");
2486 nameserver_remove(service, type, global_dns);
2488 searchdomain_remove_all(service);
2494 * The is_auto variable is set to true when IPv6 autoconf nameservers are
2495 * inserted to resolver via netlink message (see rtnl.c:rtnl_newnduseropt()
2496 * for details) and not through service.c
2498 #if defined TIZEN_EXT
2499 int __connman_service_nameserver_append(struct connman_service *service,
2500 const char *nameserver, bool is_auto,
2501 enum connman_ipconfig_type type)
2503 int __connman_service_nameserver_append(struct connman_service *service,
2504 const char *nameserver, bool is_auto)
2510 DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
2516 nameservers = service->nameservers_auto;
2518 nameservers = service->nameservers;
2521 for (i = 0; nameservers[i]; i++) {
2522 #if defined TIZEN_EXT
2523 DBG("nameservers[%d] %s, nameserver %s", i, nameservers[i], nameserver);
2525 if (g_strcmp0(nameservers[i], nameserver) == 0)
2529 len = g_strv_length(nameservers);
2530 nameservers = g_try_renew(char *, nameservers, len + 2);
2533 nameservers = g_try_new0(char *, len + 2);
2539 nameservers[len] = g_strdup(nameserver);
2540 nameservers[len + 1] = NULL;
2543 if(type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
2544 service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
2545 service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
2547 if(type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
2548 service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
2549 service->dns_config_method_ipv6 = CONNMAN_DNSCONFIG_METHOD_DHCP;
2553 service->nameservers_auto = nameservers;
2555 service->nameservers = nameservers;
2556 nameserver_add(service, CONNMAN_IPCONFIG_TYPE_ALL, nameserver);
2559 nameservers_changed(service);
2561 searchdomain_add_all(service);
2566 #if defined TIZEN_EXT
2567 int __connman_service_nameserver_remove(struct connman_service *service,
2568 const char *nameserver, bool is_auto,
2569 enum connman_ipconfig_type type)
2571 int __connman_service_nameserver_remove(struct connman_service *service,
2572 const char *nameserver, bool is_auto)
2575 char **servers, **nameservers;
2579 DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
2585 nameservers = service->nameservers_auto;
2587 nameservers = service->nameservers;
2592 for (i = 0; nameservers[i]; i++)
2593 if (g_strcmp0(nameservers[i], nameserver) == 0) {
2601 len = g_strv_length(nameservers);
2608 servers = g_try_new0(char *, len);
2612 for (i = 0, j = 0; i < len; i++) {
2613 if (g_strcmp0(nameservers[i], nameserver)) {
2614 servers[j] = nameservers[i];
2617 g_free(nameservers[i]);
2619 nameservers[i] = NULL;
2621 servers[len - 1] = NULL;
2624 g_strfreev(nameservers);
2625 nameservers = servers;
2628 service->nameservers_auto = nameservers;
2630 service->nameservers = nameservers;
2631 #if defined TIZEN_EXT
2632 DBG("nameserver remove ip_type: %d", type);
2633 nameserver_remove(service, type,
2636 nameserver_remove(service, CONNMAN_IPCONFIG_TYPE_ALL,
2644 void __connman_service_nameserver_clear(struct connman_service *service)
2646 nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
2648 g_strfreev(service->nameservers);
2649 service->nameservers = NULL;
2651 nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
2654 static void add_nameserver_route(int family, int index, char *nameserver,
2659 if (connman_inet_compare_subnet(index, nameserver))
2662 if (connman_inet_add_host_route(index, nameserver, gw) < 0)
2663 /* For P-t-P link the above route add will fail */
2664 connman_inet_add_host_route(index, nameserver, NULL);
2668 if (connman_inet_add_ipv6_host_route(index, nameserver,
2670 connman_inet_add_ipv6_host_route(index, nameserver,
2676 static void nameserver_add_routes(int index, char **nameservers,
2679 int i, ns_family, gw_family;
2681 gw_family = connman_inet_check_ipaddress(gw);
2685 for (i = 0; nameservers[i]; i++) {
2686 ns_family = connman_inet_check_ipaddress(nameservers[i]);
2687 if (ns_family < 0 || ns_family != gw_family)
2690 add_nameserver_route(ns_family, index, nameservers[i], gw);
2694 static void nameserver_del_routes(int index, char **nameservers,
2695 enum connman_ipconfig_type type)
2699 for (i = 0; nameservers[i]; i++) {
2700 family = connman_inet_check_ipaddress(nameservers[i]);
2706 if (type != CONNMAN_IPCONFIG_TYPE_IPV6)
2707 connman_inet_del_host_route(index,
2711 if (type != CONNMAN_IPCONFIG_TYPE_IPV4)
2712 connman_inet_del_ipv6_host_route(index,
2719 void __connman_service_nameserver_add_routes(struct connman_service *service,
2727 index = __connman_service_get_index(service);
2729 if (service->nameservers_config) {
2731 * Configured nameserver takes preference over the
2732 * discoverd nameserver gathered from DHCP, VPN, etc.
2734 nameserver_add_routes(index, service->nameservers_config, gw);
2735 } else if (service->nameservers) {
2737 * We add nameservers host routes for nameservers that
2738 * are not on our subnet. For those who are, the subnet
2739 * route will be installed by the time the dns proxy code
2740 * tries to reach them. The subnet route is installed
2741 * when setting the interface IP address.
2743 nameserver_add_routes(index, service->nameservers, gw);
2747 void __connman_service_nameserver_del_routes(struct connman_service *service,
2748 enum connman_ipconfig_type type)
2755 index = __connman_service_get_index(service);
2757 if (service->nameservers_config)
2758 nameserver_del_routes(index, service->nameservers_config,
2760 else if (service->nameservers)
2761 nameserver_del_routes(index, service->nameservers, type);
2764 static bool check_proxy_setup(struct connman_service *service)
2767 * We start WPAD if we haven't got a PAC URL from DHCP and
2768 * if our proxy manual configuration is either empty or set
2769 * to AUTO with an empty URL.
2772 if (service->proxy != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN)
2775 if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN &&
2776 (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_AUTO ||
2780 if (__connman_wpad_start(service) < 0) {
2781 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
2782 __connman_notifier_proxy_changed(service);
2789 static void cancel_online_check(struct connman_service *service)
2791 if (service->online_timeout == 0)
2794 g_source_remove(service->online_timeout);
2795 service->online_timeout = 0;
2796 connman_service_unref(service);
2799 static void start_online_check(struct connman_service *service,
2800 enum connman_ipconfig_type type)
2802 if (!connman_setting_get_bool("EnableOnlineCheck")) {
2803 connman_info("Online check disabled. "
2804 "Default service remains in READY state.");
2807 enable_online_to_ready_transition =
2808 connman_setting_get_bool("EnableOnlineToReadyTransition");
2809 online_check_initial_interval =
2810 connman_setting_get_uint("OnlineCheckInitialInterval");
2811 online_check_max_interval =
2812 connman_setting_get_uint("OnlineCheckMaxInterval");
2814 if (type != CONNMAN_IPCONFIG_TYPE_IPV4 || check_proxy_setup(service)) {
2815 cancel_online_check(service);
2816 __connman_service_wispr_start(service, type);
2820 static void address_updated(struct connman_service *service,
2821 enum connman_ipconfig_type type)
2823 if (is_connected(service->state) &&
2824 service == connman_service_get_default()) {
2825 nameserver_remove_all(service, type);
2826 nameserver_add_all(service, type);
2827 start_online_check(service, type);
2829 __connman_timeserver_sync(service);
2833 static struct connman_stats *stats_get(struct connman_service *service)
2835 if (service->roaming)
2836 return &service->stats_roaming;
2838 return &service->stats;
2841 static bool stats_enabled(struct connman_service *service)
2843 struct connman_stats *stats = stats_get(service);
2845 return stats->enabled;
2848 static void stats_start(struct connman_service *service)
2850 struct connman_stats *stats = stats_get(service);
2852 DBG("service %p", service);
2857 stats->enabled = true;
2858 stats->data_last.time = stats->data.time;
2860 g_timer_start(stats->timer);
2863 static void stats_stop(struct connman_service *service)
2865 struct connman_stats *stats = stats_get(service);
2866 unsigned int seconds;
2868 DBG("service %p", service);
2873 if (!stats->enabled)
2876 g_timer_stop(stats->timer);
2878 seconds = g_timer_elapsed(stats->timer, NULL);
2879 stats->data.time = stats->data_last.time + seconds;
2881 stats->enabled = false;
2884 static void reset_stats(struct connman_service *service)
2886 DBG("service %p", service);
2889 service->stats.valid = false;
2891 service->stats.data.rx_packets = 0;
2892 service->stats.data.tx_packets = 0;
2893 service->stats.data.rx_bytes = 0;
2894 service->stats.data.tx_bytes = 0;
2895 service->stats.data.rx_errors = 0;
2896 service->stats.data.tx_errors = 0;
2897 service->stats.data.rx_dropped = 0;
2898 service->stats.data.tx_dropped = 0;
2899 service->stats.data.time = 0;
2900 service->stats.data_last.time = 0;
2902 g_timer_reset(service->stats.timer);
2905 service->stats_roaming.valid = false;
2907 service->stats_roaming.data.rx_packets = 0;
2908 service->stats_roaming.data.tx_packets = 0;
2909 service->stats_roaming.data.rx_bytes = 0;
2910 service->stats_roaming.data.tx_bytes = 0;
2911 service->stats_roaming.data.rx_errors = 0;
2912 service->stats_roaming.data.tx_errors = 0;
2913 service->stats_roaming.data.rx_dropped = 0;
2914 service->stats_roaming.data.tx_dropped = 0;
2915 service->stats_roaming.data.time = 0;
2916 service->stats_roaming.data_last.time = 0;
2918 g_timer_reset(service->stats_roaming.timer);
2921 #if defined TIZEN_EXT
2922 static gboolean __connman_service_is_internet_profile(
2923 struct connman_service *cellular)
2925 const char internet_suffix[] = "_1";
2927 DBG("Service path: %s", cellular->path);
2929 if (g_str_has_suffix(cellular->path, internet_suffix) == TRUE)
2935 struct connman_service *connman_service_get_default_connection(void)
2938 struct connman_service *service;
2939 struct connman_service *default_service = NULL;
2941 for (list = service_list; list; list = list->next) {
2942 service = list->data;
2944 DBG("service: %p %s %s %s", service, service->name,
2945 state2string(service->state),
2946 __connman_service_type2string(service->type));
2948 #if defined TIZEN_MAINTAIN_ONLINE
2949 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
2950 service->state == CONNMAN_SERVICE_STATE_ONLINE) {
2952 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
2953 is_connected(service->state) == TRUE) {
2956 } else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
2957 __connman_service_is_internet_profile(service) == TRUE) {
2958 if (default_service == NULL)
2959 default_service = service;
2960 else if (is_connected(service->state) == TRUE &&
2961 is_connected(default_service->state) == FALSE)
2962 default_service = service;
2963 } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET &&
2964 is_connected(service->state) == TRUE) {
2965 if (default_service == NULL)
2966 default_service = service;
2967 } else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH &&
2968 is_connected(service->state) == TRUE) {
2969 if (default_service == NULL)
2970 default_service = service;
2974 return default_service;
2977 struct connman_service *connman_service_get_connected_service(const char *ifname)
2980 const char *svc_ifname;
2981 struct connman_service *service;
2986 for (list = service_list; list; list = list->next) {
2987 service = list->data;
2989 if (!is_connected(service->state))
2992 svc_ifname = connman_device_get_string(
2993 connman_network_get_device(service->network), "Interface");
2995 if (svc_ifname && g_strcmp0(svc_ifname, ifname) == 0)
3003 struct connman_service *connman_service_get_default(void)
3005 #if defined TIZEN_MAINTAIN_ONLINE
3006 return connman_service_get_default_connection();
3008 struct connman_service *service;
3013 service = service_list->data;
3015 if (!is_connected(service->state))
3022 bool __connman_service_index_is_default(int index)
3024 struct connman_service *service;
3029 service = connman_service_get_default();
3031 return __connman_service_get_index(service) == index;
3034 static void default_changed(void)
3036 #if defined TIZEN_EXT
3037 struct connman_service *service = connman_service_get_default_connection();
3039 struct connman_service *service = connman_service_get_default();
3042 if (service == current_default)
3045 DBG("current default %p %s", current_default,
3046 current_default ? current_default->identifier : "");
3047 DBG("new default %p %s", service, service ? service->identifier : "");
3049 #if defined TIZEN_EXT
3050 current_default = service;
3052 __connman_service_timeserver_changed(service, NULL);
3054 __connman_service_timeserver_changed(current_default, NULL);
3056 current_default = service;
3060 if (service->hostname &&
3061 connman_setting_get_bool("AllowHostnameUpdates"))
3062 __connman_utsname_set_hostname(service->hostname);
3064 if (service->domainname &&
3065 connman_setting_get_bool("AllowDomainnameUpdates"))
3066 __connman_utsname_set_domainname(service->domainname);
3068 if (__connman_service_is_connected_state(service,
3069 CONNMAN_IPCONFIG_TYPE_IPV4))
3070 __connman_service_wispr_start(service,
3071 CONNMAN_IPCONFIG_TYPE_IPV4);
3073 if (__connman_service_is_connected_state(service,
3074 CONNMAN_IPCONFIG_TYPE_IPV6))
3075 __connman_service_wispr_start(service,
3076 CONNMAN_IPCONFIG_TYPE_IPV6);
3079 * Connect VPN automatically when new default service
3080 * is set and connected, unless new default is VPN
3082 if (is_connected(service->state) &&
3083 service->type != CONNMAN_SERVICE_TYPE_VPN) {
3084 DBG("running vpn_auto_connect");
3089 __connman_notifier_default_changed(service);
3092 #if defined TIZEN_EXT
3093 static void append_struct(gpointer value, gpointer user_data);
3095 static void emit_state_changed_with_properties(struct connman_service *service)
3097 DBusMessage *signal;
3098 DBusMessageIter iter;
3103 signal = dbus_message_new_signal(service->path, CONNMAN_SERVICE_INTERFACE,
3104 "StateChangedProperties");
3108 dbus_message_iter_init_append(signal, &iter);
3109 append_struct(service, &iter);
3111 g_dbus_send_message(connection, signal);
3117 static void state_changed(struct connman_service *service)
3121 __connman_notifier_service_state_changed(service, service->state);
3123 str = state2string(service->state);
3127 #if !defined TIZEN_EXT
3128 if (!allow_property_changed(service))
3131 DBG(" %s, %s", str, service->path);
3134 connman_dbus_property_changed_basic(service->path,
3135 CONNMAN_SERVICE_INTERFACE, "State",
3136 DBUS_TYPE_STRING, &str);
3138 #if defined TIZEN_EXT
3139 emit_state_changed_with_properties(service);
3143 #if defined TIZEN_EXT
3144 static void connect_reason_changed(struct connman_service *service)
3146 #if defined TIZEN_EXT_INS
3147 struct connman_device *device;
3152 if (!allow_property_changed(service))
3155 #if defined TIZEN_EXT_INS
3156 if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
3157 device = connman_network_get_device(service->network);
3159 bool need_save = false;
3161 need_save |= connman_device_set_last_user_selection_ident(device, service->identifier);
3162 need_save |= connman_device_set_last_user_selection_time(device, time(NULL));
3164 DBG("last user selection ident[%s] time[%ld]",
3165 connman_device_get_last_user_selection_ident(device),
3166 connman_device_get_last_user_selection_time(device));
3169 connman_device_save_last_user_selection(device);
3174 connman_dbus_property_changed_basic(service->path,
3175 CONNMAN_SERVICE_INTERFACE,
3178 &service->connect_reason);
3180 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
3182 #if defined TIZEN_EXT
3183 static void disconnection_requested_changed(struct connman_service *service)
3185 dbus_bool_t disconnection_requested;
3190 if (!allow_property_changed(service))
3193 disconnection_requested = service->disconnection_requested;
3194 connman_dbus_property_changed_basic(service->path,
3195 CONNMAN_SERVICE_INTERFACE,
3196 "DisconnectionRequested",
3198 &disconnection_requested);
3201 void connman_service_set_disconnection_requested(struct connman_service *service,
3202 bool disconnection_requested)
3204 if (service == NULL)
3207 service->disconnection_requested = disconnection_requested;
3208 disconnection_requested_changed(service);
3211 static void connman_service_emit_state(struct connman_service *service,
3212 enum connman_service_state state)
3215 enum connman_service_state cur_state = service->state;
3217 if (service->state != state)
3218 service->state = state;
3220 str = state2string(service->state);
3222 service->state = cur_state;
3226 DBG(" %s, %s", str, service->path);
3228 connman_dbus_property_changed_basic(service->path,
3229 CONNMAN_SERVICE_INTERFACE, "State",
3230 DBUS_TYPE_STRING, &str);
3232 emit_state_changed_with_properties(service);
3233 service->state = cur_state;
3236 void connman_service_notify_reconnection(struct connman_service *service)
3241 if (service->state != CONNMAN_SERVICE_STATE_READY &&
3242 service->state != CONNMAN_SERVICE_STATE_ONLINE)
3245 connman_service_emit_state(service, CONNMAN_SERVICE_STATE_CONFIGURATION);
3246 connman_service_emit_state(service, CONNMAN_SERVICE_STATE_READY);
3248 if (service->state == CONNMAN_SERVICE_STATE_ONLINE)
3249 connman_service_emit_state(service, CONNMAN_SERVICE_STATE_ONLINE);
3253 static void strength_changed(struct connman_service *service)
3255 if (service->strength == 0)
3258 if (!allow_property_changed(service))
3261 connman_dbus_property_changed_basic(service->path,
3262 CONNMAN_SERVICE_INTERFACE, "Strength",
3263 DBUS_TYPE_BYTE, &service->strength);
3266 #if defined TIZEN_EXT_INS
3267 static bool update_last_connected_bssid(struct connman_service *service)
3269 const unsigned char *last_connected_bssid;
3271 if (!service->network)
3274 last_connected_bssid = connman_network_get_last_connected_bssid(service->network);
3275 if (memcmp(last_connected_bssid, invalid_bssid, WIFI_BSSID_LEN_MAX) == 0)
3278 if (memcmp(last_connected_bssid, service->last_connected_bssid, WIFI_BSSID_LEN_MAX) != 0) {
3279 memcpy(service->last_connected_bssid, last_connected_bssid, WIFI_BSSID_LEN_MAX);
3287 static void favorite_changed(struct connman_service *service)
3289 dbus_bool_t favorite;
3294 if (!allow_property_changed(service))
3297 favorite = service->favorite;
3298 connman_dbus_property_changed_basic(service->path,
3299 CONNMAN_SERVICE_INTERFACE, "Favorite",
3300 DBUS_TYPE_BOOLEAN, &favorite);
3303 static void immutable_changed(struct connman_service *service)
3305 dbus_bool_t immutable;
3310 if (!allow_property_changed(service))
3313 immutable = service->immutable;
3314 connman_dbus_property_changed_basic(service->path,
3315 CONNMAN_SERVICE_INTERFACE, "Immutable",
3316 DBUS_TYPE_BOOLEAN, &immutable);
3319 static void roaming_changed(struct connman_service *service)
3321 dbus_bool_t roaming;
3326 if (!allow_property_changed(service))
3329 roaming = service->roaming;
3330 connman_dbus_property_changed_basic(service->path,
3331 CONNMAN_SERVICE_INTERFACE, "Roaming",
3332 DBUS_TYPE_BOOLEAN, &roaming);
3335 static void autoconnect_changed(struct connman_service *service)
3337 dbus_bool_t autoconnect;
3342 if (!allow_property_changed(service))
3345 autoconnect = service->autoconnect;
3346 connman_dbus_property_changed_basic(service->path,
3347 CONNMAN_SERVICE_INTERFACE, "AutoConnect",
3348 DBUS_TYPE_BOOLEAN, &autoconnect);
3351 bool connman_service_set_autoconnect(struct connman_service *service,
3354 if (service->autoconnect == autoconnect)
3357 service->autoconnect = autoconnect;
3358 autoconnect_changed(service);
3360 connman_network_set_autoconnect(service->network, autoconnect);
3365 static void append_security(DBusMessageIter *iter, void *user_data)
3367 struct connman_service *service = user_data;
3370 str = security2string(service->security);
3372 dbus_message_iter_append_basic(iter,
3373 DBUS_TYPE_STRING, &str);
3376 * Some access points incorrectly advertise WPS even when they
3377 * are configured as open or no security, so filter
3381 switch (service->security) {
3382 case CONNMAN_SERVICE_SECURITY_PSK:
3383 case CONNMAN_SERVICE_SECURITY_WPA:
3384 case CONNMAN_SERVICE_SECURITY_RSN:
3385 #if defined TIZEN_EXT
3386 case CONNMAN_SERVICE_SECURITY_SAE:
3389 dbus_message_iter_append_basic(iter,
3390 DBUS_TYPE_STRING, &str);
3392 #if defined TIZEN_EXT
3393 case CONNMAN_SERVICE_SECURITY_OWE:
3394 case CONNMAN_SERVICE_SECURITY_DPP:
3396 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
3397 case CONNMAN_SERVICE_SECURITY_NONE:
3398 case CONNMAN_SERVICE_SECURITY_WEP:
3399 case CONNMAN_SERVICE_SECURITY_8021X:
3401 #if defined TIZEN_EXT
3407 if (service->wps_advertizing) {
3408 str = "wps_advertising";
3409 dbus_message_iter_append_basic(iter,
3410 DBUS_TYPE_STRING, &str);
3415 static void security_changed(struct connman_service *service)
3420 if (!allow_property_changed(service))
3423 connman_dbus_property_changed_array(service->path,
3424 CONNMAN_SERVICE_INTERFACE, "Security",
3425 DBUS_TYPE_STRING, append_security, service);
3428 static void append_ethernet(DBusMessageIter *iter, void *user_data)
3430 struct connman_service *service = user_data;
3432 if (service->ipconfig_ipv4)
3433 __connman_ipconfig_append_ethernet(service->ipconfig_ipv4,
3435 else if (service->ipconfig_ipv6)
3436 __connman_ipconfig_append_ethernet(service->ipconfig_ipv6,
3440 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
3441 static void append_eap_over_ethernet(DBusMessageIter *iter, void *user_data)
3443 struct connman_service *service = user_data;
3446 val = service->use_eapol;
3447 connman_dbus_dict_append_basic(iter, "UseEapol",
3448 DBUS_TYPE_BOOLEAN, &val);
3449 if (service->use_eapol) {
3451 connman_dbus_dict_append_basic(iter, "EAP",
3452 DBUS_TYPE_STRING, &service->eap);
3454 if (service->identity)
3455 connman_dbus_dict_append_basic(iter, "Identity",
3456 DBUS_TYPE_STRING, &service->identity);
3458 if (service->anonymous_identity)
3459 connman_dbus_dict_append_basic(iter, "AnonymousIdentity",
3460 DBUS_TYPE_STRING, &service->anonymous_identity);
3462 if (service->ca_cert_file)
3463 connman_dbus_dict_append_basic(iter, "CACertFile",
3464 DBUS_TYPE_STRING, &service->ca_cert_file);
3466 if (service->client_cert_file)
3467 connman_dbus_dict_append_basic(iter, "ClientCertFile",
3468 DBUS_TYPE_STRING, &service->client_cert_file);
3470 if (service->private_key_file)
3471 connman_dbus_dict_append_basic(iter, "PrivateKeyFile",
3472 DBUS_TYPE_STRING, &service->private_key_file);
3474 if (service->phase2)
3475 connman_dbus_dict_append_basic(iter, "Phase2",
3476 DBUS_TYPE_STRING, &service->phase2);
3478 if (service->phase1)
3479 connman_dbus_dict_append_basic(iter, "Phase1",
3480 DBUS_TYPE_STRING, &service->phase1);
3482 if (service->pac_file)
3483 connman_dbus_dict_append_basic(iter, "PacFile",
3484 DBUS_TYPE_STRING, &service->pac_file);
3486 /* Should we include passphrase? */
3489 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
3491 static void append_ipv4(DBusMessageIter *iter, void *user_data)
3493 struct connman_service *service = user_data;
3495 if (!is_connected(service->state_ipv4))
3498 if (service->ipconfig_ipv4)
3499 __connman_ipconfig_append_ipv4(service->ipconfig_ipv4, iter);
3502 static void append_ipv6(DBusMessageIter *iter, void *user_data)
3504 struct connman_service *service = user_data;
3506 if (!is_connected(service->state_ipv6))
3509 if (service->ipconfig_ipv6)
3510 __connman_ipconfig_append_ipv6(service->ipconfig_ipv6, iter,
3511 service->ipconfig_ipv4);
3514 static void append_ipv4config(DBusMessageIter *iter, void *user_data)
3516 struct connman_service *service = user_data;
3518 if (service->ipconfig_ipv4)
3519 __connman_ipconfig_append_ipv4config(service->ipconfig_ipv4,
3523 static void append_ipv6config(DBusMessageIter *iter, void *user_data)
3525 struct connman_service *service = user_data;
3527 if (service->ipconfig_ipv6)
3528 __connman_ipconfig_append_ipv6config(service->ipconfig_ipv6,
3532 static void append_nameservers(DBusMessageIter *iter,
3533 struct connman_service *service, char **servers)
3536 bool available = true;
3538 for (i = 0; servers[i]; i++) {
3540 available = nameserver_available(service,
3541 CONNMAN_IPCONFIG_TYPE_ALL,
3545 dbus_message_iter_append_basic(iter,
3546 DBUS_TYPE_STRING, &servers[i]);
3550 #if defined TIZEN_EXT
3551 static void append_nameserver_manual(DBusMessageIter *iter,
3552 struct connman_service *service, const char *server)
3554 bool available = true;
3557 available = nameserver_available(service,
3558 CONNMAN_IPCONFIG_TYPE_ALL, server);
3561 dbus_message_iter_append_basic(iter,
3562 DBUS_TYPE_STRING, &server);
3565 static void append_nameserver_dhcp(DBusMessageIter *iter,
3566 struct connman_service *service, const char *server)
3568 bool available = true;
3571 available = nameserver_available(service,
3572 CONNMAN_IPCONFIG_TYPE_ALL, server);
3575 dbus_message_iter_append_basic(iter,
3576 DBUS_TYPE_STRING, &server);
3580 static void append_dns(DBusMessageIter *iter, void *user_data)
3582 struct connman_service *service = user_data;
3583 #if defined TIZEN_EXT
3587 if (!is_connected(service->state))
3593 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4);
3595 char *str1 = g_strdup_printf("ipv4.%s", str);
3596 dbus_message_iter_append_basic(iter,
3597 DBUS_TYPE_STRING, &str1);
3601 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6);
3603 char *str1 = g_strdup_printf("ipv6.%s", str);
3604 dbus_message_iter_append_basic(iter,
3605 DBUS_TYPE_STRING, &str1);
3610 if (service->nameservers_config) {
3611 #if defined TIZEN_EXT
3613 while (service->nameservers_config[i]) {
3614 if (connman_inet_check_ipaddress(
3615 service->nameservers_config[i]) == AF_INET &&
3616 service->dns_config_method_ipv4 ==
3617 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
3618 append_nameserver_manual(iter, service,
3619 service->nameservers_config[i]);
3622 if (connman_inet_check_ipaddress(
3623 service->nameservers_config[i]) == AF_INET6 &&
3624 service->dns_config_method_ipv6 ==
3625 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
3626 append_nameserver_manual(iter, service,
3627 service->nameservers_config[i]);
3631 /* In case of mixed DNS Config Type one of IPv4/IPv6 can be
3632 * dynamic while other is static so try to append the DNS
3633 * Address which is dynamic also */
3634 if (service->nameservers != NULL) {
3636 while (service->nameservers[i]) {
3637 if (connman_inet_check_ipaddress(
3638 service->nameservers[i]) == AF_INET &&
3639 service->dns_config_method_ipv4 ==
3640 CONNMAN_DNSCONFIG_METHOD_DHCP) {
3641 append_nameserver_dhcp(iter, service,
3642 service->nameservers[i]);
3645 if (connman_inet_check_ipaddress(
3646 service->nameservers[i]) == AF_INET6 &&
3647 service->dns_config_method_ipv6 ==
3648 CONNMAN_DNSCONFIG_METHOD_DHCP) {
3649 append_nameserver_dhcp(iter, service,
3650 service->nameservers[i]);
3656 append_nameservers(iter, service, service->nameservers_config);
3660 if (service->nameservers)
3661 #if defined TIZEN_EXT
3664 while (service->nameservers[i]) {
3665 if (connman_inet_check_ipaddress(
3666 service->nameservers[i]) == AF_INET &&
3667 service->dns_config_method_ipv4 ==
3668 CONNMAN_DNSCONFIG_METHOD_DHCP) {
3669 append_nameserver_dhcp(iter, service,
3670 service->nameservers[i]);
3673 if (connman_inet_check_ipaddress(
3674 service->nameservers[i]) == AF_INET6 &&
3675 service->dns_config_method_ipv6 ==
3676 CONNMAN_DNSCONFIG_METHOD_DHCP) {
3677 append_nameserver_dhcp(iter, service,
3678 service->nameservers[i]);
3684 append_nameservers(iter, service,
3685 service->nameservers);
3688 if (service->nameservers_auto)
3689 append_nameservers(iter, service,
3690 service->nameservers_auto);
3692 if (!service->nameservers && !service->nameservers_auto) {
3695 DBG("append fallback nameservers");
3697 ns = connman_setting_get_string_list("FallbackNameservers");
3699 append_nameservers(iter, service, ns);
3704 static void append_dnsconfig(DBusMessageIter *iter, void *user_data)
3706 struct connman_service *service = user_data;
3709 /* Append DNS Config Type */
3711 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4);
3713 char *str1 = g_strdup_printf("ipv4.%s", str);
3714 dbus_message_iter_append_basic(iter,
3715 DBUS_TYPE_STRING, &str1);
3719 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6);
3721 char *str1 = g_strdup_printf("ipv6.%s", str);
3722 dbus_message_iter_append_basic(iter,
3723 DBUS_TYPE_STRING, &str1);
3728 if (!service->nameservers_config)
3731 #if defined TIZEN_EXT
3733 while (service->nameservers_config[i]) {
3734 if (connman_inet_check_ipaddress(service->nameservers_config[i]) == AF_INET &&
3735 service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL) {
3736 append_nameserver_manual(iter, NULL, service->nameservers_config[i]);
3739 if (connman_inet_check_ipaddress(service->nameservers_config[i]) == AF_INET6 &&
3740 service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL) {
3741 append_nameserver_manual(iter, NULL, service->nameservers_config[i]);
3746 append_nameservers(iter, NULL, service->nameservers_config);
3750 static void append_ts(DBusMessageIter *iter, void *user_data)
3752 GSList *list = user_data;
3755 char *timeserver = list->data;
3758 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
3761 list = g_slist_next(list);
3765 static void append_tsconfig(DBusMessageIter *iter, void *user_data)
3767 struct connman_service *service = user_data;
3770 if (!service->timeservers_config)
3773 for (i = 0; service->timeservers_config[i]; i++) {
3774 dbus_message_iter_append_basic(iter,
3776 &service->timeservers_config[i]);
3780 static void append_domainconfig(DBusMessageIter *iter, void *user_data)
3782 struct connman_service *service = user_data;
3785 if (!service->domains)
3788 for (i = 0; service->domains[i]; i++)
3789 dbus_message_iter_append_basic(iter,
3790 DBUS_TYPE_STRING, &service->domains[i]);
3793 static void append_domain(DBusMessageIter *iter, void *user_data)
3795 struct connman_service *service = user_data;
3797 if (!is_connected(service->state) &&
3798 !is_connecting(service->state))
3801 if (service->domains)
3802 append_domainconfig(iter, user_data);
3803 else if (service->domainname)
3804 dbus_message_iter_append_basic(iter,
3805 DBUS_TYPE_STRING, &service->domainname);
3808 static void append_proxies(DBusMessageIter *iter, void *user_data)
3810 struct connman_service *service = user_data;
3813 if (!service->proxies)
3816 for (i = 0; service->proxies[i]; i++)
3817 dbus_message_iter_append_basic(iter,
3818 DBUS_TYPE_STRING, &service->proxies[i]);
3821 static void append_excludes(DBusMessageIter *iter, void *user_data)
3823 struct connman_service *service = user_data;
3826 if (!service->excludes)
3829 for (i = 0; service->excludes[i]; i++)
3830 dbus_message_iter_append_basic(iter,
3831 DBUS_TYPE_STRING, &service->excludes[i]);
3834 static void append_proxy(DBusMessageIter *iter, void *user_data)
3836 struct connman_service *service = user_data;
3837 enum connman_service_proxy_method proxy;
3838 const char *pac = NULL;
3839 const char *method = proxymethod2string(
3840 CONNMAN_SERVICE_PROXY_METHOD_DIRECT);
3842 if (!is_connected(service->state))
3845 proxy = connman_service_get_proxy_method(service);
3848 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
3850 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
3852 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
3853 connman_dbus_dict_append_array(iter, "Servers",
3854 DBUS_TYPE_STRING, append_proxies,
3857 connman_dbus_dict_append_array(iter, "Excludes",
3858 DBUS_TYPE_STRING, append_excludes,
3861 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
3862 /* Maybe DHCP, or WPAD, has provided an url for a pac file */
3863 if (service->ipconfig_ipv4)
3864 pac = __connman_ipconfig_get_proxy_autoconfig(
3865 service->ipconfig_ipv4);
3866 else if (service->ipconfig_ipv6)
3867 pac = __connman_ipconfig_get_proxy_autoconfig(
3868 service->ipconfig_ipv6);
3870 if (!service->pac && !pac)
3876 connman_dbus_dict_append_basic(iter, "URL",
3877 DBUS_TYPE_STRING, &pac);
3881 method = proxymethod2string(proxy);
3884 connman_dbus_dict_append_basic(iter, "Method",
3885 DBUS_TYPE_STRING, &method);
3888 static void append_proxyconfig(DBusMessageIter *iter, void *user_data)
3890 struct connman_service *service = user_data;
3893 if (service->proxy_config == CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN)
3896 switch (service->proxy_config) {
3897 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
3899 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
3901 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
3902 if (service->proxies)
3903 connman_dbus_dict_append_array(iter, "Servers",
3905 append_proxies, service);
3907 if (service->excludes)
3908 connman_dbus_dict_append_array(iter, "Excludes",
3910 append_excludes, service);
3912 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
3914 connman_dbus_dict_append_basic(iter, "URL",
3915 DBUS_TYPE_STRING, &service->pac);
3919 method = proxymethod2string(service->proxy_config);
3921 connman_dbus_dict_append_basic(iter, "Method",
3922 DBUS_TYPE_STRING, &method);
3925 static void append_provider(DBusMessageIter *iter, void *user_data)
3927 struct connman_service *service = user_data;
3929 if (!is_connected(service->state))
3932 if (service->provider)
3933 __connman_provider_append_properties(service->provider, iter);
3937 static void settings_changed(struct connman_service *service,
3938 struct connman_ipconfig *ipconfig)
3940 enum connman_ipconfig_type type;
3942 type = __connman_ipconfig_get_config_type(ipconfig);
3944 __connman_notifier_ipconfig_changed(service, ipconfig);
3946 if (!allow_property_changed(service))
3949 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
3950 connman_dbus_property_changed_dict(service->path,
3951 CONNMAN_SERVICE_INTERFACE, "IPv4",
3952 append_ipv4, service);
3953 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
3954 connman_dbus_property_changed_dict(service->path,
3955 CONNMAN_SERVICE_INTERFACE, "IPv6",
3956 append_ipv6, service);
3959 static void ipv4_configuration_changed(struct connman_service *service)
3961 if (!allow_property_changed(service))
3964 connman_dbus_property_changed_dict(service->path,
3965 CONNMAN_SERVICE_INTERFACE,
3966 "IPv4.Configuration",
3971 void __connman_service_notify_ipv4_configuration(
3972 struct connman_service *service)
3977 ipv4_configuration_changed(service);
3980 static void ipv6_configuration_changed(struct connman_service *service)
3982 if (!allow_property_changed(service))
3985 connman_dbus_property_changed_dict(service->path,
3986 CONNMAN_SERVICE_INTERFACE,
3987 "IPv6.Configuration",
3992 static void dns_changed(struct connman_service *service)
3994 if (!allow_property_changed(service))
3997 connman_dbus_property_changed_array(service->path,
3998 CONNMAN_SERVICE_INTERFACE, "Nameservers",
3999 DBUS_TYPE_STRING, append_dns, service);
4002 static void dns_configuration_changed(struct connman_service *service)
4004 if (!allow_property_changed(service))
4007 connman_dbus_property_changed_array(service->path,
4008 CONNMAN_SERVICE_INTERFACE,
4009 "Nameservers.Configuration",
4010 DBUS_TYPE_STRING, append_dnsconfig, service);
4012 dns_changed(service);
4015 static void domain_changed(struct connman_service *service)
4017 if (!allow_property_changed(service))
4020 connman_dbus_property_changed_array(service->path,
4021 CONNMAN_SERVICE_INTERFACE, "Domains",
4022 DBUS_TYPE_STRING, append_domain, service);
4025 static void domain_configuration_changed(struct connman_service *service)
4027 if (!allow_property_changed(service))
4030 connman_dbus_property_changed_array(service->path,
4031 CONNMAN_SERVICE_INTERFACE,
4032 "Domains.Configuration",
4033 DBUS_TYPE_STRING, append_domainconfig, service);
4036 static void proxy_changed(struct connman_service *service)
4038 if (!allow_property_changed(service))
4041 connman_dbus_property_changed_dict(service->path,
4042 CONNMAN_SERVICE_INTERFACE, "Proxy",
4043 append_proxy, service);
4046 static void proxy_configuration_changed(struct connman_service *service)
4048 if (!allow_property_changed(service))
4051 connman_dbus_property_changed_dict(service->path,
4052 CONNMAN_SERVICE_INTERFACE, "Proxy.Configuration",
4053 append_proxyconfig, service);
4055 proxy_changed(service);
4058 static void mdns_changed(struct connman_service *service)
4060 dbus_bool_t mdns = service->mdns;
4062 if (!allow_property_changed(service))
4065 connman_dbus_property_changed_basic(service->path,
4066 CONNMAN_SERVICE_INTERFACE, "mDNS", DBUS_TYPE_BOOLEAN,
4070 static void mdns_configuration_changed(struct connman_service *service)
4072 dbus_bool_t mdns_config = service->mdns_config;
4074 if (!allow_property_changed(service))
4077 connman_dbus_property_changed_basic(service->path,
4078 CONNMAN_SERVICE_INTERFACE, "mDNS.Configuration",
4079 DBUS_TYPE_BOOLEAN, &mdns_config);
4082 static int set_mdns(struct connman_service *service,
4087 result = __connman_resolver_set_mdns(
4088 __connman_service_get_index(service), enabled);
4091 if (service->mdns != enabled) {
4092 service->mdns = enabled;
4093 mdns_changed(service);
4100 static void timeservers_configuration_changed(struct connman_service *service)
4102 if (!allow_property_changed(service))
4105 connman_dbus_property_changed_array(service->path,
4106 CONNMAN_SERVICE_INTERFACE,
4107 "Timeservers.Configuration",
4109 append_tsconfig, service);
4112 static void link_changed(struct connman_service *service)
4114 if (!allow_property_changed(service))
4117 connman_dbus_property_changed_dict(service->path,
4118 CONNMAN_SERVICE_INTERFACE, "Ethernet",
4119 append_ethernet, service);
4122 static void stats_append_counters(DBusMessageIter *dict,
4123 struct connman_stats_data *stats,
4124 struct connman_stats_data *counters,
4127 if (counters->rx_packets != stats->rx_packets || append_all) {
4128 counters->rx_packets = stats->rx_packets;
4129 connman_dbus_dict_append_basic(dict, "RX.Packets",
4130 DBUS_TYPE_UINT32, &stats->rx_packets);
4133 if (counters->tx_packets != stats->tx_packets || append_all) {
4134 counters->tx_packets = stats->tx_packets;
4135 connman_dbus_dict_append_basic(dict, "TX.Packets",
4136 DBUS_TYPE_UINT32, &stats->tx_packets);
4139 if (counters->rx_bytes != stats->rx_bytes || append_all) {
4140 counters->rx_bytes = stats->rx_bytes;
4141 connman_dbus_dict_append_basic(dict, "RX.Bytes",
4142 DBUS_TYPE_UINT32, &stats->rx_bytes);
4145 if (counters->tx_bytes != stats->tx_bytes || append_all) {
4146 counters->tx_bytes = stats->tx_bytes;
4147 connman_dbus_dict_append_basic(dict, "TX.Bytes",
4148 DBUS_TYPE_UINT32, &stats->tx_bytes);
4151 if (counters->rx_errors != stats->rx_errors || append_all) {
4152 counters->rx_errors = stats->rx_errors;
4153 connman_dbus_dict_append_basic(dict, "RX.Errors",
4154 DBUS_TYPE_UINT32, &stats->rx_errors);
4157 if (counters->tx_errors != stats->tx_errors || append_all) {
4158 counters->tx_errors = stats->tx_errors;
4159 connman_dbus_dict_append_basic(dict, "TX.Errors",
4160 DBUS_TYPE_UINT32, &stats->tx_errors);
4163 if (counters->rx_dropped != stats->rx_dropped || append_all) {
4164 counters->rx_dropped = stats->rx_dropped;
4165 connman_dbus_dict_append_basic(dict, "RX.Dropped",
4166 DBUS_TYPE_UINT32, &stats->rx_dropped);
4169 if (counters->tx_dropped != stats->tx_dropped || append_all) {
4170 counters->tx_dropped = stats->tx_dropped;
4171 connman_dbus_dict_append_basic(dict, "TX.Dropped",
4172 DBUS_TYPE_UINT32, &stats->tx_dropped);
4175 if (counters->time != stats->time || append_all) {
4176 counters->time = stats->time;
4177 connman_dbus_dict_append_basic(dict, "Time",
4178 DBUS_TYPE_UINT32, &stats->time);
4182 static void stats_append(struct connman_service *service,
4183 const char *counter,
4184 struct connman_stats_counter *counters,
4187 DBusMessageIter array, dict;
4190 DBG("service %p counter %s", service, counter);
4192 msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
4196 dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH,
4197 &service->path, DBUS_TYPE_INVALID);
4199 dbus_message_iter_init_append(msg, &array);
4202 connman_dbus_dict_open(&array, &dict);
4204 stats_append_counters(&dict, &service->stats.data,
4205 &counters->stats.data, append_all);
4207 connman_dbus_dict_close(&array, &dict);
4209 /* roaming counter */
4210 connman_dbus_dict_open(&array, &dict);
4212 stats_append_counters(&dict, &service->stats_roaming.data,
4213 &counters->stats_roaming.data, append_all);
4215 connman_dbus_dict_close(&array, &dict);
4217 __connman_counter_send_usage(counter, msg);
4220 static void stats_update(struct connman_service *service,
4221 unsigned int rx_packets, unsigned int tx_packets,
4222 unsigned int rx_bytes, unsigned int tx_bytes,
4223 unsigned int rx_errors, unsigned int tx_errors,
4224 unsigned int rx_dropped, unsigned int tx_dropped)
4226 struct connman_stats *stats = stats_get(service);
4227 struct connman_stats_data *data_last = &stats->data_last;
4228 struct connman_stats_data *data = &stats->data;
4229 unsigned int seconds;
4231 DBG("service %p", service);
4235 rx_packets - data_last->rx_packets;
4237 tx_packets - data_last->tx_packets;
4239 rx_bytes - data_last->rx_bytes;
4241 tx_bytes - data_last->tx_bytes;
4243 rx_errors - data_last->rx_errors;
4245 tx_errors - data_last->tx_errors;
4247 rx_dropped - data_last->rx_dropped;
4249 tx_dropped - data_last->tx_dropped;
4251 stats->valid = true;
4254 data_last->rx_packets = rx_packets;
4255 data_last->tx_packets = tx_packets;
4256 data_last->rx_bytes = rx_bytes;
4257 data_last->tx_bytes = tx_bytes;
4258 data_last->rx_errors = rx_errors;
4259 data_last->tx_errors = tx_errors;
4260 data_last->rx_dropped = rx_dropped;
4261 data_last->tx_dropped = tx_dropped;
4263 seconds = g_timer_elapsed(stats->timer, NULL);
4264 stats->data.time = stats->data_last.time + seconds;
4267 void __connman_service_notify(struct connman_service *service,
4268 unsigned int rx_packets, unsigned int tx_packets,
4269 unsigned int rx_bytes, unsigned int tx_bytes,
4270 unsigned int rx_errors, unsigned int tx_errors,
4271 unsigned int rx_dropped, unsigned int tx_dropped)
4273 GHashTableIter iter;
4274 gpointer key, value;
4275 const char *counter;
4276 struct connman_stats_counter *counters;
4277 struct connman_stats_data *data;
4283 if (!is_connected(service->state))
4286 stats_update(service,
4287 rx_packets, tx_packets,
4289 rx_errors, tx_errors,
4290 rx_dropped, tx_dropped);
4292 data = &stats_get(service)->data;
4293 err = __connman_stats_update(service, service->roaming, data);
4295 connman_error("Failed to store statistics for %s",
4296 service->identifier);
4298 g_hash_table_iter_init(&iter, service->counter_table);
4299 while (g_hash_table_iter_next(&iter, &key, &value)) {
4303 stats_append(service, counter, counters, counters->append_all);
4304 counters->append_all = false;
4308 int __connman_service_counter_register(const char *counter)
4310 struct connman_service *service;
4312 struct connman_stats_counter *counters;
4314 DBG("counter %s", counter);
4316 counter_list = g_slist_prepend(counter_list, (gpointer)counter);
4318 for (list = service_list; list; list = list->next) {
4319 service = list->data;
4321 counters = g_try_new0(struct connman_stats_counter, 1);
4325 counters->append_all = true;
4327 g_hash_table_replace(service->counter_table, (gpointer)counter,
4334 void __connman_service_counter_unregister(const char *counter)
4336 struct connman_service *service;
4339 DBG("counter %s", counter);
4341 for (list = service_list; list; list = list->next) {
4342 service = list->data;
4344 g_hash_table_remove(service->counter_table, counter);
4347 counter_list = g_slist_remove(counter_list, counter);
4350 int connman_service_iterate_services(connman_service_iterate_cb cb,
4356 for (list = service_list; list && ret == 0; list = list->next)
4357 ret = cb((struct connman_service *)list->data, user_data);
4362 #if defined TIZEN_EXT
4363 static void append_security_list(DBusMessageIter *iter, void *user_data)
4365 GSList *sec_list = (GSList *)user_data;
4366 const char *sec_str;
4370 for (list = sec_list; list; list = list->next) {
4371 sec_str = (const char *)list->data;
4373 dbus_message_iter_append_basic(iter,
4374 DBUS_TYPE_STRING, &sec_str);
4379 static void append_wifi_ext_info(DBusMessageIter *dict,
4380 struct connman_network *network)
4382 char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
4383 char *bssid_str = bssid_buff;
4385 unsigned int ssid_len;
4386 unsigned char *bssid;
4387 unsigned int maxrate;
4389 unsigned int keymgmt;
4391 const char *enc_mode;
4394 gboolean pmf_required;
4395 char country_code_buff[WIFI_COUNTRY_CODE_LEN + 1] = {0,};
4396 char *country_code_str = country_code_buff;
4397 unsigned char *country_code;
4398 uint16_t connection_mode;
4399 GSList *sec_list = NULL;
4401 ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len);
4402 bssid = connman_network_get_bssid(network);
4403 maxrate = connman_network_get_maxrate(network);
4404 maxspeed = connman_network_get_maxspeed(network);
4405 frequency = connman_network_get_frequency(network);
4406 enc_mode = connman_network_get_enc_mode(network);
4407 passpoint = connman_network_get_bool(network, "WiFi.HS20AP");
4408 keymgmt = connman_network_get_keymgmt(network);
4409 pmf_required = connman_network_get_bool(network, "WiFi.PMFRequired");
4410 country_code = connman_network_get_countrycode(network);
4411 connection_mode = connman_network_get_connection_mode(network);
4412 sec_list = (GSList *)connman_network_get_sec_list(network);
4414 snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
4416 snprintf(country_code_str, (WIFI_COUNTRY_CODE_LEN + 1), "%c%c",
4417 country_code[0], country_code[1]);
4419 connman_dbus_dict_append_array(dict, "SecurityList",
4421 append_security_list, sec_list);
4423 connman_dbus_dict_append_fixed_array(dict, "SSID",
4424 DBUS_TYPE_BYTE, &ssid, ssid_len);
4425 connman_dbus_dict_append_basic(dict, "BSSID",
4426 DBUS_TYPE_STRING, &bssid_str);
4427 connman_dbus_dict_append_basic(dict, "MaxRate",
4428 DBUS_TYPE_UINT32, &maxrate);
4429 connman_dbus_dict_append_basic(dict, "MaxSpeed",
4430 DBUS_TYPE_INT32, &maxspeed);
4431 connman_dbus_dict_append_basic(dict, "Frequency",
4432 DBUS_TYPE_UINT16, &frequency);
4433 connman_dbus_dict_append_basic(dict, "EncryptionMode",
4434 DBUS_TYPE_STRING, &enc_mode);
4435 connman_dbus_dict_append_basic(dict, "Passpoint",
4436 DBUS_TYPE_BOOLEAN, &passpoint);
4437 connman_dbus_dict_append_basic(dict, "Keymgmt",
4438 DBUS_TYPE_UINT32, &keymgmt);
4439 connman_dbus_dict_append_basic(dict, "PmfReq",
4440 DBUS_TYPE_BOOLEAN, &pmf_required);
4441 connman_dbus_dict_append_basic(dict, "Country", DBUS_TYPE_STRING,
4443 connman_dbus_dict_append_basic(dict, "ConnMode",
4444 DBUS_TYPE_UINT16, &connection_mode);
4446 str = connman_network_get_string(network, "WiFi.Security");
4447 if (str != NULL && g_str_equal(str, "ieee8021x") == TRUE) {
4448 str = connman_network_get_string(network, "WiFi.EAP");
4450 connman_dbus_dict_append_basic(dict, "EAP",
4451 DBUS_TYPE_STRING, &str);
4453 str = connman_network_get_string(network, "WiFi.Phase2");
4455 connman_dbus_dict_append_basic(dict, "Phase2",
4456 DBUS_TYPE_STRING, &str);
4458 str = connman_network_get_string(network, "WiFi.Identity");
4460 connman_dbus_dict_append_basic(dict, "Identity",
4461 DBUS_TYPE_STRING, &str);
4463 str = connman_network_get_string(network, "WiFi.CACertFile");
4465 connman_dbus_dict_append_basic(dict, "CACertFile",
4466 DBUS_TYPE_STRING, &str);
4468 str = connman_network_get_string(network,
4469 "WiFi.ClientCertFile");
4471 connman_dbus_dict_append_basic(dict, "ClientCertFile",
4472 DBUS_TYPE_STRING, &str);
4474 str = connman_network_get_string(network,
4475 "WiFi.PrivateKeyFile");
4477 connman_dbus_dict_append_basic(dict, "PrivateKeyFile",
4478 DBUS_TYPE_STRING, &str);
4482 static void append_bssid_info(DBusMessageIter *iter, void *user_data)
4484 GSList *bssid_list = NULL;
4485 struct connman_network *network = user_data;
4486 struct connman_bssids *bssids;
4487 char bssid_buf[MAC_ADDRESS_LENGTH] = {0,};
4488 char *bssid_str = bssid_buf;
4490 bssid_list = (GSList *)connman_network_get_bssid_list(network);
4493 for (list = bssid_list; list; list = list->next) {
4494 bssids = (struct connman_bssids *)list->data;
4495 g_snprintf(bssid_buf, MAC_ADDRESS_LENGTH, MACSTR, MAC2STR(bssids->bssid));
4497 connman_dbus_dict_append_basic(iter, "BSSID",
4498 DBUS_TYPE_STRING, &bssid_str);
4500 connman_dbus_dict_append_basic(iter, "Strength",
4501 DBUS_TYPE_UINT16, &bssids->strength);
4503 connman_dbus_dict_append_basic(iter, "Frequency",
4504 DBUS_TYPE_UINT16, &bssids->frequency);
4510 static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
4511 struct connman_service *service)
4517 #if defined TIZEN_EXT
4518 unsigned int frequency = 0U;
4519 unsigned char *wifi_vsie;
4520 unsigned int wifi_vsie_len;
4521 GSList *vsie_list = NULL;
4523 if (service->network) {
4524 frequency = connman_network_get_frequency(service->network);
4525 connman_dbus_dict_append_basic(dict, "Frequency",
4526 DBUS_TYPE_UINT16, &frequency);
4527 vsie_list = (GSList *)connman_network_get_vsie_list(service->network);
4532 for (list = vsie_list; list; list = list->next) {
4533 wifi_vsie = (unsigned char *)list->data;
4534 wifi_vsie_len = wifi_vsie[1] + 2;
4536 connman_dbus_dict_append_fixed_array(dict, "Vsie", DBUS_TYPE_BYTE,
4537 &wifi_vsie, wifi_vsie_len);
4542 str = __connman_service_type2string(service->type);
4544 connman_dbus_dict_append_basic(dict, "Type",
4545 DBUS_TYPE_STRING, &str);
4547 connman_dbus_dict_append_array(dict, "Security",
4548 DBUS_TYPE_STRING, append_security, service);
4550 str = state2string(service->state);
4552 connman_dbus_dict_append_basic(dict, "State",
4553 DBUS_TYPE_STRING, &str);
4556 str = state2string(service->state_ipv6);
4558 connman_dbus_dict_append_basic(dict, "StateIPv6",
4559 DBUS_TYPE_STRING, &str);
4562 str = error2string(service->error);
4564 connman_dbus_dict_append_basic(dict, "Error",
4565 DBUS_TYPE_STRING, &str);
4567 if (service->strength > 0)
4568 connman_dbus_dict_append_basic(dict, "Strength",
4569 DBUS_TYPE_BYTE, &service->strength);
4571 val = service->favorite;
4572 connman_dbus_dict_append_basic(dict, "Favorite",
4573 DBUS_TYPE_BOOLEAN, &val);
4575 val = service->immutable;
4576 connman_dbus_dict_append_basic(dict, "Immutable",
4577 DBUS_TYPE_BOOLEAN, &val);
4579 if (service->favorite)
4580 val = service->autoconnect;
4582 val = service->favorite;
4584 connman_dbus_dict_append_basic(dict, "AutoConnect",
4585 DBUS_TYPE_BOOLEAN, &val);
4588 connman_dbus_dict_append_basic(dict, "Name",
4589 DBUS_TYPE_STRING, &service->name);
4591 switch (service->type) {
4592 case CONNMAN_SERVICE_TYPE_UNKNOWN:
4593 case CONNMAN_SERVICE_TYPE_SYSTEM:
4594 case CONNMAN_SERVICE_TYPE_GPS:
4595 case CONNMAN_SERVICE_TYPE_VPN:
4596 case CONNMAN_SERVICE_TYPE_P2P:
4597 #if defined TIZEN_EXT_WIFI_MESH
4598 case CONNMAN_SERVICE_TYPE_MESH:
4601 case CONNMAN_SERVICE_TYPE_CELLULAR:
4602 val = service->roaming;
4603 connman_dbus_dict_append_basic(dict, "Roaming",
4604 DBUS_TYPE_BOOLEAN, &val);
4606 connman_dbus_dict_append_dict(dict, "Ethernet",
4607 append_ethernet, service);
4609 case CONNMAN_SERVICE_TYPE_WIFI:
4610 #if defined TIZEN_EXT
4611 if (service->network != NULL) {
4612 append_wifi_ext_info(dict, service->network);
4613 connman_dbus_dict_append_dict(dict, "BSSID.List",
4614 append_bssid_info, service->network);
4617 connman_dbus_dict_append_dict(dict, "Ethernet",
4618 append_ethernet, service);
4620 service->disconnect_reason = connman_network_get_disconnect_reason(service->network);
4621 connman_dbus_dict_append_basic(dict, "DisconnectReason",
4622 DBUS_TYPE_INT32, &service->disconnect_reason);
4624 connman_dbus_dict_append_basic(dict, "AssocStatusCode",
4625 DBUS_TYPE_INT32, &service->assoc_status_code);
4627 val = service->hidden_service;
4628 connman_dbus_dict_append_basic(dict, "Hidden",
4629 DBUS_TYPE_BOOLEAN, &val);
4633 case CONNMAN_SERVICE_TYPE_ETHERNET:
4634 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
4635 connman_dbus_dict_append_dict(dict, "EapOverEthernet",
4636 append_eap_over_ethernet, service);
4638 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
4639 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
4640 case CONNMAN_SERVICE_TYPE_GADGET:
4641 connman_dbus_dict_append_dict(dict, "Ethernet",
4642 append_ethernet, service);
4646 connman_dbus_dict_append_dict(dict, "IPv4", append_ipv4, service);
4648 connman_dbus_dict_append_dict(dict, "IPv4.Configuration",
4649 append_ipv4config, service);
4651 connman_dbus_dict_append_dict(dict, "IPv6", append_ipv6, service);
4653 connman_dbus_dict_append_dict(dict, "IPv6.Configuration",
4654 append_ipv6config, service);
4656 connman_dbus_dict_append_array(dict, "Nameservers",
4657 DBUS_TYPE_STRING, append_dns, service);
4659 connman_dbus_dict_append_array(dict, "Nameservers.Configuration",
4660 DBUS_TYPE_STRING, append_dnsconfig, service);
4662 if (service->state == CONNMAN_SERVICE_STATE_READY ||
4663 service->state == CONNMAN_SERVICE_STATE_ONLINE)
4664 list = __connman_timeserver_get_all(service);
4668 connman_dbus_dict_append_array(dict, "Timeservers",
4669 DBUS_TYPE_STRING, append_ts, list);
4671 g_slist_free_full(list, g_free);
4673 connman_dbus_dict_append_array(dict, "Timeservers.Configuration",
4674 DBUS_TYPE_STRING, append_tsconfig, service);
4676 connman_dbus_dict_append_array(dict, "Domains",
4677 DBUS_TYPE_STRING, append_domain, service);
4679 connman_dbus_dict_append_array(dict, "Domains.Configuration",
4680 DBUS_TYPE_STRING, append_domainconfig, service);
4682 connman_dbus_dict_append_dict(dict, "Proxy", append_proxy, service);
4684 connman_dbus_dict_append_dict(dict, "Proxy.Configuration",
4685 append_proxyconfig, service);
4687 val = service->mdns;
4688 connman_dbus_dict_append_basic(dict, "mDNS", DBUS_TYPE_BOOLEAN,
4691 val = service->mdns_config;
4692 connman_dbus_dict_append_basic(dict, "mDNS.Configuration",
4693 DBUS_TYPE_BOOLEAN, &val);
4695 connman_dbus_dict_append_dict(dict, "Provider",
4696 append_provider, service);
4698 if (service->network)
4699 connman_network_append_acddbus(dict, service->network);
4702 #if defined TIZEN_EXT && defined TIZEN_EXT_INS
4703 static void append_ins_bssid_info(DBusMessageIter *iter, void *user_data)
4705 GSList *bssid_list = NULL;
4706 struct connman_network *network = user_data;
4707 struct connman_bssids *bssids;
4708 char bssid_buf[MAC_ADDRESS_LENGTH] = {0,};
4709 char *bssid_str = bssid_buf;
4711 bssid_list = (GSList *)connman_network_get_bssid_list(network);
4714 for (list = bssid_list; list; list = list->next) {
4715 bssids = (struct connman_bssids *)list->data;
4716 g_snprintf(bssid_buf, MAC_ADDRESS_LENGTH, MACSTR, MAC2STR(bssids->bssid));
4718 connman_dbus_dict_append_basic(iter, "BSSID",
4719 DBUS_TYPE_STRING, &bssid_str);
4721 connman_dbus_dict_append_basic(iter, "ScoreINS",
4722 DBUS_TYPE_INT32, &bssids->ins_score);
4724 connman_dbus_dict_append_basic(iter, "ScoreLastConnected",
4725 DBUS_TYPE_INT32, &bssids->score_last_connected_bssid);
4727 connman_dbus_dict_append_basic(iter, "ScoreAssocReject",
4728 DBUS_TYPE_INT32, &bssids->score_assoc_reject);
4730 connman_dbus_dict_append_basic(iter, "Frequency",
4731 DBUS_TYPE_UINT16, &bssids->frequency);
4733 connman_dbus_dict_append_basic(iter, "ScoreFrequency",
4734 DBUS_TYPE_INT32, &bssids->score_frequency);
4736 connman_dbus_dict_append_basic(iter, "Strength",
4737 DBUS_TYPE_UINT16, &bssids->strength);
4739 connman_dbus_dict_append_basic(iter, "ScoreStrength",
4740 DBUS_TYPE_INT32, &bssids->score_strength);
4745 static void append_ins_properties(DBusMessageIter *dict,
4746 struct connman_service *service)
4749 unsigned int frequency = 0U;
4752 connman_dbus_dict_append_basic(dict, "Name",
4753 DBUS_TYPE_STRING, &service->name);
4755 connman_dbus_dict_append_basic(dict, "ScoreINS",
4756 DBUS_TYPE_INT32, &service->ins_score);
4758 connman_dbus_dict_append_basic(dict, "ScoreLastUserSelection",
4759 DBUS_TYPE_INT32, &service->score_last_user_selection);
4761 connman_dbus_dict_append_basic(dict, "ScoreLastConnected",
4762 DBUS_TYPE_INT32, &service->score_last_connected);
4764 str = security2string(service->security);
4766 connman_dbus_dict_append_basic(dict, "Security",
4767 DBUS_TYPE_STRING, &str);
4769 connman_dbus_dict_append_basic(dict, "ScoreSecurityPriority",
4770 DBUS_TYPE_INT32, &service->score_security_priority);
4772 connman_dbus_dict_append_basic(dict, "Strength",
4773 DBUS_TYPE_BYTE, &service->strength);
4775 connman_dbus_dict_append_basic(dict, "ScoreStrength",
4776 DBUS_TYPE_INT32, &service->score_strength);
4778 connman_dbus_dict_append_basic(dict, "ScoreInternetConnection",
4779 DBUS_TYPE_INT32, &service->score_internet_connection);
4781 if (service->network) {
4782 frequency = connman_network_get_frequency(service->network);
4783 connman_dbus_dict_append_basic(dict, "Frequency",
4784 DBUS_TYPE_UINT16, &frequency);
4786 connman_dbus_dict_append_basic(dict, "ScoreFrequency",
4787 DBUS_TYPE_INT32, &service->score_frequency);
4789 connman_dbus_dict_append_dict(dict, "BSSID.List",
4790 append_ins_bssid_info, service->network);
4793 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
4795 static void append_struct_service(DBusMessageIter *iter,
4796 connman_dbus_append_cb_t function,
4797 struct connman_service *service)
4799 DBusMessageIter entry, dict;
4801 dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &entry);
4803 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
4806 connman_dbus_dict_open(&entry, &dict);
4808 function(&dict, service);
4809 connman_dbus_dict_close(&entry, &dict);
4811 dbus_message_iter_close_container(iter, &entry);
4814 static void append_dict_properties(DBusMessageIter *dict, void *user_data)
4816 struct connman_service *service = user_data;
4818 append_properties(dict, TRUE, service);
4821 static void append_struct(gpointer value, gpointer user_data)
4823 struct connman_service *service = value;
4824 DBusMessageIter *iter = user_data;
4829 append_struct_service(iter, append_dict_properties, service);
4832 #if defined TIZEN_EXT && defined TIZEN_EXT_INS
4833 static void append_dict_ins_properties(DBusMessageIter *dict, void *user_data)
4835 struct connman_service *service = user_data;
4837 append_ins_properties(dict, service);
4840 static void append_ins_struct(gpointer value, gpointer user_data)
4842 struct connman_service *service = value;
4843 DBusMessageIter *iter = user_data;
4848 if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
4851 append_struct_service(iter, append_dict_ins_properties, service);
4854 void __connman_ins_list_struct(DBusMessageIter *iter)
4856 g_list_foreach(service_list, append_ins_struct, iter);
4858 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
4860 void __connman_service_list_struct(DBusMessageIter *iter)
4862 g_list_foreach(service_list, append_struct, iter);
4865 bool __connman_service_is_hidden(struct connman_service *service)
4867 return service->hidden;
4871 __connman_service_is_split_routing(struct connman_service *service)
4873 return service->do_split_routing;
4876 bool __connman_service_index_is_split_routing(int index)
4878 struct connman_service *service;
4883 service = __connman_service_lookup_from_index(index);
4887 return __connman_service_is_split_routing(service);
4890 int __connman_service_get_index(struct connman_service *service)
4895 if (service->network)
4896 return connman_network_get_index(service->network);
4897 else if (service->provider)
4898 return connman_provider_get_index(service->provider);
4903 void __connman_service_set_hidden(struct connman_service *service)
4905 if (!service || service->hidden)
4908 service->hidden_service = true;
4911 void __connman_service_set_hostname(struct connman_service *service,
4912 const char *hostname)
4914 if (!service || service->hidden)
4917 g_free(service->hostname);
4918 service->hostname = NULL;
4920 if (hostname && g_str_is_ascii(hostname))
4921 service->hostname = g_strdup(hostname);
4924 const char *__connman_service_get_hostname(struct connman_service *service)
4929 return service->hostname;
4932 void __connman_service_set_domainname(struct connman_service *service,
4933 const char *domainname)
4935 if (!service || service->hidden)
4938 g_free(service->domainname);
4939 service->domainname = NULL;
4941 if (domainname && g_str_is_ascii(domainname))
4942 service->domainname = g_strdup(domainname);
4944 domain_changed(service);
4947 const char *connman_service_get_domainname(struct connman_service *service)
4952 if (service->domains)
4953 return service->domains[0];
4955 return service->domainname;
4958 const char *connman_service_get_dbuspath(struct connman_service *service)
4963 return service->path;
4966 char **connman_service_get_nameservers(struct connman_service *service)
4971 if (service->nameservers_config)
4972 return g_strdupv(service->nameservers_config);
4973 else if (service->nameservers ||
4974 service->nameservers_auto) {
4975 int len = 0, len_auto = 0, i;
4978 if (service->nameservers)
4979 len = g_strv_length(service->nameservers);
4980 if (service->nameservers_auto)
4981 len_auto = g_strv_length(service->nameservers_auto);
4983 nameservers = g_try_new0(char *, len + len_auto + 1);
4987 for (i = 0; i < len; i++)
4988 nameservers[i] = g_strdup(service->nameservers[i]);
4990 for (i = 0; i < len_auto; i++)
4991 nameservers[i + len] =
4992 g_strdup(service->nameservers_auto[i]);
4997 return g_strdupv(connman_setting_get_string_list("FallbackNameservers"));
5000 char **connman_service_get_timeservers_config(struct connman_service *service)
5005 return service->timeservers_config;
5008 char **connman_service_get_timeservers(struct connman_service *service)
5013 return service->timeservers;
5016 #if defined TIZEN_EXT
5018 * Description: Telephony plug-in requires manual PROXY setting function
5020 int connman_service_set_proxy(struct connman_service *service,
5021 const char *proxy, gboolean active)
5023 char **proxies_array = NULL;
5025 if (service == NULL)
5028 switch (service->type) {
5029 case CONNMAN_SERVICE_TYPE_CELLULAR:
5030 case CONNMAN_SERVICE_TYPE_ETHERNET:
5031 case CONNMAN_SERVICE_TYPE_WIFI:
5038 g_strfreev(service->proxies);
5039 service->proxies = NULL;
5042 proxies_array = g_strsplit(proxy, " ", 0);
5044 service->proxies = proxies_array;
5046 if (proxy == NULL) {
5047 service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
5048 DBG("proxy changed (%d)", active);
5050 service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_MANUAL;
5051 DBG("proxy chagned %s (%d)", proxy, active);
5054 if (active == TRUE) {
5055 proxy_changed(service);
5057 __connman_notifier_proxy_changed(service);
5064 void connman_service_set_proxy_method(struct connman_service *service,
5065 enum connman_service_proxy_method method)
5067 if (!service || service->hidden)
5070 service->proxy = method;
5072 proxy_changed(service);
5074 if (method != CONNMAN_SERVICE_PROXY_METHOD_AUTO)
5075 __connman_notifier_proxy_changed(service);
5078 enum connman_service_proxy_method connman_service_get_proxy_method(
5079 struct connman_service *service)
5082 return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
5084 if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN) {
5085 if (service->proxy_config == CONNMAN_SERVICE_PROXY_METHOD_AUTO &&
5087 return service->proxy;
5089 return service->proxy_config;
5092 return service->proxy;
5095 char **connman_service_get_proxy_servers(struct connman_service *service)
5097 return g_strdupv(service->proxies);
5100 char **connman_service_get_proxy_excludes(struct connman_service *service)
5102 return g_strdupv(service->excludes);
5105 const char *connman_service_get_proxy_url(struct connman_service *service)
5110 return service->pac;
5113 #if defined TIZEN_EXT_INS
5114 void connman_service_set_internet_connection(struct connman_service *service,
5115 bool internet_connection)
5120 if (service->is_internet_connection != internet_connection) {
5121 service->is_internet_connection = internet_connection;
5123 g_get_current_time((GTimeVal *)&service->modified);
5124 service_save(service);
5128 bool connman_service_get_internet_connection(struct connman_service *service)
5133 return service->is_internet_connection;
5137 #if defined TIZEN_EXT
5138 DBusMessage *connman_service_create_dbus_service_reply(DBusMessage *msg,
5139 struct connman_service *service)
5142 DBusMessageIter array, dict;
5144 reply = dbus_message_new_method_return(msg);
5148 dbus_message_iter_init_append(reply, &array);
5151 dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH,
5154 connman_dbus_dict_open(&array, &dict);
5156 append_properties(&dict, FALSE, service);
5157 connman_dbus_dict_close(&array, &dict);
5163 void __connman_service_set_proxy_autoconfig(struct connman_service *service,
5166 if (!service || service->hidden)
5169 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_AUTO;
5171 if (service->ipconfig_ipv4) {
5172 if (__connman_ipconfig_set_proxy_autoconfig(
5173 service->ipconfig_ipv4, url) < 0)
5175 } else if (service->ipconfig_ipv6) {
5176 if (__connman_ipconfig_set_proxy_autoconfig(
5177 service->ipconfig_ipv6, url) < 0)
5182 proxy_changed(service);
5184 __connman_notifier_proxy_changed(service);
5187 const char *connman_service_get_proxy_autoconfig(struct connman_service *service)
5192 if (service->ipconfig_ipv4)
5193 return __connman_ipconfig_get_proxy_autoconfig(
5194 service->ipconfig_ipv4);
5195 else if (service->ipconfig_ipv6)
5196 return __connman_ipconfig_get_proxy_autoconfig(
5197 service->ipconfig_ipv6);
5201 #if defined TIZEN_EXT
5202 int connman_service_get_ipv6_dns_method(struct connman_service *service)
5205 DBG("Service is NULL");
5209 return service->dns_config_method_ipv6;
5213 void __connman_service_set_timeservers(struct connman_service *service,
5221 g_strfreev(service->timeservers);
5222 service->timeservers = NULL;
5224 for (i = 0; timeservers && timeservers[i]; i++)
5225 __connman_service_timeserver_append(service, timeservers[i]);
5228 int __connman_service_timeserver_append(struct connman_service *service,
5229 const char *timeserver)
5233 DBG("service %p timeserver %s", service, timeserver);
5238 if (service->timeservers) {
5241 for (i = 0; service->timeservers[i]; i++)
5242 if (g_strcmp0(service->timeservers[i], timeserver) == 0)
5245 len = g_strv_length(service->timeservers);
5246 service->timeservers = g_try_renew(char *, service->timeservers,
5250 service->timeservers = g_try_new0(char *, len + 2);
5253 if (!service->timeservers)
5256 service->timeservers[len] = g_strdup(timeserver);
5257 service->timeservers[len + 1] = NULL;
5262 int __connman_service_timeserver_remove(struct connman_service *service,
5263 const char *timeserver)
5266 int len, i, j, found = 0;
5268 DBG("service %p timeserver %s", service, timeserver);
5273 if (!service->timeservers)
5276 for (i = 0; service->timeservers &&
5277 service->timeservers[i]; i++)
5278 if (g_strcmp0(service->timeservers[i], timeserver) == 0) {
5286 len = g_strv_length(service->timeservers);
5289 g_strfreev(service->timeservers);
5290 service->timeservers = NULL;
5295 servers = g_try_new0(char *, len);
5299 for (i = 0, j = 0; i < len; i++) {
5300 if (g_strcmp0(service->timeservers[i], timeserver) != 0) {
5301 servers[j] = g_strdup(service->timeservers[i]);
5307 servers[len - 1] = NULL;
5309 g_strfreev(service->timeservers);
5310 service->timeservers = servers;
5315 void __connman_service_timeserver_changed(struct connman_service *service,
5321 if (!allow_property_changed(service))
5324 connman_dbus_property_changed_array(service->path,
5325 CONNMAN_SERVICE_INTERFACE, "Timeservers",
5326 DBUS_TYPE_STRING, append_ts, ts_list);
5329 void __connman_service_set_pac(struct connman_service *service,
5332 if (service->hidden)
5334 g_free(service->pac);
5335 service->pac = g_strdup(pac);
5337 proxy_changed(service);
5340 #if defined TIZEN_EXT
5341 void __connman_service_set_proxy(struct connman_service *service,
5342 const char *proxies)
5344 char **proxies_array = NULL;
5346 g_strfreev(service->proxies);
5347 service->proxies = NULL;
5349 if (proxies != NULL)
5350 proxies_array = g_strsplit(proxies, " ", 0);
5352 service->proxies = proxies_array;
5356 void __connman_service_set_identity(struct connman_service *service,
5357 const char *identity)
5359 if (service->immutable || service->hidden)
5362 g_free(service->identity);
5363 service->identity = g_strdup(identity);
5365 if (service->network)
5366 connman_network_set_string(service->network,
5371 void __connman_service_set_anonymous_identity(struct connman_service *service,
5372 const char *anonymous_identity)
5374 if (service->immutable || service->hidden)
5377 g_free(service->anonymous_identity);
5378 service->anonymous_identity = g_strdup(anonymous_identity);
5380 if (service->network)
5381 connman_network_set_string(service->network,
5382 "WiFi.AnonymousIdentity",
5383 service->anonymous_identity);
5386 void __connman_service_set_subject_match(struct connman_service *service,
5387 const char *subject_match)
5389 if (service->immutable || service->hidden)
5392 g_free(service->subject_match);
5393 service->subject_match = g_strdup(subject_match);
5395 if (service->network)
5396 connman_network_set_string(service->network,
5397 "WiFi.SubjectMatch",
5398 service->subject_match);
5401 void __connman_service_set_altsubject_match(struct connman_service *service,
5402 const char *altsubject_match)
5404 if (service->immutable || service->hidden)
5407 g_free(service->altsubject_match);
5408 service->altsubject_match = g_strdup(altsubject_match);
5410 if (service->network)
5411 connman_network_set_string(service->network,
5412 "WiFi.AltSubjectMatch",
5413 service->altsubject_match);
5416 void __connman_service_set_domain_suffix_match(struct connman_service *service,
5417 const char *domain_suffix_match)
5419 if (service->immutable || service->hidden)
5422 g_free(service->domain_suffix_match);
5423 service->domain_suffix_match = g_strdup(domain_suffix_match);
5425 if (service->network)
5426 connman_network_set_string(service->network,
5427 "WiFi.DomainSuffixMatch",
5428 service->domain_suffix_match);
5431 void __connman_service_set_domain_match(struct connman_service *service,
5432 const char *domain_match)
5434 if (service->immutable || service->hidden)
5437 g_free(service->domain_match);
5438 service->domain_match = g_strdup(domain_match);
5440 if (service->network)
5441 connman_network_set_string(service->network,
5443 service->domain_match);
5446 void __connman_service_set_agent_identity(struct connman_service *service,
5447 const char *agent_identity)
5449 if (service->hidden)
5451 g_free(service->agent_identity);
5452 service->agent_identity = g_strdup(agent_identity);
5454 if (service->network)
5455 connman_network_set_string(service->network,
5456 "WiFi.AgentIdentity",
5457 service->agent_identity);
5460 int __connman_service_check_passphrase(enum connman_service_security security,
5461 const char *passphrase)
5469 length = strlen(passphrase);
5472 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
5473 case CONNMAN_SERVICE_SECURITY_NONE:
5474 case CONNMAN_SERVICE_SECURITY_WPA:
5475 #if !defined TIZEN_EXT
5476 case CONNMAN_SERVICE_SECURITY_RSN:
5479 DBG("service security '%s' (%d) not handled",
5480 security2string(security), security);
5484 case CONNMAN_SERVICE_SECURITY_PSK:
5485 #if defined TIZEN_EXT
5486 case CONNMAN_SERVICE_SECURITY_RSN:
5487 /* TO CHECK: We need to check the key length supported by SAE */
5488 case CONNMAN_SERVICE_SECURITY_SAE:
5490 /* A raw key is always 64 bytes length,
5491 * its content is in hex representation.
5492 * A PSK key must be between [8..63].
5495 for (i = 0; i < 64; i++)
5496 if (!isxdigit((unsigned char)
5499 } else if (length < 8 || length > 63)
5502 case CONNMAN_SERVICE_SECURITY_WEP:
5503 /* length of WEP key is 10 or 26
5504 * length of WEP passphrase is 5 or 13
5506 if (length == 10 || length == 26) {
5507 for (i = 0; i < length; i++)
5508 if (!isxdigit((unsigned char)
5511 } else if (length != 5 && length != 13)
5515 case CONNMAN_SERVICE_SECURITY_8021X:
5516 #if defined TIZEN_EXT
5517 case CONNMAN_SERVICE_SECURITY_OWE:
5518 case CONNMAN_SERVICE_SECURITY_DPP:
5527 int __connman_service_set_passphrase(struct connman_service *service,
5528 const char *passphrase)
5532 if (service->hidden)
5535 if (service->immutable &&
5536 service->security != CONNMAN_SERVICE_SECURITY_8021X)
5539 #if defined TIZEN_EXT
5540 if (service->immutable &&
5541 service->security != CONNMAN_SERVICE_SECURITY_DPP)
5543 /* The encrypted passphrase is used here
5544 * and validation is done by net-config before being encrypted.
5547 if (service->security != CONNMAN_SERVICE_SECURITY_PSK &&
5548 service->security != CONNMAN_SERVICE_SECURITY_RSN &&
5549 service->security != CONNMAN_SERVICE_SECURITY_SAE &&
5550 service->security != CONNMAN_SERVICE_SECURITY_WEP)
5552 err = __connman_service_check_passphrase(service->security, passphrase);
5557 g_free(service->passphrase);
5558 service->passphrase = g_strdup(passphrase);
5560 if (service->network)
5561 connman_network_set_string(service->network, "WiFi.Passphrase",
5562 service->passphrase);
5567 const char *__connman_service_get_passphrase(struct connman_service *service)
5572 return service->passphrase;
5575 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
5576 int __connman_service_get_use_eapol(struct connman_service *service)
5579 DBG("Service is NULL");
5583 return service->use_eapol;
5586 int __connman_service_get_connect_reason(struct connman_service *service)
5589 DBG("Service is NULL");
5593 return service->connect_reason;
5595 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
5597 static DBusMessage *get_properties(DBusConnection *conn,
5598 DBusMessage *msg, void *user_data)
5600 struct connman_service *service = user_data;
5602 DBusMessageIter array, dict;
5604 reply = dbus_message_new_method_return(msg);
5608 dbus_message_iter_init_append(reply, &array);
5610 connman_dbus_dict_open(&array, &dict);
5611 append_properties(&dict, FALSE, service);
5612 connman_dbus_dict_close(&array, &dict);
5617 static char **remove_empty_strings(char **strv)
5624 strv[index++] = *iter;
5634 static int update_proxy_configuration(struct connman_service *service,
5635 DBusMessageIter *array)
5637 DBusMessageIter dict;
5638 enum connman_service_proxy_method method;
5639 GString *servers_str = NULL;
5640 GString *excludes_str = NULL;
5641 const char *url = NULL;
5643 method = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
5645 dbus_message_iter_recurse(array, &dict);
5647 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
5648 DBusMessageIter entry, variant;
5652 dbus_message_iter_recurse(&dict, &entry);
5654 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
5657 dbus_message_iter_get_basic(&entry, &key);
5658 dbus_message_iter_next(&entry);
5660 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
5663 dbus_message_iter_recurse(&entry, &variant);
5665 type = dbus_message_iter_get_arg_type(&variant);
5667 if (g_str_equal(key, "Method")) {
5670 if (type != DBUS_TYPE_STRING)
5673 dbus_message_iter_get_basic(&variant, &val);
5674 method = string2proxymethod(val);
5675 } else if (g_str_equal(key, "URL")) {
5676 if (type != DBUS_TYPE_STRING)
5679 dbus_message_iter_get_basic(&variant, &url);
5680 } else if (g_str_equal(key, "Servers")) {
5681 DBusMessageIter str_array;
5683 if (type != DBUS_TYPE_ARRAY)
5686 servers_str = g_string_new(NULL);
5690 dbus_message_iter_recurse(&variant, &str_array);
5692 while (dbus_message_iter_get_arg_type(&str_array) ==
5696 dbus_message_iter_get_basic(&str_array, &val);
5698 if (servers_str->len > 0)
5699 g_string_append_printf(servers_str,
5702 g_string_append(servers_str, val);
5704 dbus_message_iter_next(&str_array);
5706 } else if (g_str_equal(key, "Excludes")) {
5707 DBusMessageIter str_array;
5709 if (type != DBUS_TYPE_ARRAY)
5712 excludes_str = g_string_new(NULL);
5716 dbus_message_iter_recurse(&variant, &str_array);
5718 while (dbus_message_iter_get_arg_type(&str_array) ==
5722 dbus_message_iter_get_basic(&str_array, &val);
5724 if (excludes_str->len > 0)
5725 g_string_append_printf(excludes_str,
5728 g_string_append(excludes_str, val);
5730 dbus_message_iter_next(&str_array);
5734 dbus_message_iter_next(&dict);
5738 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
5740 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
5741 if (!servers_str && !service->proxies)
5745 g_strfreev(service->proxies);
5747 if (servers_str->len > 0) {
5748 char **proxies = g_strsplit_set(
5749 servers_str->str, " ", 0);
5750 proxies = remove_empty_strings(proxies);
5751 service->proxies = proxies;
5753 service->proxies = NULL;
5757 g_strfreev(service->excludes);
5759 if (excludes_str->len > 0) {
5760 char **excludes = g_strsplit_set(
5761 excludes_str->str, " ", 0);
5762 excludes = remove_empty_strings(excludes);
5763 service->excludes = excludes;
5765 service->excludes = NULL;
5768 if (!service->proxies)
5769 method = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
5772 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
5773 g_free(service->pac);
5775 if (url && strlen(url) > 0)
5776 service->pac = g_strstrip(g_strdup(url));
5778 service->pac = NULL;
5780 /* if we are connected:
5781 - if service->pac == NULL
5782 - if __connman_ipconfig_get_proxy_autoconfig(
5783 service->ipconfig) == NULL
5784 --> We should start WPAD */
5787 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
5792 g_string_free(servers_str, TRUE);
5795 g_string_free(excludes_str, TRUE);
5797 service->proxy_config = method;
5803 g_string_free(servers_str, TRUE);
5806 g_string_free(excludes_str, TRUE);
5811 static void do_auto_connect(struct connman_service *service,
5812 enum connman_service_connect_reason reason)
5815 * CONNMAN_SERVICE_CONNECT_REASON_NONE must be ignored for VPNs. VPNs
5816 * always have reason CONNMAN_SERVICE_CONNECT_REASON_USER/AUTO.
5818 if (!service || (service->type == CONNMAN_SERVICE_TYPE_VPN &&
5819 reason == CONNMAN_SERVICE_CONNECT_REASON_NONE))
5823 * Only user interaction should get VPN or WIFI connected in failure
5826 if (service->state == CONNMAN_SERVICE_STATE_FAILURE &&
5827 reason != CONNMAN_SERVICE_CONNECT_REASON_USER &&
5828 (service->type == CONNMAN_SERVICE_TYPE_VPN ||
5829 service->type == CONNMAN_SERVICE_TYPE_WIFI))
5833 * Do not use the builtin auto connect, instead rely on the
5834 * native auto connect feature of the service.
5836 if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_NATIVE)
5840 * Run service auto connect for other than VPN services. Afterwards
5841 * start also VPN auto connect process.
5843 if (service->type != CONNMAN_SERVICE_TYPE_VPN)
5844 __connman_service_auto_connect(reason);
5849 int __connman_service_reset_ipconfig(struct connman_service *service,
5850 enum connman_ipconfig_type type, DBusMessageIter *array,
5851 enum connman_service_state *new_state)
5853 struct connman_ipconfig *ipconfig, *new_ipconfig;
5854 enum connman_ipconfig_method old_method, new_method;
5855 enum connman_service_state state;
5858 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
5859 ipconfig = service->ipconfig_ipv4;
5860 state = service->state_ipv4;
5861 new_method = CONNMAN_IPCONFIG_METHOD_DHCP;
5862 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
5863 ipconfig = service->ipconfig_ipv6;
5864 state = service->state_ipv6;
5865 new_method = CONNMAN_IPCONFIG_METHOD_AUTO;
5872 old_method = __connman_ipconfig_get_method(ipconfig);
5873 index = __connman_ipconfig_get_index(ipconfig);
5875 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
5876 new_ipconfig = create_ip4config(service, index,
5877 CONNMAN_IPCONFIG_METHOD_UNKNOWN);
5879 new_ipconfig = create_ip6config(service, index);
5882 err = __connman_ipconfig_set_config(new_ipconfig, array);
5884 __connman_ipconfig_unref(new_ipconfig);
5888 new_method = __connman_ipconfig_get_method(new_ipconfig);
5891 if (is_connecting(state) || is_connected(state))
5892 __connman_network_clear_ipconfig(service->network, ipconfig);
5894 __connman_ipconfig_unref(ipconfig);
5896 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
5897 service->ipconfig_ipv4 = new_ipconfig;
5898 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
5899 service->ipconfig_ipv6 = new_ipconfig;
5901 if (is_connecting(state) || is_connected(state))
5902 __connman_ipconfig_enable(new_ipconfig);
5904 if (new_state && new_method != old_method) {
5905 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
5906 *new_state = service->state_ipv4;
5908 *new_state = service->state_ipv6;
5910 settings_changed(service, new_ipconfig);
5911 address_updated(service, type);
5913 do_auto_connect(service, CONNMAN_SERVICE_CONNECT_REASON_AUTO);
5916 DBG("err %d ipconfig %p type %d method %d state %s", err,
5917 new_ipconfig, type, new_method,
5918 !new_state ? "-" : state2string(*new_state));
5923 void __connman_service_wispr_start(struct connman_service *service,
5924 enum connman_ipconfig_type type)
5926 DBG("service %p type %s", service, __connman_ipconfig_type2string(type));
5928 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
5929 service->online_check_interval_ipv4 =
5930 online_check_initial_interval;
5932 service->online_check_interval_ipv6 =
5933 online_check_initial_interval;
5935 __connman_wispr_start(service, type);
5938 static void set_error(struct connman_service *service,
5939 enum connman_service_error error);
5941 static DBusMessage *set_property(DBusConnection *conn,
5942 DBusMessage *msg, void *user_data)
5944 struct connman_service *service = user_data;
5945 DBusMessageIter iter, value;
5949 DBG("service %p", service);
5951 if (!dbus_message_iter_init(msg, &iter))
5952 return __connman_error_invalid_arguments(msg);
5954 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
5955 return __connman_error_invalid_arguments(msg);
5957 dbus_message_iter_get_basic(&iter, &name);
5958 dbus_message_iter_next(&iter);
5960 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
5961 return __connman_error_invalid_arguments(msg);
5963 dbus_message_iter_recurse(&iter, &value);
5965 type = dbus_message_iter_get_arg_type(&value);
5967 if (g_str_equal(name, "AutoConnect")) {
5968 dbus_bool_t autoconnect;
5970 if (type != DBUS_TYPE_BOOLEAN)
5971 return __connman_error_invalid_arguments(msg);
5973 if (!service->favorite)
5974 return __connman_error_invalid_service(msg);
5976 dbus_message_iter_get_basic(&value, &autoconnect);
5978 if (autoconnect && service->type == CONNMAN_SERVICE_TYPE_VPN) {
5980 * Changing the autoconnect flag on VPN to "on" should
5981 * have the same effect as user connecting the VPN =
5982 * clear previous error and change state to idle.
5984 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
5986 if (service->state == CONNMAN_SERVICE_STATE_FAILURE) {
5987 service->state = CONNMAN_SERVICE_STATE_IDLE;
5988 state_changed(service);
5992 if (connman_service_set_autoconnect(service, autoconnect)) {
5993 service_save(service);
5995 do_auto_connect(service,
5996 CONNMAN_SERVICE_CONNECT_REASON_AUTO);
5998 } else if (g_str_equal(name, "Nameservers.Configuration")) {
5999 DBusMessageIter entry;
6003 #if defined TIZEN_EXT
6004 enum connman_ipconfig_type ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
6008 if (__connman_provider_is_immutable(service->provider) ||
6010 return __connman_error_not_supported(msg);
6012 if (type != DBUS_TYPE_ARRAY)
6013 return __connman_error_invalid_arguments(msg);
6015 str = g_string_new(NULL);
6017 return __connman_error_invalid_arguments(msg);
6019 index = __connman_service_get_index(service);
6020 gw = __connman_ipconfig_get_gateway_from_index(index,
6021 CONNMAN_IPCONFIG_TYPE_ALL);
6023 #if !defined TIZEN_EXT
6024 if (gw && strlen(gw))
6025 __connman_service_nameserver_del_routes(service,
6026 CONNMAN_IPCONFIG_TYPE_ALL);
6029 dbus_message_iter_recurse(&value, &entry);
6031 #if defined TIZEN_EXT
6032 /* IPv4/IPv6 Last DNS config method */
6033 int last_dns_ipv4 = service->dns_config_method_ipv4;
6034 int last_dns_ipv6 = service->dns_config_method_ipv6;
6035 DBG("Last DNS Config Method IPv4: %d IPv6: %d", last_dns_ipv4, last_dns_ipv6);
6038 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
6040 dbus_message_iter_get_basic(&entry, &val);
6041 dbus_message_iter_next(&entry);
6043 /* First unpack the DNS Config Method */
6044 DBG("DNS Config Method: %s", val);
6045 if((g_strcmp0(val, "ipv4.manual") == 0)) {
6046 service->dns_config_method_ipv4 =
6047 CONNMAN_DNSCONFIG_METHOD_MANUAL;
6049 if(last_dns_ipv4 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
6050 if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
6051 ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
6053 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
6056 } else if(g_strcmp0(val, "ipv4.dhcp") == 0) {
6057 service->dns_config_method_ipv4 =
6058 CONNMAN_DNSCONFIG_METHOD_DHCP;
6059 if(last_dns_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
6060 ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
6063 } else if(g_strcmp0(val, "ipv6.manual") == 0) {
6064 service->dns_config_method_ipv6 =
6065 CONNMAN_DNSCONFIG_METHOD_MANUAL;
6066 if(last_dns_ipv6 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
6067 if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
6068 ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
6070 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
6073 } else if(g_strcmp0(val, "ipv6.dhcp") == 0) {
6074 service->dns_config_method_ipv6 =
6075 CONNMAN_DNSCONFIG_METHOD_DHCP;
6076 if(last_dns_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
6077 ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
6086 g_string_append_printf(str, " %s", val);
6088 g_string_append(str, val);
6091 #if defined TIZEN_EXT
6092 if (service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_DHCP &&
6093 service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_DHCP) {
6094 DBG("Both IPv4 and IPv6 DNS Method DHCP");
6095 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
6097 if (gw && strlen(gw))
6098 __connman_service_nameserver_del_routes(service,
6101 DBG("%s ip_type: %d nameserver remove all", name, ip_type);
6102 nameserver_remove_all(service, ip_type);
6104 nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
6106 g_strfreev(service->nameservers_config);
6109 char **nameservers, **iter;
6111 nameservers = g_strsplit_set(str->str, " ", 0);
6113 for (iter = nameservers; *iter; iter++)
6114 if (connman_inet_check_ipaddress(*iter) <= 0)
6117 nameservers = remove_empty_strings(nameservers);
6118 service->nameservers_config = nameservers;
6120 service->nameservers_config = NULL;
6123 g_string_free(str, TRUE);
6125 if (gw && strlen(gw))
6126 __connman_service_nameserver_add_routes(service, gw);
6128 #if defined TIZEN_EXT
6129 DBG("%s ip_type: %d nameserver add all", name, ip_type);
6130 nameserver_add_all(service, ip_type);
6132 nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
6134 dns_configuration_changed(service);
6136 if (__connman_service_is_connected_state(service,
6137 CONNMAN_IPCONFIG_TYPE_IPV4))
6138 __connman_service_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
6140 if (__connman_service_is_connected_state(service,
6141 CONNMAN_IPCONFIG_TYPE_IPV6))
6142 __connman_service_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV6);
6144 service_save(service);
6145 } else if (g_str_equal(name, "Timeservers.Configuration")) {
6146 DBusMessageIter entry;
6149 if (service->immutable)
6150 return __connman_error_not_supported(msg);
6152 if (type != DBUS_TYPE_ARRAY)
6153 return __connman_error_invalid_arguments(msg);
6155 str = g_string_new(NULL);
6157 return __connman_error_invalid_arguments(msg);
6159 dbus_message_iter_recurse(&value, &entry);
6161 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
6163 dbus_message_iter_get_basic(&entry, &val);
6164 dbus_message_iter_next(&entry);
6170 g_string_append_printf(str, " %s", val);
6172 g_string_append(str, val);
6175 g_strfreev(service->timeservers_config);
6176 service->timeservers_config = NULL;
6179 char **timeservers = g_strsplit_set(str->str, " ", 0);
6180 timeservers = remove_empty_strings(timeservers);
6181 service->timeservers_config = timeservers;
6184 g_string_free(str, TRUE);
6186 service_save(service);
6187 timeservers_configuration_changed(service);
6188 __connman_timeserver_conf_update(service);
6190 } else if (g_str_equal(name, "Domains.Configuration")) {
6191 DBusMessageIter entry;
6194 if (service->immutable)
6195 return __connman_error_not_supported(msg);
6197 if (type != DBUS_TYPE_ARRAY)
6198 return __connman_error_invalid_arguments(msg);
6200 str = g_string_new(NULL);
6202 return __connman_error_invalid_arguments(msg);
6204 dbus_message_iter_recurse(&value, &entry);
6206 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
6208 dbus_message_iter_get_basic(&entry, &val);
6209 dbus_message_iter_next(&entry);
6215 g_string_append_printf(str, " %s", val);
6217 g_string_append(str, val);
6220 searchdomain_remove_all(service);
6221 g_strfreev(service->domains);
6224 char **domains = g_strsplit_set(str->str, " ", 0);
6225 domains = remove_empty_strings(domains);
6226 service->domains = domains;
6228 service->domains = NULL;
6230 g_string_free(str, TRUE);
6232 searchdomain_add_all(service);
6233 domain_configuration_changed(service);
6234 domain_changed(service);
6236 service_save(service);
6237 } else if (g_str_equal(name, "Proxy.Configuration")) {
6240 if (service->immutable)
6241 return __connman_error_not_supported(msg);
6243 if (type != DBUS_TYPE_ARRAY)
6244 return __connman_error_invalid_arguments(msg);
6246 err = update_proxy_configuration(service, &value);
6249 return __connman_error_failed(msg, -err);
6251 proxy_configuration_changed(service);
6253 __connman_notifier_proxy_changed(service);
6255 service_save(service);
6256 } else if (g_str_equal(name, "mDNS.Configuration")) {
6259 if (service->immutable)
6260 return __connman_error_not_supported(msg);
6262 if (type != DBUS_TYPE_BOOLEAN)
6263 return __connman_error_invalid_arguments(msg);
6265 dbus_message_iter_get_basic(&value, &val);
6266 service->mdns_config = val;
6268 mdns_configuration_changed(service);
6270 set_mdns(service, service->mdns_config);
6272 service_save(service);
6273 } else if (g_str_equal(name, "IPv4.Configuration") ||
6274 g_str_equal(name, "IPv6.Configuration")) {
6276 enum connman_service_state state =
6277 CONNMAN_SERVICE_STATE_UNKNOWN;
6278 enum connman_ipconfig_type type =
6279 CONNMAN_IPCONFIG_TYPE_UNKNOWN;
6282 if (service->type == CONNMAN_SERVICE_TYPE_VPN ||
6284 return __connman_error_not_supported(msg);
6288 if (!service->ipconfig_ipv4 &&
6289 !service->ipconfig_ipv6)
6290 return __connman_error_invalid_property(msg);
6292 if (g_str_equal(name, "IPv4.Configuration"))
6293 type = CONNMAN_IPCONFIG_TYPE_IPV4;
6295 type = CONNMAN_IPCONFIG_TYPE_IPV6;
6297 err = __connman_service_reset_ipconfig(service, type, &value,
6301 if (is_connected(state) || is_connecting(state)) {
6302 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
6303 __connman_network_enable_ipconfig(service->network,
6304 service->ipconfig_ipv4);
6306 __connman_network_enable_ipconfig(service->network,
6307 service->ipconfig_ipv6);
6310 return __connman_error_failed(msg, -err);
6313 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
6314 ipv4_configuration_changed(service);
6316 ipv6_configuration_changed(service);
6318 if (is_connecting(service->state) ||
6319 is_connected(service->state)) {
6320 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
6321 __connman_network_enable_ipconfig(service->network,
6322 service->ipconfig_ipv4);
6324 __connman_network_enable_ipconfig(service->network,
6325 service->ipconfig_ipv6);
6328 service_save(service);
6329 #if defined TIZEN_EXT
6330 /* When AP is connected using WPS without SSID then its password needs
6331 * to be saved for autoconnection */
6332 } else if (g_str_equal(name, "Passphrase")) {
6335 if (type != DBUS_TYPE_STRING)
6336 return __connman_error_invalid_arguments(msg);
6338 dbus_message_iter_get_basic(&value, &passphrase);
6340 __connman_service_set_passphrase(service, passphrase);
6342 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
6343 } else if (g_str_equal(name, "EapOverEthernet")) {
6344 int err = connman_service_set_eapol_property(service, &value);
6346 return __connman_error_failed(msg, -err);
6348 service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_USER;
6349 service_save(service);
6350 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
6352 return __connman_error_invalid_property(msg);
6354 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
6357 static void set_error(struct connman_service *service,
6358 enum connman_service_error error)
6362 #if !defined TIZEN_EXT
6363 if (service->error == error)
6367 service->error = error;
6372 #if !defined TIZEN_EXT
6373 if (!allow_property_changed(service))
6377 str = error2string(service->error);
6382 connman_dbus_property_changed_basic(service->path,
6383 CONNMAN_SERVICE_INTERFACE, "Error",
6384 DBUS_TYPE_STRING, &str);
6387 static void remove_timeout(struct connman_service *service)
6389 if (service->timeout > 0) {
6390 g_source_remove(service->timeout);
6391 service->timeout = 0;
6395 static void reply_pending(struct connman_service *service, int error)
6397 remove_timeout(service);
6399 if (service->pending) {
6400 connman_dbus_reply_pending(service->pending, error, NULL);
6401 service->pending = NULL;
6404 if (service->provider_pending) {
6405 connman_dbus_reply_pending(service->provider_pending,
6406 error, service->path);
6407 service->provider_pending = NULL;
6411 static void service_complete(struct connman_service *service)
6413 reply_pending(service, EIO);
6415 if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
6416 do_auto_connect(service, service->connect_reason);
6418 gettimeofday(&service->modified, NULL);
6419 service_save(service);
6422 static DBusMessage *clear_property(DBusConnection *conn,
6423 DBusMessage *msg, void *user_data)
6425 struct connman_service *service = user_data;
6428 DBG("service %p", service);
6430 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
6433 if (g_str_equal(name, "Error")) {
6434 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
6436 __connman_service_clear_error(service);
6437 service_complete(service);
6439 return __connman_error_invalid_property(msg);
6441 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
6444 static bool is_ipconfig_usable(struct connman_service *service)
6446 if (!__connman_ipconfig_is_usable(service->ipconfig_ipv4) &&
6447 !__connman_ipconfig_is_usable(service->ipconfig_ipv6))
6453 static bool is_ignore(struct connman_service *service)
6455 if (!service->autoconnect)
6458 if (service->roaming &&
6459 !connman_setting_get_bool("AutoConnectRoamingServices"))
6462 if (service->ignore)
6465 if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
6468 if (!is_ipconfig_usable(service))
6474 static void disconnect_on_last_session(enum connman_service_type type)
6478 for (list = service_list; list; list = list->next) {
6479 struct connman_service *service = list->data;
6481 if (service->type != type)
6484 if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_SESSION)
6487 __connman_service_disconnect(service);
6492 static int active_sessions[MAX_CONNMAN_SERVICE_TYPES] = {};
6493 static int always_connect[MAX_CONNMAN_SERVICE_TYPES] = {};
6494 static int active_count = 0;
6496 void __connman_service_set_active_session(bool enable, GSList *list)
6507 enum connman_service_type type = GPOINTER_TO_INT(list->data);
6510 case CONNMAN_SERVICE_TYPE_ETHERNET:
6511 case CONNMAN_SERVICE_TYPE_WIFI:
6512 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
6513 case CONNMAN_SERVICE_TYPE_CELLULAR:
6514 case CONNMAN_SERVICE_TYPE_GADGET:
6516 active_sessions[type]++;
6518 active_sessions[type]--;
6521 case CONNMAN_SERVICE_TYPE_UNKNOWN:
6522 case CONNMAN_SERVICE_TYPE_SYSTEM:
6523 case CONNMAN_SERVICE_TYPE_GPS:
6524 case CONNMAN_SERVICE_TYPE_VPN:
6525 case CONNMAN_SERVICE_TYPE_P2P:
6526 #if defined TIZEN_EXT_WIFI_MESH
6527 case CONNMAN_SERVICE_TYPE_MESH:
6532 if (active_sessions[type] == 0)
6533 disconnect_on_last_session(type);
6535 list = g_slist_next(list);
6538 DBG("eth %d wifi %d bt %d cellular %d gadget %d sessions %d",
6539 active_sessions[CONNMAN_SERVICE_TYPE_ETHERNET],
6540 active_sessions[CONNMAN_SERVICE_TYPE_WIFI],
6541 active_sessions[CONNMAN_SERVICE_TYPE_BLUETOOTH],
6542 active_sessions[CONNMAN_SERVICE_TYPE_CELLULAR],
6543 active_sessions[CONNMAN_SERVICE_TYPE_GADGET],
6547 struct preferred_tech_data {
6548 GList *preferred_list;
6549 enum connman_service_type type;
6552 static void preferred_tech_add_by_type(gpointer data, gpointer user_data)
6554 struct connman_service *service = data;
6555 struct preferred_tech_data *tech_data = user_data;
6557 if (service->type == tech_data->type) {
6558 tech_data->preferred_list =
6559 g_list_append(tech_data->preferred_list, service);
6561 #if defined TIZEN_EXT
6562 if (!simplified_log)
6564 DBG("type %d service %p %s", tech_data->type, service,
6569 static GList *preferred_tech_list_get(void)
6571 unsigned int *tech_array;
6572 struct preferred_tech_data tech_data = { 0, };
6575 tech_array = connman_setting_get_uint_list("PreferredTechnologies");
6579 if (connman_setting_get_bool("SingleConnectedTechnology")) {
6581 for (list = service_list; list; list = list->next) {
6582 struct connman_service *service = list->data;
6584 if (!is_connected(service->state))
6587 if (service->connect_reason ==
6588 CONNMAN_SERVICE_CONNECT_REASON_USER) {
6589 DBG("service %p name %s is user connected",
6590 service, service->name);
6591 #if defined TIZEN_EXT
6592 /* We can connect to a favorite service like
6593 * wifi even we have a userconnect for cellular
6594 * because we have refount for cellular service
6596 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6599 if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
6607 for (i = 0; tech_array[i] != 0; i += 1) {
6608 tech_data.type = tech_array[i];
6609 g_list_foreach(service_list, preferred_tech_add_by_type,
6613 return tech_data.preferred_list;
6616 static void set_always_connecting_technologies()
6618 unsigned int *always_connected_techs =
6619 connman_setting_get_uint_list("AlwaysConnectedTechnologies");
6621 for (i = 0; always_connected_techs && always_connected_techs[i]; i++)
6622 always_connect[always_connected_techs[i]] = 1;
6625 #if !defined TIZEN_EXT
6626 static bool autoconnect_no_session_active(struct connman_service *service)
6629 * Test active_count to see if there are no sessions set up and
6630 * stop autoconnecting, but continue connecting if the service
6631 * belongs to a technology which should always autoconnect.
6633 if (!active_count && !always_connect[service->type])
6640 static bool autoconnect_already_connecting(struct connman_service *service,
6641 bool autoconnecting)
6644 * If another service is already connecting and this service type has
6645 * not been marked as always connecting, stop the connecting procedure.
6647 if (autoconnecting &&
6648 !active_sessions[service->type] &&
6649 !always_connect[service->type])
6655 static int service_indicate_state(struct connman_service *service);
6657 static bool auto_connect_service(GList *services,
6658 enum connman_service_connect_reason reason,
6661 struct connman_service *service = NULL;
6662 bool ignore[MAX_CONNMAN_SERVICE_TYPES] = { };
6663 bool autoconnecting = false;
6665 #if defined TIZEN_EXT
6666 GSList *wifi_ignore = NULL;
6669 DBG("preferred %d sessions %d reason %s", preferred, active_count,
6670 reason2string(reason));
6672 ignore[CONNMAN_SERVICE_TYPE_VPN] = true;
6674 #if defined TIZEN_EXT_WIFI_MESH
6675 /* Don't auto connect wifi if mesh interface is created */
6676 if (connman_mesh_is_interface_created())
6677 ignore[CONNMAN_SERVICE_TYPE_WIFI] = true;
6680 for (list = services; list; list = list->next) {
6681 service = list->data;
6683 #if defined TIZEN_EXT
6684 if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
6685 int index = connman_network_get_index(service->network);
6686 if (g_slist_find(wifi_ignore, GINT_TO_POINTER(index)) != NULL)
6690 if (ignore[service->type]) {
6691 DBG("service %p type %s ignore", service,
6692 __connman_service_type2string(service->type));
6696 #if defined TIZEN_EXT
6697 DBG("service %p %s %s %s, favorite(%d), ignore(%d), hidden(%d, %d)",
6698 service, service->name,
6699 state2string(service->state),
6700 __connman_service_type2string(service->type),
6701 service->favorite, is_ignore(service),
6702 service->hidden, service->hidden_service);
6704 /* Tizen takes Wi-Fi as the highest priority into consideration. */
6705 if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
6706 if (is_connecting(service->state) == TRUE || is_connected(service->state) == TRUE)
6710 if (service->connect_reason ==
6711 CONNMAN_SERVICE_CONNECT_REASON_NATIVE) {
6712 DBG("service %p uses native autonnect, skip", service);
6716 if (service->pending ||
6717 is_connecting(service->state) ||
6718 is_connected(service->state)) {
6719 #if defined TIZEN_EXT
6720 if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
6721 int index = connman_network_get_index(service->network);
6722 wifi_ignore = g_slist_prepend(wifi_ignore, GINT_TO_POINTER(index));
6724 autoconnecting = true;
6728 if (autoconnect_no_session_active(service))
6731 ignore[service->type] = true;
6732 autoconnecting = true;
6734 DBG("service %p type %s busy", service,
6735 __connman_service_type2string(service->type));
6740 if (!service->favorite) {
6744 #if defined TIZEN_EXT
6745 DBG("Service is not favorite, autoconnecting %d",
6747 g_slist_free(wifi_ignore);
6749 return autoconnecting;
6752 #if defined TIZEN_EXT
6753 DBG("service %p identifier %s roaming %d ignore %d "
6754 "ipconfig_usable %d autoconnect %d state %d",
6756 service->identifier, service->roaming,
6757 service->ignore, is_ipconfig_usable(service),
6758 service->autoconnect, service->state);
6760 if (is_ignore(service) || service->state !=
6761 CONNMAN_SERVICE_STATE_IDLE)
6763 #if defined TIZEN_EXT
6764 if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
6766 if (autoconnect_already_connecting(service, autoconnecting)) {
6767 DBG("service %p type %s has no users", service,
6768 __connman_service_type2string(service->type));
6772 DBG("service %p %s %s", service, service->name,
6773 (preferred) ? "preferred" : reason2string(reason));
6775 #if defined TIZEN_EXT
6776 __connman_service_connect(service, reason);
6778 if (__connman_service_connect(service, reason) == 0)
6779 service_indicate_state(service);
6781 if (autoconnect_no_session_active(service))
6784 #if defined TIZEN_EXT
6785 if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
6786 int index = connman_network_get_index(service->network);
6787 wifi_ignore = g_slist_prepend(wifi_ignore, GINT_TO_POINTER(index));
6788 autoconnecting = true;
6791 ignore[service->type] = true;
6793 #if defined TIZEN_EXT
6794 g_slist_free(wifi_ignore);
6796 return autoconnecting;
6799 static gboolean run_auto_connect(gpointer data)
6801 enum connman_service_connect_reason reason = GPOINTER_TO_UINT(data);
6802 bool autoconnecting = false;
6803 GList *preferred_tech;
6809 preferred_tech = preferred_tech_list_get();
6810 if (preferred_tech) {
6811 autoconnecting = auto_connect_service(preferred_tech, reason,
6813 g_list_free(preferred_tech);
6816 if (!autoconnecting || active_count)
6817 auto_connect_service(service_list, reason, false);
6822 #if defined TIZEN_EXT
6823 bool __connman_service_get_auto_connect_mode(void)
6825 return auto_connect_mode;
6828 void __connman_service_set_auto_connect_mode(bool enable)
6830 DBG("set auto_connect_mode = %d", enable);
6832 if (auto_connect_mode != enable)
6833 auto_connect_mode = enable;
6837 void __connman_service_auto_connect(enum connman_service_connect_reason reason)
6841 if (autoconnect_id != 0)
6844 #if defined TIZEN_EXT
6845 if (auto_connect_mode == FALSE) {
6846 DBG("Currently, not auto connection mode");
6851 if (!__connman_session_policy_autoconnect(reason))
6854 #if defined TIZEN_EXT
6855 /* Adding Timeout of 500ms before trying to auto connect.
6856 * This is done because of below scenario
6857 * 1. Device is connected to AP1
6858 * 2. WPS Connection request is initiated for AP2
6859 * 3. Immediately WPS Connection is Cancelled
6860 * When WPS Connection Connection is initiated for AP2 then
6861 * sometimes there is a scenario where connman gets in ASSOCIATED
6862 * state with AP1 due to autoconnect and subsequently the connection
6863 * initiated by AP1 fails and connman service for AP1 comes in
6864 * FAILURE state due to this when connection with AP2 is cancelled
6865 * then autoconnect with AP1 doesn't works because its autoconnection
6866 * is ignored as its last state was FAILURE rather than IDLE */
6867 autoconnect_id = g_timeout_add(500, run_auto_connect,
6869 autoconnect_id = g_idle_add(run_auto_connect,
6871 GUINT_TO_POINTER(reason));
6874 static gboolean run_vpn_auto_connect(gpointer data) {
6876 bool need_split = false;
6877 bool autoconnectable_vpns = false;
6879 int timeout = VPN_AUTOCONNECT_TIMEOUT_DEFAULT;
6880 struct connman_service *def_service;
6882 attempts = GPOINTER_TO_INT(data);
6883 def_service = connman_service_get_default();
6886 * Stop auto connecting VPN if there is no transport service or the
6887 * transport service is not connected or if the current default service
6888 * is a connected VPN (in ready state).
6890 if (!def_service || !is_connected(def_service->state) ||
6891 (def_service->type == CONNMAN_SERVICE_TYPE_VPN &&
6892 is_connected(def_service->state))) {
6894 DBG("stopped, default service %s connected %d",
6895 def_service ? def_service->identifier : "NULL",
6896 def_service ? is_connected(def_service->state) : -1);
6900 for (list = service_list; list; list = list->next) {
6901 struct connman_service *service = list->data;
6904 if (service->type != CONNMAN_SERVICE_TYPE_VPN)
6907 if (is_connected(service->state) ||
6908 is_connecting(service->state)) {
6909 if (!service->do_split_routing)
6913 * If the service is connecting it must be accounted
6914 * for to keep the autoconnection in main loop.
6916 if (is_connecting(service->state))
6917 autoconnectable_vpns = true;
6922 if (is_ignore(service) || !service->favorite)
6925 if (need_split && !service->do_split_routing) {
6926 DBG("service %p no split routing", service);
6930 DBG("service %p %s %s", service, service->name,
6931 service->do_split_routing ?
6932 "split routing" : "");
6934 res = __connman_service_connect(service,
6935 CONNMAN_SERVICE_CONNECT_REASON_AUTO);
6939 service_indicate_state(service);
6942 autoconnectable_vpns = true;
6948 if (!service->do_split_routing)
6952 /* Stop if there is no VPN to automatically connect.*/
6953 if (!autoconnectable_vpns) {
6954 DBG("stopping, no autoconnectable VPNs found");
6958 /* Increase the attempt count up to the threshold.*/
6959 if (attempts < VPN_AUTOCONNECT_TIMEOUT_ATTEMPTS_THRESHOLD)
6963 * Timeout increases with 1s after VPN_AUTOCONNECT_TIMEOUT_STEP amount
6964 * of attempts made. After VPN_AUTOCONNECT_TIMEOUT_ATTEMPTS_THRESHOLD is
6965 * reached the delay does not increase.
6967 timeout = timeout + (int)(attempts / VPN_AUTOCONNECT_TIMEOUT_STEP);
6969 /* Re add this to main loop */
6970 vpn_autoconnect_id =
6971 g_timeout_add_seconds(timeout, run_vpn_auto_connect,
6972 GINT_TO_POINTER(attempts));
6974 DBG("re-added to main loop, next VPN autoconnect in %d seconds (#%d)",
6977 return G_SOURCE_REMOVE;
6980 vpn_autoconnect_id = 0;
6981 return G_SOURCE_REMOVE;
6984 static void vpn_auto_connect(void)
6987 * Remove existing autoconnect from main loop to reset the attempt
6988 * counter in order to get VPN connected when there is a network change.
6990 if (vpn_autoconnect_id) {
6991 if (!g_source_remove(vpn_autoconnect_id))
6995 vpn_autoconnect_id =
6996 g_idle_add(run_vpn_auto_connect, NULL);
7000 __connman_service_is_provider_pending(struct connman_service *service)
7005 if (service->provider_pending)
7011 void __connman_service_set_provider_pending(struct connman_service *service,
7014 if (service->provider_pending) {
7015 DBG("service %p provider pending msg %p already exists",
7016 service, service->provider_pending);
7020 service->provider_pending = msg;
7023 static void check_pending_msg(struct connman_service *service)
7025 if (!service->pending)
7028 DBG("service %p pending msg %p already exists", service,
7030 dbus_message_unref(service->pending);
7033 void __connman_service_set_hidden_data(struct connman_service *service,
7036 DBusMessage *pending = user_data;
7038 DBG("service %p pending %p", service, pending);
7043 check_pending_msg(service);
7045 service->pending = pending;
7048 void __connman_service_return_error(struct connman_service *service,
7049 int error, gpointer user_data)
7051 DBG("service %p error %d user_data %p", service, error, user_data);
7053 __connman_service_set_hidden_data(service, user_data);
7055 reply_pending(service, error);
7058 static gboolean connect_timeout(gpointer user_data)
7060 struct connman_service *service = user_data;
7061 bool autoconnect = false;
7063 DBG("service %p", service);
7065 service->timeout = 0;
7067 if (service->network)
7068 __connman_network_disconnect(service->network);
7069 else if (service->provider)
7070 connman_provider_disconnect(service->provider);
7072 __connman_stats_service_unregister(service);
7074 if (service->pending) {
7077 reply = __connman_error_operation_timeout(service->pending);
7079 g_dbus_send_message(connection, reply);
7081 dbus_message_unref(service->pending);
7082 service->pending = NULL;
7086 __connman_service_ipconfig_indicate_state(service,
7087 CONNMAN_SERVICE_STATE_FAILURE,
7088 CONNMAN_IPCONFIG_TYPE_IPV4);
7089 __connman_service_ipconfig_indicate_state(service,
7090 CONNMAN_SERVICE_STATE_FAILURE,
7091 CONNMAN_IPCONFIG_TYPE_IPV6);
7094 service->connect_reason !=
7095 CONNMAN_SERVICE_CONNECT_REASON_USER)
7096 do_auto_connect(service, CONNMAN_SERVICE_CONNECT_REASON_AUTO);
7101 static DBusMessage *connect_service(DBusConnection *conn,
7102 DBusMessage *msg, void *user_data)
7104 struct connman_service *service = user_data;
7105 #if defined TIZEN_EXT
7112 DBG("service %p", service);
7114 #if defined TIZEN_EXT
7116 * Description: TIZEN implements system global connection management.
7118 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
7119 connman_service_user_pdn_connection_ref(service);
7121 /*Reset the Disconnect Reason while issue connect request*/
7122 service->disconnect_reason = 0;
7124 /*Reset the association status code while issue connect request*/
7125 service->assoc_status_code = 0;
7127 /* Reset the disconnection_requested while issue connect request*/
7128 connman_service_set_disconnection_requested(service, false);
7131 if (service->pending)
7132 return __connman_error_in_progress(msg);
7134 #if !defined TIZEN_EXT
7135 index = __connman_service_get_index(service);
7137 for (list = service_list; list; list = list->next) {
7138 struct connman_service *temp = list->data;
7140 #if defined TIZEN_EXT
7141 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
7144 if (!is_connecting(temp->state) && !is_connected(temp->state))
7147 if (service == temp)
7150 if (service->type != temp->type)
7153 if (__connman_service_get_index(temp) == index &&
7154 __connman_service_disconnect(temp) == -EINPROGRESS)
7158 if (err == -EINPROGRESS)
7159 return __connman_error_operation_timeout(msg);
7162 service->ignore = false;
7164 service->pending = dbus_message_ref(msg);
7166 err = __connman_service_connect(service,
7167 CONNMAN_SERVICE_CONNECT_REASON_USER);
7169 if (err != -EINPROGRESS)
7170 reply_pending(service, -err);
7175 static DBusMessage *disconnect_service(DBusConnection *conn,
7176 DBusMessage *msg, void *user_data)
7178 struct connman_service *service = user_data;
7181 DBG("service %p", service);
7183 #if defined TIZEN_EXT
7185 * Description: TIZEN implements system global connection management.
7187 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
7188 if (connman_service_user_pdn_connection_unref_and_test(service) != TRUE)
7189 return __connman_error_failed(msg, EISCONN);
7191 if (is_connected(service->state) == TRUE &&
7192 service == connman_service_get_default_connection())
7193 return __connman_error_failed(msg, EISCONN);
7197 service->ignore = true;
7199 err = __connman_service_disconnect(service);
7200 if (err < 0 && err != -EINPROGRESS)
7201 return __connman_error_failed(msg, -err);
7203 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
7206 #if defined TIZEN_EXT
7207 static void __connman_service_cleanup_network_8021x(struct connman_service *service)
7209 if (service == NULL)
7212 DBG("service %p ", service);
7214 connman_network_set_string(service->network, "WiFi.EAP", NULL);
7215 connman_network_set_string(service->network, "WiFi.Identity", NULL);
7216 connman_network_set_string(service->network, "WiFi.CACertFile", NULL);
7217 connman_network_set_string(service->network, "WiFi.ClientCertFile", NULL);
7218 connman_network_set_string(service->network, "WiFi.PrivateKeyFile", NULL);
7219 connman_network_set_string(service->network, "WiFi.PrivateKeyPassphrase", NULL);
7220 connman_network_set_string(service->network, "WiFi.Phase2", NULL);
7221 connman_network_set_string(service->network, "WiFi.AnonymousIdentity", NULL);
7223 static void __connman_service_cleanup_network_dpp(struct connman_service *service)
7225 if (service == NULL)
7228 DBG("service %p ", service);
7230 connman_network_set_string(service->network, "WiFi.Connector", NULL);
7231 connman_network_set_string(service->network, "WiFi.CSignKey", NULL);
7232 connman_network_set_string(service->network, "WiFi.NetAccessKey", NULL);
7236 bool __connman_service_remove(struct connman_service *service)
7238 if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET ||
7239 service->type == CONNMAN_SERVICE_TYPE_GADGET)
7242 if (service->immutable || service->hidden ||
7243 __connman_provider_is_immutable(service->provider))
7246 #if !defined TIZEN_EXT
7247 if (!service->favorite && !is_idle(service->state))
7251 __connman_service_disconnect(service);
7253 g_free(service->passphrase);
7254 service->passphrase = NULL;
7256 g_free(service->identity);
7257 service->identity = NULL;
7259 g_free(service->anonymous_identity);
7260 service->anonymous_identity = NULL;
7262 g_free(service->subject_match);
7263 service->subject_match = NULL;
7265 g_free(service->altsubject_match);
7266 service->altsubject_match = NULL;
7268 g_free(service->domain_suffix_match);
7269 service->domain_suffix_match = NULL;
7271 g_free(service->domain_match);
7272 service->domain_match = NULL;
7274 g_free(service->agent_identity);
7275 service->agent_identity = NULL;
7277 g_free(service->eap);
7278 service->eap = NULL;
7280 #if defined TIZEN_EXT
7281 g_free(service->ca_cert_file);
7282 service->ca_cert_file = NULL;
7284 g_free(service->client_cert_file);
7285 service->client_cert_file = NULL;
7287 g_free(service->private_key_file);
7288 service->private_key_file = NULL;
7290 g_free(service->private_key_passphrase);
7291 service->private_key_passphrase = NULL;
7293 g_free(service->phase2);
7294 service->phase2 = NULL;
7296 __connman_service_cleanup_network_8021x(service);
7298 __connman_ipconfig_set_method(service->ipconfig_ipv4, CONNMAN_IPCONFIG_METHOD_DHCP);
7299 __connman_ipconfig_set_method(service->ipconfig_ipv6, CONNMAN_IPCONFIG_METHOD_AUTO);
7300 connman_service_set_proxy(service, NULL, false);
7302 __connman_service_nameserver_clear(service);
7304 g_strfreev(service->nameservers_config);
7305 service->nameservers_config = NULL;
7307 g_free(service->connector);
7308 service->connector = NULL;
7310 g_free(service->c_sign_key);
7311 service->c_sign_key = NULL;
7313 g_free(service->net_access_key);
7314 service->net_access_key = NULL;
7316 __connman_service_cleanup_network_dpp(service);
7319 service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
7321 __connman_service_set_favorite(service, false);
7323 __connman_ipconfig_ipv6_reset_privacy(service->ipconfig_ipv6);
7325 #if defined TIZEN_EXT
7326 /* Reset IP Method and DNS Method to DHCP */
7327 __connman_ipconfig_set_method(service->ipconfig_ipv4,
7328 CONNMAN_IPCONFIG_METHOD_DHCP);
7329 service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
7330 g_strfreev(service->nameservers_config);
7331 service->nameservers_config = NULL;
7334 #if defined TIZEN_EXT
7335 __connman_storage_remove_service(service->identifier);
7337 service_save(service);
7343 static DBusMessage *remove_service(DBusConnection *conn,
7344 DBusMessage *msg, void *user_data)
7346 struct connman_service *service = user_data;
7348 DBG("service %p", service);
7350 if (!__connman_service_remove(service))
7351 return __connman_error_not_supported(msg);
7353 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
7356 static bool check_suitable_state(enum connman_service_state a,
7357 enum connman_service_state b)
7360 * Special check so that "ready" service can be moved before
7363 if ((a == CONNMAN_SERVICE_STATE_ONLINE &&
7364 b == CONNMAN_SERVICE_STATE_READY) ||
7365 (b == CONNMAN_SERVICE_STATE_ONLINE &&
7366 a == CONNMAN_SERVICE_STATE_READY))
7372 static void downgrade_state(struct connman_service *service)
7377 DBG("service %p state4 %d state6 %d", service, service->state_ipv4,
7378 service->state_ipv6);
7380 if (service->state_ipv4 == CONNMAN_SERVICE_STATE_ONLINE)
7381 __connman_service_ipconfig_indicate_state(service,
7382 CONNMAN_SERVICE_STATE_READY,
7383 CONNMAN_IPCONFIG_TYPE_IPV4);
7385 if (service->state_ipv6 == CONNMAN_SERVICE_STATE_ONLINE)
7386 __connman_service_ipconfig_indicate_state(service,
7387 CONNMAN_SERVICE_STATE_READY,
7388 CONNMAN_IPCONFIG_TYPE_IPV6);
7391 static void apply_relevant_default_downgrade(struct connman_service *service)
7393 struct connman_service *def_service;
7395 def_service = connman_service_get_default();
7399 if (def_service == service &&
7400 def_service->state == CONNMAN_SERVICE_STATE_ONLINE) {
7401 def_service->state = CONNMAN_SERVICE_STATE_READY;
7402 __connman_notifier_leave_online(def_service->type);
7403 state_changed(def_service);
7407 static void switch_default_service(struct connman_service *default_service,
7408 struct connman_service *downgrade_service)
7410 struct connman_service *service;
7413 apply_relevant_default_downgrade(default_service);
7414 src = g_list_find(service_list, downgrade_service);
7415 dst = g_list_find(service_list, default_service);
7418 if (src == dst || src->next == dst)
7421 service = src->data;
7422 service_list = g_list_delete_link(service_list, src);
7423 service_list = g_list_insert_before(service_list, dst, service);
7425 downgrade_state(downgrade_service);
7428 static struct _services_notify {
7435 static void service_append_added_foreach(gpointer data, gpointer user_data)
7437 struct connman_service *service = data;
7438 DBusMessageIter *iter = user_data;
7440 if (!service || !service->path) {
7441 DBG("service %p or path is NULL", service);
7445 if (g_hash_table_lookup(services_notify->add, service->path)) {
7446 DBG("new %s", service->path);
7448 append_struct(service, iter);
7449 g_hash_table_remove(services_notify->add, service->path);
7451 #if defined TIZEN_EXT
7452 if (!simplified_log)
7454 DBG("changed %s", service->path);
7456 append_struct_service(iter, NULL, service);
7460 static void service_append_ordered(DBusMessageIter *iter, void *user_data)
7462 g_list_foreach(service_list, service_append_added_foreach, iter);
7465 static void append_removed(gpointer key, gpointer value, gpointer user_data)
7467 char *objpath = key;
7468 DBusMessageIter *iter = user_data;
7470 DBG("removed %s", objpath);
7471 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &objpath);
7474 static void service_append_removed(DBusMessageIter *iter, void *user_data)
7476 g_hash_table_foreach(services_notify->remove, append_removed, iter);
7479 static gboolean service_send_changed(gpointer data)
7481 DBusMessage *signal;
7485 services_notify->id = 0;
7487 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
7488 CONNMAN_MANAGER_INTERFACE, "ServicesChanged");
7492 __connman_dbus_append_objpath_dict_array(signal,
7493 service_append_ordered, NULL);
7494 __connman_dbus_append_objpath_array(signal,
7495 service_append_removed, NULL);
7497 dbus_connection_send(connection, signal, NULL);
7498 dbus_message_unref(signal);
7500 g_hash_table_remove_all(services_notify->remove);
7501 g_hash_table_remove_all(services_notify->add);
7506 static void service_schedule_changed(void)
7508 if (services_notify->id != 0)
7511 services_notify->id = g_timeout_add(100, service_send_changed, NULL);
7514 int __connman_service_move(struct connman_service *service,
7515 struct connman_service *target, bool before)
7517 enum connman_ipconfig_method target4, target6;
7518 enum connman_ipconfig_method service4, service6;
7520 DBG("service %p", service);
7525 if (!service->favorite)
7528 if (!target || !target->favorite || target == service)
7531 if (target->type == CONNMAN_SERVICE_TYPE_VPN) {
7533 * We only allow VPN route splitting if there are
7534 * routes defined for a given VPN.
7536 if (!__connman_provider_check_routes(target->provider)) {
7537 connman_info("Cannot move service. "
7538 "No routes defined for provider %s",
7539 __connman_provider_get_ident(target->provider));
7543 __connman_service_set_split_routing(target, true);
7545 __connman_service_set_split_routing(target, false);
7547 __connman_service_set_split_routing(service, false);
7549 target4 = __connman_ipconfig_get_method(target->ipconfig_ipv4);
7550 target6 = __connman_ipconfig_get_method(target->ipconfig_ipv6);
7551 service4 = __connman_ipconfig_get_method(service->ipconfig_ipv4);
7552 service6 = __connman_ipconfig_get_method(service->ipconfig_ipv6);
7554 DBG("target %s method %d/%d state %d/%d split %d", target->identifier,
7555 target4, target6, target->state_ipv4, target->state_ipv6,
7556 target->do_split_routing);
7558 DBG("service %s method %d/%d state %d/%d", service->identifier,
7560 service->state_ipv4, service->state_ipv6);
7563 * If method is OFF, then we do not need to check the corresponding
7566 if (target4 == CONNMAN_IPCONFIG_METHOD_OFF) {
7567 if (service6 != CONNMAN_IPCONFIG_METHOD_OFF) {
7568 if (!check_suitable_state(target->state_ipv6,
7569 service->state_ipv6))
7574 if (target6 == CONNMAN_IPCONFIG_METHOD_OFF) {
7575 if (service4 != CONNMAN_IPCONFIG_METHOD_OFF) {
7576 if (!check_suitable_state(target->state_ipv4,
7577 service->state_ipv4))
7582 if (service4 == CONNMAN_IPCONFIG_METHOD_OFF) {
7583 if (target6 != CONNMAN_IPCONFIG_METHOD_OFF) {
7584 if (!check_suitable_state(target->state_ipv6,
7585 service->state_ipv6))
7590 if (service6 == CONNMAN_IPCONFIG_METHOD_OFF) {
7591 if (target4 != CONNMAN_IPCONFIG_METHOD_OFF) {
7592 if (!check_suitable_state(target->state_ipv4,
7593 service->state_ipv4))
7598 gettimeofday(&service->modified, NULL);
7599 service_save(service);
7600 service_save(target);
7603 * If the service which goes down is the default service and is
7604 * online, we downgrade directly its state to ready so:
7605 * the service which goes up, needs to recompute its state which
7606 * is triggered via downgrading it - if relevant - to state ready.
7609 switch_default_service(target, service);
7611 switch_default_service(service, target);
7613 __connman_connection_update_gateway();
7615 service_schedule_changed();
7620 static DBusMessage *move_service(DBusConnection *conn,
7621 DBusMessage *msg, void *user_data,
7624 struct connman_service *service = user_data;
7625 struct connman_service *target;
7629 DBG("service %p", service);
7631 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
7634 target = find_service(path);
7636 err = __connman_service_move(service, target, before);
7641 return __connman_error_invalid_service(msg);
7643 return __connman_error_not_supported(msg);
7645 connman_warn("unsupported error code %d in move_service()",
7650 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
7653 static DBusMessage *move_before(DBusConnection *conn,
7654 DBusMessage *msg, void *user_data)
7656 return move_service(conn, msg, user_data, true);
7659 static DBusMessage *move_after(DBusConnection *conn,
7660 DBusMessage *msg, void *user_data)
7662 return move_service(conn, msg, user_data, false);
7665 static DBusMessage *reset_counters(DBusConnection *conn,
7666 DBusMessage *msg, void *user_data)
7668 struct connman_service *service = user_data;
7670 reset_stats(service);
7672 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
7675 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
7676 static DBusMessage *is_eapol_enabled(DBusConnection *conn,
7677 DBusMessage *msg, void *user_data)
7679 struct connman_service *service = user_data;
7680 DBG("service: %p path: %s UseEapol: %d", service, service->path, service->use_eapol);
7682 dbus_bool_t eapol_status = service->use_eapol;
7684 DBusMessage *reply = dbus_message_new_method_return(msg);
7686 DBG("Failed to initialize reply");
7690 dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &eapol_status, DBUS_TYPE_INVALID);
7693 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
7695 #if defined TIZEN_EXT
7696 static DBusMessage *downgrade_service(DBusConnection *conn,
7697 DBusMessage *msg, void *user_data)
7699 struct connman_service *service = user_data;
7701 downgrade_state(service);
7702 __connman_connection_update_gateway();
7703 start_online_check(service, CONNMAN_IPCONFIG_TYPE_IPV4);
7705 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
7709 static void service_schedule_added(struct connman_service *service)
7711 #if defined TIZEN_EXT
7712 if (!simplified_log)
7714 DBG("service %p", service);
7716 g_hash_table_remove(services_notify->remove, service->path);
7717 g_hash_table_replace(services_notify->add, service->path, service);
7719 service_schedule_changed();
7722 static void service_schedule_removed(struct connman_service *service)
7724 if (!service || !service->path) {
7725 DBG("service %p or path is NULL", service);
7729 DBG("service %p %s", service, service->path);
7731 g_hash_table_remove(services_notify->add, service->path);
7732 g_hash_table_replace(services_notify->remove, g_strdup(service->path),
7735 service_schedule_changed();
7738 static bool allow_property_changed(struct connman_service *service)
7740 #if defined TIZEN_EXT
7741 if (service->path == NULL)
7744 if (g_hash_table_lookup_extended(services_notify->add, service->path,
7751 static const GDBusMethodTable service_methods[] = {
7752 { GDBUS_DEPRECATED_METHOD("GetProperties",
7753 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
7755 { GDBUS_METHOD("SetProperty",
7756 GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
7757 NULL, set_property) },
7758 { GDBUS_METHOD("ClearProperty",
7759 GDBUS_ARGS({ "name", "s" }), NULL,
7761 { GDBUS_ASYNC_METHOD("Connect", NULL, NULL,
7763 { GDBUS_METHOD("Disconnect", NULL, NULL,
7764 disconnect_service) },
7765 { GDBUS_METHOD("Remove", NULL, NULL, remove_service) },
7766 { GDBUS_METHOD("MoveBefore",
7767 GDBUS_ARGS({ "service", "o" }), NULL,
7769 { GDBUS_METHOD("MoveAfter",
7770 GDBUS_ARGS({ "service", "o" }), NULL,
7772 { GDBUS_METHOD("ResetCounters", NULL, NULL, reset_counters) },
7773 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
7774 { GDBUS_METHOD("IsEapolEnabled", NULL, GDBUS_ARGS({ "eapol", "b" }), is_eapol_enabled) },
7776 #if defined TIZEN_EXT
7777 { GDBUS_METHOD("Downgrade", NULL, NULL, downgrade_service) },
7782 static const GDBusSignalTable service_signals[] = {
7783 { GDBUS_SIGNAL("PropertyChanged",
7784 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
7785 #if defined TIZEN_EXT
7786 { GDBUS_SIGNAL("StateChangedProperties",
7787 GDBUS_ARGS({ "properties", "a{sv}" })) },
7792 static void service_free(gpointer user_data)
7794 struct connman_service *service = user_data;
7795 char *path = service->path;
7797 DBG("service %p", service);
7799 reply_pending(service, ENOENT);
7801 if (service->nameservers_timeout) {
7802 g_source_remove(service->nameservers_timeout);
7803 dns_changed(service);
7806 __connman_notifier_service_remove(service);
7807 service_schedule_removed(service);
7809 __connman_wispr_stop(service);
7810 stats_stop(service);
7812 service->path = NULL;
7815 __connman_connection_update_gateway();
7817 g_dbus_unregister_interface(connection, path,
7818 CONNMAN_SERVICE_INTERFACE);
7822 g_hash_table_destroy(service->counter_table);
7824 if (service->network) {
7825 __connman_network_disconnect(service->network);
7826 connman_network_unref(service->network);
7827 service->network = NULL;
7830 if (service->provider)
7831 connman_provider_unref(service->provider);
7833 if (service->ipconfig_ipv4) {
7834 __connman_ipconfig_set_ops(service->ipconfig_ipv4, NULL);
7835 __connman_ipconfig_set_data(service->ipconfig_ipv4, NULL);
7836 __connman_ipconfig_unref(service->ipconfig_ipv4);
7837 service->ipconfig_ipv4 = NULL;
7840 if (service->ipconfig_ipv6) {
7841 __connman_ipconfig_set_ops(service->ipconfig_ipv6, NULL);
7842 __connman_ipconfig_set_data(service->ipconfig_ipv6, NULL);
7843 __connman_ipconfig_unref(service->ipconfig_ipv6);
7844 service->ipconfig_ipv6 = NULL;
7847 g_strfreev(service->timeservers);
7848 g_strfreev(service->timeservers_config);
7849 g_strfreev(service->nameservers);
7850 g_strfreev(service->nameservers_config);
7851 g_strfreev(service->nameservers_auto);
7852 g_strfreev(service->domains);
7853 g_strfreev(service->proxies);
7854 g_strfreev(service->excludes);
7856 g_free(service->hostname);
7857 g_free(service->domainname);
7858 g_free(service->pac);
7859 g_free(service->name);
7860 g_free(service->passphrase);
7861 g_free(service->identifier);
7862 g_free(service->eap);
7863 g_free(service->identity);
7864 g_free(service->anonymous_identity);
7865 g_free(service->agent_identity);
7866 g_free(service->ca_cert_file);
7867 g_free(service->subject_match);
7868 g_free(service->altsubject_match);
7869 g_free(service->domain_suffix_match);
7870 g_free(service->domain_match);
7871 g_free(service->client_cert_file);
7872 g_free(service->private_key_file);
7873 g_free(service->private_key_passphrase);
7874 g_free(service->phase2);
7875 g_free(service->config_file);
7876 g_free(service->config_entry);
7877 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
7878 g_free(service->pac_file);
7879 g_free(service->phase1);
7882 #if defined TIZEN_EXT
7883 g_free(service->connector);
7884 g_free(service->c_sign_key);
7885 g_free(service->net_access_key);
7888 if (service->stats.timer)
7889 g_timer_destroy(service->stats.timer);
7890 if (service->stats_roaming.timer)
7891 g_timer_destroy(service->stats_roaming.timer);
7893 if (current_default == service)
7894 current_default = NULL;
7899 static void stats_init(struct connman_service *service)
7902 service->stats.valid = false;
7903 service->stats.enabled = false;
7904 service->stats.timer = g_timer_new();
7907 service->stats_roaming.valid = false;
7908 service->stats_roaming.enabled = false;
7909 service->stats_roaming.timer = g_timer_new();
7912 static void service_initialize(struct connman_service *service)
7914 #if defined TIZEN_EXT
7915 if (!simplified_log)
7917 DBG("service %p", service);
7919 service->refcount = 1;
7921 service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
7923 service->type = CONNMAN_SERVICE_TYPE_UNKNOWN;
7924 service->security = CONNMAN_SERVICE_SECURITY_UNKNOWN;
7926 service->state = CONNMAN_SERVICE_STATE_UNKNOWN;
7927 service->state_ipv4 = CONNMAN_SERVICE_STATE_UNKNOWN;
7928 service->state_ipv6 = CONNMAN_SERVICE_STATE_UNKNOWN;
7930 service->favorite = false;
7931 service->immutable = false;
7932 service->hidden = false;
7934 service->ignore = false;
7936 service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
7940 stats_init(service);
7942 service->provider = NULL;
7944 service->wps = false;
7945 service->wps_advertizing = false;
7946 #if defined TIZEN_EXT_INS
7947 memset(service->last_connected_bssid, 0, WIFI_BSSID_LEN_MAX);
7948 service->is_internet_connection = false;
7949 service->assoc_reject_count = 0;
7951 #if defined TIZEN_EXT
7952 service->disconnection_requested = false;
7953 service->storage_reload = false;
7955 * Description: TIZEN implements system global connection management.
7957 service->user_pdn_connection_refcount = 0;
7958 __sync_synchronize();
7960 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
7961 service->use_eapol = false;
7962 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
7966 * connman_service_create:
7968 * Allocate a new service.
7970 * Returns: a newly-allocated #connman_service structure
7972 struct connman_service *connman_service_create(void)
7975 struct connman_stats_counter *counters;
7976 const char *counter;
7978 struct connman_service *service;
7980 service = g_try_new0(struct connman_service, 1);
7984 DBG("service %p", service);
7986 service->counter_table = g_hash_table_new_full(g_str_hash,
7987 g_str_equal, NULL, g_free);
7989 for (list = counter_list; list; list = list->next) {
7990 counter = list->data;
7992 counters = g_try_new0(struct connman_stats_counter, 1);
7994 g_hash_table_destroy(service->counter_table);
7999 counters->append_all = true;
8001 g_hash_table_replace(service->counter_table, (gpointer)counter,
8005 service_initialize(service);
8011 * connman_service_ref:
8012 * @service: service structure
8014 * Increase reference counter of service
8016 struct connman_service *
8017 connman_service_ref_debug(struct connman_service *service,
8018 const char *file, int line, const char *caller)
8020 DBG("%p ref %d by %s:%d:%s()", service, service->refcount + 1,
8021 file, line, caller);
8023 __sync_fetch_and_add(&service->refcount, 1);
8029 * connman_service_unref:
8030 * @service: service structure
8032 * Decrease reference counter of service and release service if no
8035 void connman_service_unref_debug(struct connman_service *service,
8036 const char *file, int line, const char *caller)
8038 DBG("%p ref %d by %s:%d:%s()", service, service->refcount - 1,
8039 file, line, caller);
8041 if (__sync_fetch_and_sub(&service->refcount, 1) != 1)
8044 service_list = g_list_remove(service_list, service);
8046 __connman_service_disconnect(service);
8048 g_hash_table_remove(service_hash, service->identifier);
8051 #if defined TIZEN_EXT && defined TIZEN_EXT_INS
8052 static int calculate_score_last_user_selection(struct connman_service *service)
8055 struct connman_device *device;
8056 const char *last_user_selection_ident;
8057 time_t last_user_selection_time;
8058 unsigned int frequency;
8061 struct tm* ref_timeinfo;
8063 device = connman_network_get_device(service->network);
8067 last_user_selection_time = connman_device_get_last_user_selection_time(device);
8068 last_user_selection_ident = connman_device_get_last_user_selection_ident(device);
8069 frequency = connman_network_get_frequency(service->network);
8071 if (ins_settings.last_user_selection) {
8072 if (g_strcmp0(last_user_selection_ident, service->identifier) == 0 &&
8073 (((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 &&
8074 frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) &&
8075 service->strength >= ins_settings.signal_level3_24ghz) ||
8076 ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 &&
8077 frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) &&
8078 service->strength >= ins_settings.signal_level3_5ghz))) {
8080 /* Only events that occur within 8 hours are counted. */
8081 curr_time = time(NULL);
8082 ref_timeinfo = localtime(&curr_time);
8083 ref_timeinfo->tm_hour -= 8;
8084 ref_time = mktime(ref_timeinfo);
8086 if (last_user_selection_time > ref_time) {
8087 int time_diff = (curr_time - last_user_selection_time) / 60;
8088 int denominator = ins_settings.last_user_selection_time - time_diff;
8089 int numerator = ins_settings.last_user_selection_time /
8090 ins_settings.last_user_selection_score;
8091 int last_user_score = denominator / numerator;
8093 score += (last_user_score > ins_settings.last_user_selection_score ?
8094 ins_settings.last_user_selection_score : last_user_score);
8102 static int calculate_score_last_connected(struct connman_service *service)
8105 struct connman_device *device;
8106 const char *last_connected_ident;
8107 unsigned int frequency;
8109 device = connman_network_get_device(service->network);
8113 last_connected_ident = connman_device_get_last_connected_ident(device);
8114 frequency = connman_network_get_frequency(service->network);
8116 if (ins_settings.last_connected) {
8117 if (ins_settings.last_connected) {
8118 if (g_strcmp0(last_connected_ident, service->identifier) == 0 &&
8119 (((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 &&
8120 frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) &&
8121 service->strength >= ins_settings.signal_level3_24ghz) ||
8122 ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 &&
8123 frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) &&
8124 service->strength >= ins_settings.signal_level3_5ghz))) {
8125 score += ins_settings.last_connected_score;
8133 static int calculate_score_frequency(struct connman_service *service)
8136 unsigned int frequency;
8138 frequency = connman_network_get_frequency(service->network);
8140 switch (ins_settings.preferred_freq) {
8141 case CONNMAN_INS_PREFERRED_FREQ_24GHZ:
8142 if ((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 &&
8143 frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) &&
8144 (service->strength >= ins_settings.signal_level3_24ghz))
8145 score += ins_settings.preferred_freq_score;
8148 case CONNMAN_INS_PREFERRED_FREQ_5GHZ:
8149 if ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 &&
8150 frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) &&
8151 (service->strength >= ins_settings.signal_level3_5ghz))
8152 score += ins_settings.preferred_freq_score;
8162 static int calculate_score_security_priority(struct connman_service *service)
8166 if (ins_settings.security_priority_count)
8167 score += ins_settings.security_priority[service->security];
8172 static int calculate_score_internet_connection(struct connman_service *service)
8176 if (ins_settings.internet) {
8177 if (service->is_internet_connection)
8178 score += ins_settings.internet_score;
8184 static int calculate_score_strength(struct connman_service *service)
8188 if (ins_settings.signal)
8189 score += (((service->strength > 60) ? 60 : service->strength) - 35);
8194 static int calculate_score(struct connman_service *service)
8196 int score_last_user_selection;
8197 int score_last_connected;
8198 int score_frequency;
8199 int score_security_priority;
8200 int score_internet_connection;
8204 if (service->type != CONNMAN_SERVICE_TYPE_WIFI) {
8205 score += calculate_score_internet_connection(service);
8206 service->ins_score = score;
8210 score_last_user_selection = calculate_score_last_user_selection(service);
8211 score_last_connected = calculate_score_last_connected(service);
8212 score_frequency = calculate_score_frequency(service);
8213 score_security_priority = calculate_score_security_priority(service);
8214 score_internet_connection = calculate_score_internet_connection(service);
8215 score_strength = calculate_score_strength(service);
8217 score = score_last_user_selection + score_last_connected +
8218 score_frequency + score_security_priority +
8219 score_internet_connection + score_strength;
8221 service->score_last_user_selection = score_last_user_selection;
8222 service->score_last_connected = score_last_connected;
8223 service->score_frequency = score_frequency;
8224 service->score_security_priority = score_security_priority;
8225 service->score_internet_connection = score_internet_connection;
8226 service->score_strength = score_strength;
8228 service->ins_score = score;
8231 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
8233 static gint service_compare(gconstpointer a, gconstpointer b);
8235 static gint service_compare_vpn(struct connman_service *a,
8236 struct connman_service *b)
8238 struct connman_provider *provider;
8239 struct connman_service *service;
8240 struct connman_service *transport;
8245 provider = a->provider;
8248 } else if (b->provider) {
8249 provider = b->provider;
8256 ident = __connman_provider_get_transport_ident(provider);
8257 transport = connman_service_lookup_from_identifier(ident);
8262 return service_compare(service, transport);
8264 return service_compare(transport, service);
8267 static gint service_compare(gconstpointer a, gconstpointer b)
8269 struct connman_service *service_a = (void *) a;
8270 struct connman_service *service_b = (void *) b;
8271 enum connman_service_state state_a, state_b;
8272 bool a_connected, b_connected;
8273 #if defined TIZEN_EXT && defined TIZEN_EXT_INS
8277 #else /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
8279 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
8281 state_a = service_a->state;
8282 state_b = service_b->state;
8283 a_connected = is_connected(state_a);
8284 b_connected = is_connected(state_b);
8286 #if defined TIZEN_EXT
8287 if ((a_connected && b_connected) &&
8288 state_a == state_b &&
8289 service_a->type == CONNMAN_SERVICE_TYPE_WIFI &&
8290 service_b->type == CONNMAN_SERVICE_TYPE_WIFI) {
8291 const char *default_interface =
8292 connman_setting_get_string("DefaultWifiInterface");
8293 const char *ifname_a = connman_device_get_string(
8294 connman_network_get_device(service_a->network), "Interface");
8295 const char *ifname_b = connman_device_get_string(
8296 connman_network_get_device(service_b->network), "Interface");
8298 if (g_strcmp0(default_interface, ifname_a) == 0)
8300 else if (g_strcmp0(default_interface, ifname_b) == 0)
8305 if (a_connected && b_connected) {
8308 /* Compare the VPN transport and the service */
8309 if ((service_a->type == CONNMAN_SERVICE_TYPE_VPN ||
8310 service_b->type == CONNMAN_SERVICE_TYPE_VPN) &&
8311 service_b->type != service_a->type) {
8312 rval = service_compare_vpn(service_a, service_b);
8317 if (service_a->order > service_b->order)
8320 if (service_a->order < service_b->order)
8324 if (state_a != state_b) {
8325 if (a_connected && b_connected) {
8326 /* We prefer online over ready state */
8327 if (state_a == CONNMAN_SERVICE_STATE_ONLINE)
8330 if (state_b == CONNMAN_SERVICE_STATE_ONLINE)
8339 if (is_connecting(state_a))
8341 if (is_connecting(state_b))
8345 if (service_a->favorite && !service_b->favorite)
8348 if (!service_a->favorite && service_b->favorite)
8351 if (service_a->type != service_b->type) {
8352 unsigned int *tech_array;
8355 tech_array = connman_setting_get_uint_list(
8356 "PreferredTechnologies");
8358 for (i = 0; tech_array[i]; i++) {
8359 if (tech_array[i] == service_a->type)
8362 if (tech_array[i] == service_b->type)
8367 if (service_a->type == CONNMAN_SERVICE_TYPE_ETHERNET)
8369 if (service_b->type == CONNMAN_SERVICE_TYPE_ETHERNET)
8372 if (service_a->type == CONNMAN_SERVICE_TYPE_WIFI)
8374 if (service_b->type == CONNMAN_SERVICE_TYPE_WIFI)
8377 if (service_a->type == CONNMAN_SERVICE_TYPE_CELLULAR)
8379 if (service_b->type == CONNMAN_SERVICE_TYPE_CELLULAR)
8382 if (service_a->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
8384 if (service_b->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
8387 if (service_a->type == CONNMAN_SERVICE_TYPE_VPN)
8389 if (service_b->type == CONNMAN_SERVICE_TYPE_VPN)
8392 if (service_a->type == CONNMAN_SERVICE_TYPE_GADGET)
8394 if (service_b->type == CONNMAN_SERVICE_TYPE_GADGET)
8398 #if defined TIZEN_EXT && defined TIZEN_EXT_INS
8399 score_a = calculate_score(service_a);
8400 score_b = calculate_score(service_b);
8401 if (score_b != score_a)
8402 return score_b - score_a;
8403 else if (score_b == score_a) {
8404 strength = (gint) service_b->strength - (gint) service_a->strength;
8408 #else /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
8409 strength = (gint) service_b->strength - (gint) service_a->strength;
8412 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
8414 return g_strcmp0(service_a->name, service_b->name);
8417 static void service_list_sort(void)
8419 if (service_list && service_list->next) {
8420 service_list = g_list_sort(service_list, service_compare);
8421 service_schedule_changed();
8425 int __connman_service_compare(const struct connman_service *a,
8426 const struct connman_service *b)
8428 return service_compare(a, b);
8432 * connman_service_get_type:
8433 * @service: service structure
8435 * Get the type of service
8437 enum connman_service_type connman_service_get_type(struct connman_service *service)
8440 return CONNMAN_SERVICE_TYPE_UNKNOWN;
8442 return service->type;
8446 * connman_service_get_interface:
8447 * @service: service structure
8449 * Get network interface of service
8451 char *connman_service_get_interface(struct connman_service *service)
8458 index = __connman_service_get_index(service);
8460 return connman_inet_ifname(index);
8464 * connman_service_get_network:
8465 * @service: service structure
8467 * Get the service network
8469 struct connman_network *
8470 __connman_service_get_network(struct connman_service *service)
8475 return service->network;
8478 struct connman_ipconfig *
8479 __connman_service_get_ip4config(struct connman_service *service)
8484 return service->ipconfig_ipv4;
8487 struct connman_ipconfig *
8488 __connman_service_get_ip6config(struct connman_service *service)
8493 return service->ipconfig_ipv6;
8496 struct connman_ipconfig *
8497 __connman_service_get_ipconfig(struct connman_service *service, int family)
8499 if (family == AF_INET)
8500 return __connman_service_get_ip4config(service);
8501 else if (family == AF_INET6)
8502 return __connman_service_get_ip6config(service);
8508 bool __connman_service_is_connected_state(struct connman_service *service,
8509 enum connman_ipconfig_type type)
8515 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
8517 case CONNMAN_IPCONFIG_TYPE_IPV4:
8518 return is_connected(service->state_ipv4);
8519 case CONNMAN_IPCONFIG_TYPE_IPV6:
8520 return is_connected(service->state_ipv6);
8521 case CONNMAN_IPCONFIG_TYPE_ALL:
8522 return is_connected(service->state_ipv4) &&
8523 is_connected(service->state_ipv6);
8528 enum connman_service_security __connman_service_get_security(
8529 struct connman_service *service)
8532 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
8534 return service->security;
8537 const char *__connman_service_get_phase2(struct connman_service *service)
8542 return service->phase2;
8545 bool __connman_service_wps_enabled(struct connman_service *service)
8550 return service->wps;
8553 void __connman_service_mark_dirty(void)
8555 services_dirty = true;
8558 #if defined TIZEN_EXT
8560 * Returns profile count if there is any connected profiles
8561 * that use same interface
8563 int __connman_service_get_connected_count_of_iface(
8564 struct connman_service *service)
8573 index1 = __connman_service_get_index(service);
8578 for (list = service_list; list; list = list->next) {
8579 struct connman_service *service2 = list->data;
8581 if (service == service2)
8584 index2 = __connman_service_get_index(service2);
8586 if (is_connected(service2->state) && index2 > 0 && index1 == index2)
8592 DBG("Interface index %d, count %d", index1, count);
8597 void __connman_service_set_storage_reload(struct connman_service *service,
8598 bool storage_reload)
8600 if (service != NULL)
8601 service->storage_reload = storage_reload;
8606 * __connman_service_set_favorite_delayed:
8607 * @service: service structure
8608 * @favorite: favorite value
8609 * @delay_ordering: do not order service sequence
8611 * Change the favorite setting of service
8613 int __connman_service_set_favorite_delayed(struct connman_service *service,
8615 bool delay_ordering)
8617 #if defined TIZEN_EXT
8618 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
8621 if (service->hidden)
8624 if (service->favorite == favorite)
8627 service->favorite = favorite;
8629 favorite_changed(service);
8631 if (!delay_ordering) {
8633 service_list_sort();
8635 __connman_connection_update_gateway();
8642 * __connman_service_set_favorite:
8643 * @service: service structure
8644 * @favorite: favorite value
8646 * Change the favorite setting of service
8648 int __connman_service_set_favorite(struct connman_service *service,
8651 return __connman_service_set_favorite_delayed(service, favorite,
8655 bool connman_service_get_favorite(struct connman_service *service)
8657 return service->favorite;
8660 bool connman_service_get_autoconnect(struct connman_service *service)
8662 return service->autoconnect;
8665 int __connman_service_set_immutable(struct connman_service *service,
8668 if (service->hidden)
8671 if (service->immutable == immutable)
8674 service->immutable = immutable;
8676 immutable_changed(service);
8681 int __connman_service_set_ignore(struct connman_service *service,
8687 service->ignore = ignore;
8692 void __connman_service_set_string(struct connman_service *service,
8693 const char *key, const char *value)
8695 if (service->hidden)
8697 if (g_str_equal(key, "EAP")) {
8698 g_free(service->eap);
8699 service->eap = g_strdup(value);
8700 } else if (g_str_equal(key, "Identity")) {
8701 g_free(service->identity);
8702 service->identity = g_strdup(value);
8703 } else if (g_str_equal(key, "AnonymousIdentity")) {
8704 g_free(service->anonymous_identity);
8705 service->anonymous_identity = g_strdup(value);
8706 } else if (g_str_equal(key, "CACertFile")) {
8707 g_free(service->ca_cert_file);
8708 service->ca_cert_file = g_strdup(value);
8709 } else if (g_str_equal(key, "SubjectMatch")) {
8710 g_free(service->subject_match);
8711 service->subject_match = g_strdup(value);
8712 } else if (g_str_equal(key, "AltSubjectMatch")) {
8713 g_free(service->altsubject_match);
8714 service->altsubject_match = g_strdup(value);
8715 } else if (g_str_equal(key, "DomainSuffixMatch")) {
8716 g_free(service->domain_suffix_match);
8717 service->domain_suffix_match = g_strdup(value);
8718 } else if (g_str_equal(key, "DomainMatch")) {
8719 g_free(service->domain_match);
8720 service->domain_match = g_strdup(value);
8721 } else if (g_str_equal(key, "ClientCertFile")) {
8722 g_free(service->client_cert_file);
8723 service->client_cert_file = g_strdup(value);
8724 } else if (g_str_equal(key, "PrivateKeyFile")) {
8725 g_free(service->private_key_file);
8726 service->private_key_file = g_strdup(value);
8727 } else if (g_str_equal(key, "PrivateKeyPassphrase")) {
8728 g_free(service->private_key_passphrase);
8729 service->private_key_passphrase = g_strdup(value);
8730 } else if (g_str_equal(key, "Phase2")) {
8731 g_free(service->phase2);
8732 service->phase2 = g_strdup(value);
8733 } else if (g_str_equal(key, "Passphrase"))
8734 __connman_service_set_passphrase(service, value);
8735 #if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
8736 else if (g_str_equal(key, "Phase1")) {
8737 g_free(service->phase1);
8738 service->phase1 = g_strdup(value);
8739 } else if (g_str_equal(key, "PacFile")) {
8740 g_free(service->pac_file);
8741 service->pac_file = g_strdup(value);
8744 #if defined TIZEN_EXT
8745 else if (g_str_equal(key, "Connector")) {
8746 g_free(service->connector);
8747 service->connector = g_strdup(value);
8748 } else if (g_str_equal(key, "CSignKey")) {
8749 g_free(service->c_sign_key);
8750 service->c_sign_key = g_strdup(value);
8751 } else if (g_str_equal(key, "NetAccessKey")) {
8752 g_free(service->net_access_key);
8753 service->net_access_key = g_strdup(value);
8755 DBG("Unknown key: %s", key);
8759 void __connman_service_set_search_domains(struct connman_service *service,
8762 searchdomain_remove_all(service);
8764 if (service->domains)
8765 g_strfreev(service->domains);
8767 service->domains = g_strdupv(domains);
8769 searchdomain_add_all(service);
8772 int __connman_service_set_mdns(struct connman_service *service,
8775 service->mdns_config = enabled;
8777 return set_mdns(service, enabled);
8780 static void report_error_cb(void *user_context, bool retry,
8783 struct connman_service *service = user_context;
8786 __connman_service_connect(service,
8787 CONNMAN_SERVICE_CONNECT_REASON_USER);
8789 /* It is not relevant to stay on Failure state
8790 * when failing is due to wrong user input */
8791 __connman_service_clear_error(service);
8792 #if defined TIZEN_EXT
8793 /* Reseting the state back in case of failure state */
8794 service->state_ipv4 = service->state_ipv6 =
8795 CONNMAN_SERVICE_STATE_IDLE;
8797 if (service->error != CONNMAN_SERVICE_ERROR_AUTH_FAILED &&
8798 service->error != CONNMAN_SERVICE_ERROR_ASSOC_FAILED)
8799 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
8801 service_complete(service);
8802 service_list_sort();
8803 __connman_connection_update_gateway();
8807 static int check_wpspin(struct connman_service *service, const char *wpspin)
8815 length = strlen(wpspin);
8817 /* If 0, it will mean user wants to use PBC method */
8819 connman_network_set_string(service->network,
8820 "WiFi.PinWPS", NULL);
8824 /* A WPS PIN is always 8 chars length,
8825 * its content is in digit representation.
8830 for (i = 0; i < 8; i++)
8831 if (!isdigit((unsigned char) wpspin[i]))
8834 connman_network_set_string(service->network, "WiFi.PinWPS", wpspin);
8839 static void request_input_cb(struct connman_service *service,
8840 bool values_received,
8841 const char *name, int name_len,
8842 const char *identity, const char *passphrase,
8843 bool wps, const char *wpspin,
8844 const char *error, void *user_data)
8846 struct connman_device *device;
8847 const char *security;
8850 DBG("RequestInput return, %p", service);
8853 DBG("error: %s", error);
8855 if (g_strcmp0(error,
8856 "net.connman.Agent.Error.Canceled") == 0) {
8857 err = -ECONNABORTED;
8859 if (service->hidden)
8860 __connman_service_return_error(service,
8866 if (service->hidden)
8867 __connman_service_return_error(service,
8868 ETIMEDOUT, user_data);
8874 if (service->hidden) {
8875 if (name_len > 0 && name_len <= 32) {
8876 device = connman_network_get_device(service->network);
8877 security = connman_network_get_string(service->network,
8879 err = __connman_device_request_hidden_scan(device,
8881 identity, passphrase,
8882 security, user_data);
8887 __connman_service_return_error(service, -err,
8891 if (!values_received || service->hidden) {
8896 if (wps && service->network) {
8897 err = check_wpspin(service, wpspin);
8901 connman_network_set_bool(service->network, "WiFi.UseWPS", wps);
8905 __connman_service_set_agent_identity(service, identity);
8908 err = __connman_service_set_passphrase(service, passphrase);
8912 /* We forget any previous error. */
8913 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
8915 __connman_service_connect(service,
8916 CONNMAN_SERVICE_CONNECT_REASON_USER);
8918 } else if (err == -ENOKEY) {
8919 __connman_service_indicate_error(service,
8920 CONNMAN_SERVICE_ERROR_INVALID_KEY);
8922 /* It is not relevant to stay on Failure state
8923 * when failing is due to wrong user input */
8924 service->state = CONNMAN_SERVICE_STATE_IDLE;
8926 if (!service->hidden) {
8928 * If there was a real error when requesting
8929 * hidden scan, then that error is returned already
8930 * to the user somewhere above so do not try to
8933 __connman_service_return_error(service, -err,
8937 service_complete(service);
8938 __connman_connection_update_gateway();
8942 static void downgrade_connected_services(void)
8944 struct connman_service *up_service;
8947 for (list = service_list; list; list = list->next) {
8948 up_service = list->data;
8950 if (!is_connected(up_service->state))
8953 if (up_service->state == CONNMAN_SERVICE_STATE_ONLINE)
8956 downgrade_state(up_service);
8960 static int service_update_preferred_order(struct connman_service *default_service,
8961 struct connman_service *new_service,
8962 enum connman_service_state new_state)
8964 unsigned int *tech_array;
8967 if (!default_service || default_service == new_service ||
8968 default_service->state != new_state)
8971 tech_array = connman_setting_get_uint_list("PreferredTechnologies");
8974 for (i = 0; tech_array[i] != 0; i += 1) {
8975 if (default_service->type == tech_array[i])
8978 if (new_service->type == tech_array[i]) {
8979 switch_default_service(default_service,
8981 __connman_connection_update_gateway();
8990 #if defined TIZEN_EXT
8991 static gboolean __connman_service_can_drop(struct connman_service *service)
8993 if (is_connected(service->state) == TRUE || is_connecting(service->state) == TRUE) {
8994 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR)
8996 else if (connman_service_is_no_ref_user_pdn_connection(service) == TRUE)
9002 static struct connman_device *default_connecting_device = NULL;
9004 static void __connman_service_disconnect_default(struct connman_service *service)
9006 struct connman_device *default_device = NULL;
9007 struct connman_network *network = __connman_service_get_network(service);
9012 if (default_connecting_device == NULL)
9015 default_device = connman_network_get_device(network);
9017 DBG("Disconnecting service %p %s", service, service->path);
9018 DBG("Disconnecting device %p %p %s",
9019 default_connecting_device,
9021 connman_device_get_string(default_device, "Name"));
9023 if (default_connecting_device == default_device)
9024 default_connecting_device = NULL;
9027 #if defined TIZEN_MAINTAIN_ONLINE
9028 static void __connman_service_connect_default(struct connman_service *current,
9029 enum connman_service_state old_state)
9031 static void __connman_service_connect_default(struct connman_service *current)
9036 bool default_internet;
9037 struct connman_service *service;
9038 struct connman_service *default_service = NULL;
9039 struct connman_device *default_device = NULL;
9041 if (current->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
9042 switch (current->state) {
9043 case CONNMAN_SERVICE_STATE_UNKNOWN:
9044 case CONNMAN_SERVICE_STATE_ASSOCIATION:
9045 case CONNMAN_SERVICE_STATE_CONFIGURATION:
9051 if (default_connecting_device &&
9052 __connman_service_is_internet_profile(current) == TRUE) {
9053 if (current->network == NULL)
9056 default_device = connman_network_get_device(current->network);
9057 if (default_connecting_device == default_device) {
9058 DBG("Cellular service[%s] %p %s",
9059 state2string(current->state), current, current->path);
9060 DBG("Cellular device %p %p %s",
9061 default_connecting_device, default_device,
9062 connman_device_get_string(default_device, "Name"));
9064 default_connecting_device = NULL;
9069 #if defined TIZEN_MAINTAIN_ONLINE
9070 } else if (current->state == CONNMAN_SERVICE_STATE_READY &&
9071 old_state == CONNMAN_SERVICE_STATE_ONLINE) {
9072 DBG("Device is downgraded: online --> ready");
9074 } else if (is_connected(current->state) == TRUE || is_connecting(current->state) == TRUE)
9077 /* Always-on: keep default cellular connection as possible */
9078 for (list = service_list; list; list = list->next) {
9079 service = list->data;
9081 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
9082 __connman_service_is_internet_profile(service) != TRUE ||
9083 service->network == NULL) {
9088 connman_network_get_bool(service->network, "DefaultInternet");
9090 DBG("service: %p %s %s %s (default: %d)", service, service->name,
9091 __connman_service_type2string(service->type),
9092 state2string(service->state), default_internet);
9094 if (default_internet) {
9095 default_service = service;
9096 if (is_connected(default_service->state) == TRUE ||
9097 is_connecting(default_service->state) == TRUE)
9100 default_device = connman_network_get_device(default_service->network);
9101 if (default_connecting_device == default_device) {
9102 DBG("Device is connecting (%p)", default_connecting_device);
9106 default_connecting_device = default_device;
9107 default_service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_USER;
9109 err = __connman_network_connect(default_service->network);
9110 DBG("Connecting default service %p %s [%d]",
9111 default_service, default_service->path, err);
9112 DBG("Connecting device %p %s", default_connecting_device,
9113 connman_device_get_string(default_connecting_device, "Name"));
9114 if (err < 0 && err != -EINPROGRESS) {
9115 default_connecting_device = NULL;
9123 static void single_connected_tech(struct connman_service *allowed)
9125 struct connman_service *service;
9126 GSList *services = NULL, *list;
9129 DBG("keeping %p %s", allowed, allowed->path);
9131 #if defined TIZEN_EXT
9132 if (!allowed || allowed->type == CONNMAN_SERVICE_TYPE_CELLULAR)
9136 for (iter = service_list; iter; iter = iter->next) {
9137 service = iter->data;
9139 #if defined TIZEN_EXT
9140 if (service != allowed && service->type != allowed->type &&
9141 __connman_service_can_drop(service) == TRUE)
9143 if (!is_connected(service->state))
9146 if (service == allowed)
9150 services = g_slist_prepend(services, service);
9153 for (list = services; list; list = list->next) {
9154 service = list->data;
9156 DBG("disconnecting %p %s", service, service->path);
9157 #if defined TIZEN_EXT
9158 __connman_service_disconnect_default(service);
9160 __connman_service_disconnect(service);
9163 g_slist_free(services);
9166 #if defined TIZEN_EXT
9167 static void set_priority_connected_service(void)
9169 struct connman_service *service;
9172 for (list = service_list; list; list = list->next) {
9173 service = list->data;
9175 if (is_connected(service->state) == FALSE)
9178 #if defined TIZEN_MAINTAIN_ONLINE
9180 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
9181 service->state == CONNMAN_SERVICE_STATE_ONLINE)
9183 else if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
9194 static void emit_wifi_roaming_failure(struct connman_service *service,
9195 enum connman_service_state new_state)
9197 if (connman_setting_get_bool("WifiRoaming") &&
9198 connman_network_get_bool(service->network, "WiFi.Roaming")) {
9199 const char *cur_bssid;
9200 const char *dst_bssid;
9202 struct connman_device *device;
9204 device = connman_network_get_device(service->network);
9206 ifname = connman_device_get_string(device, "Interface");
9207 cur_bssid = connman_network_get_string(service->network,
9208 "WiFi.RoamingCurBSSID");
9209 dst_bssid = connman_network_get_string(service->network,
9210 "WiFi.RoamingDstBSSID");
9213 if (device && ifname && cur_bssid && dst_bssid) {
9215 case CONNMAN_SERVICE_STATE_UNKNOWN:
9216 case CONNMAN_SERVICE_STATE_ASSOCIATION:
9217 case CONNMAN_SERVICE_STATE_CONFIGURATION:
9218 case CONNMAN_SERVICE_STATE_READY:
9219 case CONNMAN_SERVICE_STATE_ONLINE:
9221 case CONNMAN_SERVICE_STATE_DISCONNECT:
9222 case CONNMAN_SERVICE_STATE_FAILURE:
9223 case CONNMAN_SERVICE_STATE_IDLE:
9224 __connman_technology_notify_roaming_state(ifname,
9225 "failure", cur_bssid, dst_bssid);
9226 connman_network_set_bool(service->network,
9227 "WiFi.Roaming", false);
9228 connman_network_set_string(service->network,
9229 "WiFi.RoamingCurBSSID", NULL);
9230 connman_network_set_string(service->network,
9231 "WiFi.RoamingDstBSSID", NULL);
9239 static const char *get_dbus_sender(struct connman_service *service)
9241 if (!service->pending)
9244 return dbus_message_get_sender(service->pending);
9247 static int service_indicate_state(struct connman_service *service)
9249 enum connman_service_state old_state, new_state;
9250 struct connman_service *def_service;
9251 enum connman_ipconfig_method method;
9257 old_state = service->state;
9258 new_state = combine_state(service->state_ipv4, service->state_ipv6);
9260 DBG("service %p old %s - new %s/%s => %s",
9262 state2string(old_state),
9263 state2string(service->state_ipv4),
9264 state2string(service->state_ipv6),
9265 state2string(new_state));
9267 if (old_state == new_state)
9270 def_service = connman_service_get_default();
9272 if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
9273 result = service_update_preferred_order(def_service,
9274 service, new_state);
9275 if (result == -EALREADY)
9279 if (old_state == CONNMAN_SERVICE_STATE_ONLINE)
9280 __connman_notifier_leave_online(service->type);
9282 if (is_connected(old_state) && !is_connected(new_state))
9283 searchdomain_remove_all(service);
9285 service->state = new_state;
9286 #if defined TIZEN_EXT
9287 if (!is_connected(old_state) && is_connected(new_state))
9288 connman_device_send_connected_signal(
9289 connman_network_get_device(service->network), true);
9290 else if (is_connected(old_state) && !is_connected(new_state))
9291 connman_device_send_connected_signal(
9292 connman_network_get_device(service->network), false);
9294 state_changed(service);
9296 if (!is_connected(old_state) && is_connected(new_state))
9297 searchdomain_add_all(service);
9300 case CONNMAN_SERVICE_STATE_UNKNOWN:
9304 case CONNMAN_SERVICE_STATE_IDLE:
9305 if (old_state != CONNMAN_SERVICE_STATE_DISCONNECT)
9306 __connman_service_disconnect(service);
9310 case CONNMAN_SERVICE_STATE_ASSOCIATION:
9314 case CONNMAN_SERVICE_STATE_CONFIGURATION:
9315 if (!service->new_service &&
9316 __connman_stats_service_register(service) == 0) {
9318 * For new services the statistics are updated after
9319 * we have successfully connected.
9321 __connman_stats_get(service, false,
9322 &service->stats.data);
9323 __connman_stats_get(service, true,
9324 &service->stats_roaming.data);
9329 case CONNMAN_SERVICE_STATE_READY:
9330 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
9332 if (service->new_service &&
9333 __connman_stats_service_register(service) == 0) {
9335 * This is normally done after configuring state
9336 * but for new service do this after we have connected
9339 __connman_stats_get(service, false,
9340 &service->stats.data);
9341 __connman_stats_get(service, true,
9342 &service->stats_roaming.data);
9345 service->new_service = false;
9349 def_service = connman_service_get_default();
9351 service_update_preferred_order(def_service, service, new_state);
9353 __connman_service_set_favorite(service, true);
9355 reply_pending(service, 0);
9357 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
9358 connman_network_get_bool(service->network,
9362 pass = connman_network_get_string(service->network,
9365 __connman_service_set_passphrase(service, pass);
9367 connman_network_set_bool(service->network,
9368 "WiFi.UseWPS", false);
9371 gettimeofday(&service->modified, NULL);
9372 service_save(service);
9374 domain_changed(service);
9375 proxy_changed(service);
9377 if (old_state != CONNMAN_SERVICE_STATE_ONLINE)
9378 __connman_notifier_connect(service->type);
9380 method = __connman_ipconfig_get_method(service->ipconfig_ipv6);
9381 if (method == CONNMAN_IPCONFIG_METHOD_OFF)
9382 __connman_ipconfig_disable_ipv6(
9383 service->ipconfig_ipv6);
9385 #if !defined TIZEN_MAINTAIN_ONLINE
9386 if (connman_setting_get_bool("SingleConnectedTechnology"))
9387 single_connected_tech(service);
9388 else if (service->type != CONNMAN_SERVICE_TYPE_VPN)
9391 if (service->type != CONNMAN_SERVICE_TYPE_VPN)
9395 #if defined TIZEN_EXT
9396 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
9397 set_priority_connected_service();
9402 case CONNMAN_SERVICE_STATE_ONLINE:
9403 #if defined TIZEN_MAINTAIN_ONLINE
9404 #if defined TIZEN_EXT
9405 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
9406 set_priority_connected_service();
9409 if (connman_setting_get_bool("SingleConnectedTechnology"))
9410 single_connected_tech(service);
9413 #if defined TIZEN_EXT_INS
9414 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
9415 connman_service_set_internet_connection(service, true);
9419 case CONNMAN_SERVICE_STATE_DISCONNECT:
9420 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
9422 reply_pending(service, ECONNABORTED);
9426 __connman_wispr_stop(service);
9428 __connman_wpad_stop(service);
9430 #if defined TIZEN_EXT
9432 * Skip the functions if there is any connected profiles
9433 * that use same interface
9435 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
9436 __connman_service_get_connected_count_of_iface(
9439 domain_changed(service);
9440 proxy_changed(service);
9441 #if defined TIZEN_EXT
9444 emit_wifi_roaming_failure(service, new_state);
9448 * Previous services which are connected and which states
9449 * are set to online should reset relevantly ipconfig_state
9450 * to ready so wispr/portal will be rerun on those
9452 downgrade_connected_services();
9454 do_auto_connect(service, CONNMAN_SERVICE_CONNECT_REASON_AUTO);
9457 case CONNMAN_SERVICE_STATE_FAILURE:
9458 #if defined TIZEN_EXT
9459 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
9461 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
9463 if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
9464 connman_agent_report_error(service, service->path,
9465 error2string(service->error),
9467 get_dbus_sender(service),
9469 #if !defined TIZEN_EXT
9473 service_complete(service);
9477 service_list_sort();
9479 #if defined TIZEN_EXT
9480 #if defined TIZEN_MAINTAIN_ONLINE
9481 __connman_service_connect_default(service, old_state);
9483 __connman_service_connect_default(service);
9485 emit_wifi_roaming_failure(service, new_state);
9488 __connman_connection_update_gateway();
9490 #if !defined TIZEN_EXT
9493 if ((old_state == CONNMAN_SERVICE_STATE_ONLINE &&
9494 new_state != CONNMAN_SERVICE_STATE_READY) ||
9495 (old_state == CONNMAN_SERVICE_STATE_READY &&
9496 new_state != CONNMAN_SERVICE_STATE_ONLINE)) {
9497 __connman_notifier_disconnect(service->type);
9500 if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
9501 __connman_notifier_enter_online(service->type);
9508 int __connman_service_indicate_error(struct connman_service *service,
9509 enum connman_service_error error)
9511 DBG("service %p error %d", service, error);
9516 if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
9519 #if defined TIZEN_EXT
9521 * change connman_service_error type
9522 * from CONNMAN_SERVICE_ERROR_AUTH_FAILED to CONNMAN_SERVICE_ERROR_INVALID_KEY
9523 * in case of SAE security type.
9525 if (error == CONNMAN_SERVICE_ERROR_AUTH_FAILED &&
9526 service->security == CONNMAN_SERVICE_SECURITY_SAE) {
9527 DBG("SAE security auth failed, set error to invalid-key and ignore the service");
9528 error = CONNMAN_SERVICE_ERROR_INVALID_KEY;
9529 __connman_service_set_ignore(service, true);
9533 set_error(service, error);
9535 /* default internet service: fix not cleared if pdp activation*/
9536 #if defined TIZEN_EXT
9538 * If connection failed for default service(DefaultInternet),
9539 * default_connecting_device should be cleared.
9541 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
9542 service->error == CONNMAN_SERVICE_ERROR_CONNECT_FAILED)
9543 __connman_service_disconnect_default(service);
9545 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
9546 service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) {
9547 g_free(service->passphrase);
9548 service->passphrase = NULL;
9552 __connman_service_ipconfig_indicate_state(service,
9553 CONNMAN_SERVICE_STATE_FAILURE,
9554 CONNMAN_IPCONFIG_TYPE_IPV4);
9555 __connman_service_ipconfig_indicate_state(service,
9556 CONNMAN_SERVICE_STATE_FAILURE,
9557 CONNMAN_IPCONFIG_TYPE_IPV6);
9561 int __connman_service_clear_error(struct connman_service *service)
9563 DBusMessage *pending, *provider_pending;
9565 DBG("service %p", service);
9570 if (service->state != CONNMAN_SERVICE_STATE_FAILURE)
9573 pending = service->pending;
9574 service->pending = NULL;
9575 provider_pending = service->provider_pending;
9576 service->provider_pending = NULL;
9578 __connman_service_ipconfig_indicate_state(service,
9579 CONNMAN_SERVICE_STATE_IDLE,
9580 CONNMAN_IPCONFIG_TYPE_IPV6);
9582 __connman_service_ipconfig_indicate_state(service,
9583 CONNMAN_SERVICE_STATE_IDLE,
9584 CONNMAN_IPCONFIG_TYPE_IPV4);
9586 service->pending = pending;
9587 service->provider_pending = provider_pending;
9592 int __connman_service_indicate_default(struct connman_service *service)
9594 DBG("service %p state %s", service, state2string(service->state));
9596 if (!is_connected(service->state)) {
9598 * If service is not yet fully connected, then we must not
9599 * change the default yet. The default gw will be changed
9600 * after the service state is in ready.
9602 return -EINPROGRESS;
9610 enum connman_service_state __connman_service_ipconfig_get_state(
9611 struct connman_service *service,
9612 enum connman_ipconfig_type type)
9615 return CONNMAN_SERVICE_STATE_UNKNOWN;
9617 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
9618 return service->state_ipv4;
9620 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
9621 return service->state_ipv6;
9623 return CONNMAN_SERVICE_STATE_UNKNOWN;
9626 #if defined TIZEN_EXT
9627 void connman_check_proxy_setup_and_wispr_start(struct connman_service *service){
9629 DBG("check the proxy and start wispr");
9630 check_proxy_setup(service);
9636 * How many networks are connected at the same time. If more than 1,
9637 * then set the rp_filter setting properly (loose mode routing) so that network
9638 * connectivity works ok. This is only done for IPv4 networks as IPv6
9639 * does not have rp_filter knob.
9641 static int connected_networks_count;
9642 static int original_rp_filter;
9644 static void service_rp_filter(struct connman_service *service,
9647 enum connman_ipconfig_method method;
9649 method = __connman_ipconfig_get_method(service->ipconfig_ipv4);
9652 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
9653 case CONNMAN_IPCONFIG_METHOD_OFF:
9654 case CONNMAN_IPCONFIG_METHOD_AUTO:
9656 case CONNMAN_IPCONFIG_METHOD_FIXED:
9657 case CONNMAN_IPCONFIG_METHOD_MANUAL:
9658 case CONNMAN_IPCONFIG_METHOD_DHCP:
9663 if (connected_networks_count == 1) {
9665 filter_value = __connman_ipconfig_set_rp_filter();
9666 if (filter_value < 0)
9669 original_rp_filter = filter_value;
9671 connected_networks_count++;
9674 if (connected_networks_count == 2)
9675 __connman_ipconfig_unset_rp_filter(original_rp_filter);
9677 connected_networks_count--;
9678 if (connected_networks_count < 0)
9679 connected_networks_count = 0;
9682 DBG("%s %s ipconfig %p method %d count %d filter %d",
9683 connected ? "connected" : "disconnected", service->identifier,
9684 service->ipconfig_ipv4, method,
9685 connected_networks_count, original_rp_filter);
9688 static void redo_wispr(struct connman_service *service,
9689 enum connman_ipconfig_type type)
9691 service->online_timeout = 0;
9692 connman_service_unref(service);
9694 DBG("Retrying %s WISPr for %p %s",
9695 __connman_ipconfig_type2string(type),
9696 service, service->name);
9698 __connman_wispr_start(service, type);
9701 static gboolean redo_wispr_ipv4(gpointer user_data)
9703 struct connman_service *service = user_data;
9705 #if defined TIZEN_MAINTAIN_ONLINE
9708 __connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
9710 redo_wispr(service, CONNMAN_IPCONFIG_TYPE_IPV4);
9716 static gboolean redo_wispr_ipv6(gpointer user_data)
9718 struct connman_service *service = user_data;
9720 redo_wispr(service, CONNMAN_IPCONFIG_TYPE_IPV6);
9725 void __connman_service_online_check(struct connman_service *service,
9726 enum connman_ipconfig_type type,
9729 GSourceFunc redo_func;
9730 unsigned int *interval;
9731 enum connman_service_state current_state;
9733 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
9734 interval = &service->online_check_interval_ipv4;
9735 redo_func = redo_wispr_ipv4;
9737 interval = &service->online_check_interval_ipv6;
9738 redo_func = redo_wispr_ipv6;
9741 if(!enable_online_to_ready_transition)
9745 *interval = online_check_max_interval;
9747 current_state = service->state;
9748 downgrade_state(service);
9749 if (current_state != service->state)
9750 *interval = online_check_initial_interval;
9751 if (service != connman_service_get_default()) {
9757 DBG("service %p type %s interval %d", service,
9758 __connman_ipconfig_type2string(type), *interval);
9760 service->online_timeout = g_timeout_add_seconds(*interval * *interval,
9761 redo_func, connman_service_ref(service));
9763 /* Increment the interval for the next time, set a maximum timeout of
9764 * online_check_max_interval seconds * online_check_max_interval seconds.
9766 if (*interval < online_check_max_interval)
9770 int __connman_service_ipconfig_indicate_state(struct connman_service *service,
9771 enum connman_service_state new_state,
9772 enum connman_ipconfig_type type)
9774 struct connman_ipconfig *ipconfig = NULL;
9775 enum connman_service_state old_state;
9776 enum connman_ipconfig_method method;
9782 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
9783 case CONNMAN_IPCONFIG_TYPE_ALL:
9786 case CONNMAN_IPCONFIG_TYPE_IPV4:
9787 old_state = service->state_ipv4;
9788 ipconfig = service->ipconfig_ipv4;
9792 case CONNMAN_IPCONFIG_TYPE_IPV6:
9793 old_state = service->state_ipv6;
9794 ipconfig = service->ipconfig_ipv6;
9802 method = __connman_ipconfig_get_method(ipconfig);
9805 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
9806 case CONNMAN_IPCONFIG_METHOD_OFF:
9807 if (new_state != CONNMAN_SERVICE_STATE_IDLE)
9808 connman_warn("ipconfig state %d ipconfig method %d",
9811 #if defined TIZEN_EXT
9812 if (old_state != CONNMAN_SERVICE_STATE_READY &&
9813 old_state != CONNMAN_SERVICE_STATE_ONLINE)
9815 new_state = CONNMAN_SERVICE_STATE_IDLE;
9818 case CONNMAN_IPCONFIG_METHOD_FIXED:
9819 case CONNMAN_IPCONFIG_METHOD_MANUAL:
9820 case CONNMAN_IPCONFIG_METHOD_DHCP:
9821 case CONNMAN_IPCONFIG_METHOD_AUTO:
9827 if (old_state == new_state)
9830 #if defined TIZEN_EXT
9831 __sync_synchronize();
9832 if (service->user_pdn_connection_refcount > 0 &&
9833 service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
9834 if (new_state == CONNMAN_SERVICE_STATE_FAILURE ||
9835 new_state == CONNMAN_SERVICE_STATE_DISCONNECT ||
9836 new_state == CONNMAN_SERVICE_STATE_IDLE) {
9837 service->user_pdn_connection_refcount = 0;
9838 __sync_synchronize();
9842 DBG("service %p (%s) old state %d (%s) new state %d (%s) type %d (%s)",
9843 service, service ? service->identifier : NULL,
9844 old_state, state2string(old_state),
9845 new_state, state2string(new_state),
9846 type, __connman_ipconfig_type2string(type));
9848 switch (new_state) {
9849 case CONNMAN_SERVICE_STATE_UNKNOWN:
9850 case CONNMAN_SERVICE_STATE_ASSOCIATION:
9852 case CONNMAN_SERVICE_STATE_CONFIGURATION:
9854 case CONNMAN_SERVICE_STATE_READY:
9855 #if defined TIZEN_EXT
9856 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
9857 __connman_service_is_internet_profile(service) != TRUE) {
9858 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
9859 service_rp_filter(service, TRUE);
9864 if (connman_setting_get_bool("EnableOnlineCheck"))
9865 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
9866 #if !defined TIZEN_EXT
9867 check_proxy_setup(service);
9869 #if defined TIZEN_MAINTAIN_ONLINE
9870 /* if (old_state == CONNMAN_SERVICE_STATE_ONLINE) */
9871 check_proxy_setup(service);
9874 __connman_service_wispr_start(service, type);
9877 connman_info("Online check disabled. "
9878 "Default service remains in READY state.");
9879 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
9880 service_rp_filter(service, true);
9881 set_mdns(service, service->mdns_config);
9883 case CONNMAN_SERVICE_STATE_ONLINE:
9885 case CONNMAN_SERVICE_STATE_DISCONNECT:
9886 if (service->state == CONNMAN_SERVICE_STATE_IDLE)
9889 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
9890 service_rp_filter(service, false);
9894 case CONNMAN_SERVICE_STATE_IDLE:
9895 case CONNMAN_SERVICE_STATE_FAILURE:
9896 __connman_ipconfig_disable(ipconfig);
9901 if (is_connected(old_state) && !is_connected(new_state)) {
9902 nameserver_remove_all(service, type);
9903 cancel_online_check(service);
9906 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
9907 service->state_ipv4 = new_state;
9909 service->state_ipv6 = new_state;
9911 if (!is_connected(old_state) && is_connected(new_state))
9912 nameserver_add_all(service, type);
9914 __connman_timeserver_sync(service);
9916 #if defined TIZEN_EXT
9917 int ret = service_indicate_state(service);
9918 /*Sent the Ready changed signal again in case IPv4 IP set
9921 if(ret == -EALREADY && type == CONNMAN_IPCONFIG_TYPE_IPV4
9922 && new_state == CONNMAN_SERVICE_STATE_READY) {
9923 DBG("Notify IPv4 state new/old %d/%d", new_state,old_state);
9924 state_changed(service);
9929 return service_indicate_state(service);
9932 static bool prepare_network(struct connman_service *service)
9934 enum connman_network_type type;
9935 unsigned int ssid_len;
9937 type = connman_network_get_type(service->network);
9940 case CONNMAN_NETWORK_TYPE_UNKNOWN:
9941 case CONNMAN_NETWORK_TYPE_VENDOR:
9943 case CONNMAN_NETWORK_TYPE_WIFI:
9944 if (!connman_network_get_blob(service->network, "WiFi.SSID",
9948 if (service->passphrase)
9949 connman_network_set_string(service->network,
9950 "WiFi.Passphrase", service->passphrase);
9952 case CONNMAN_NETWORK_TYPE_ETHERNET:
9953 case CONNMAN_NETWORK_TYPE_GADGET:
9954 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
9955 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
9956 case CONNMAN_NETWORK_TYPE_CELLULAR:
9963 static void prepare_8021x(struct connman_service *service)
9966 connman_network_set_string(service->network, "WiFi.EAP",
9969 if (service->identity)
9970 connman_network_set_string(service->network, "WiFi.Identity",
9973 if (service->anonymous_identity)
9974 connman_network_set_string(service->network,
9975 "WiFi.AnonymousIdentity",
9976 service->anonymous_identity);
9978 if (service->ca_cert_file)
9979 connman_network_set_string(service->network, "WiFi.CACertFile",
9980 service->ca_cert_file);
9982 if (service->subject_match)
9983 connman_network_set_string(service->network, "WiFi.SubjectMatch",
9984 service->subject_match);
9986 if (service->altsubject_match)
9987 connman_network_set_string(service->network, "WiFi.AltSubjectMatch",
9988 service->altsubject_match);
9990 if (service->domain_suffix_match)
9991 connman_network_set_string(service->network, "WiFi.DomainSuffixMatch",
9992 service->domain_suffix_match);
9994 if (service->domain_match)
9995 connman_network_set_string(service->network, "WiFi.DomainMatch",
9996 service->domain_match);
9998 if (service->client_cert_file)
9999 connman_network_set_string(service->network,
10000 "WiFi.ClientCertFile",
10001 service->client_cert_file);
10003 if (service->private_key_file)
10004 connman_network_set_string(service->network,
10005 "WiFi.PrivateKeyFile",
10006 service->private_key_file);
10008 if (service->private_key_passphrase)
10009 connman_network_set_string(service->network,
10010 "WiFi.PrivateKeyPassphrase",
10011 service->private_key_passphrase);
10013 if (service->phase2)
10014 connman_network_set_string(service->network, "WiFi.Phase2",
10017 #if defined TIZEN_EXT
10018 if (service->keymgmt_type)
10019 connman_network_set_string(service->network, "WiFi.KeymgmtType",
10020 service->keymgmt_type);
10022 DBG("service->phase1 : %s", service->phase1);
10023 if (service->phase1)
10024 connman_network_set_string(service->network, "WiFi.Phase1",
10029 #if defined TIZEN_EXT
10030 static bool has_valid_configuration_object(struct connman_service *service)
10032 return service->connector && service->c_sign_key && service->net_access_key;
10035 static void prepare_dpp(struct connman_service *service)
10037 DBG("prepare dpp");
10038 if (service->connector)
10039 connman_network_set_string(service->network, "WiFi.Connector",
10040 service->connector);
10042 if (service->c_sign_key)
10043 connman_network_set_string(service->network, "WiFi.CSignKey",
10044 service->c_sign_key);
10046 if (service->net_access_key)
10047 connman_network_set_string(service->network, "WiFi.NetAccessKey",
10048 service->net_access_key);
10052 static int service_connect(struct connman_service *service)
10056 if (service->hidden)
10059 #if defined TIZEN_EXT
10063 index = __connman_service_get_index(service);
10065 for (list = service_list; list; list = list->next) {
10066 struct connman_service *temp = list->data;
10068 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
10071 if (!is_connecting(temp->state) && !is_connected(temp->state))
10074 if (service == temp)
10077 if (service->type != temp->type)
10080 if (__connman_service_get_index(temp) == index &&
10081 __connman_service_disconnect(temp) == -EINPROGRESS)
10082 return -EINPROGRESS;
10086 switch (service->type) {
10087 case CONNMAN_SERVICE_TYPE_UNKNOWN:
10088 case CONNMAN_SERVICE_TYPE_SYSTEM:
10089 case CONNMAN_SERVICE_TYPE_GPS:
10090 case CONNMAN_SERVICE_TYPE_P2P:
10091 #if defined TIZEN_EXT_WIFI_MESH
10092 case CONNMAN_SERVICE_TYPE_MESH:
10095 case CONNMAN_SERVICE_TYPE_ETHERNET:
10096 case CONNMAN_SERVICE_TYPE_GADGET:
10097 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
10098 case CONNMAN_SERVICE_TYPE_CELLULAR:
10099 case CONNMAN_SERVICE_TYPE_VPN:
10101 case CONNMAN_SERVICE_TYPE_WIFI:
10102 switch (service->security) {
10103 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
10104 case CONNMAN_SERVICE_SECURITY_NONE:
10105 #if defined TIZEN_EXT
10106 case CONNMAN_SERVICE_SECURITY_OWE:
10109 case CONNMAN_SERVICE_SECURITY_WEP:
10110 case CONNMAN_SERVICE_SECURITY_PSK:
10111 case CONNMAN_SERVICE_SECURITY_WPA:
10112 case CONNMAN_SERVICE_SECURITY_RSN:
10113 #if defined TIZEN_EXT
10114 case CONNMAN_SERVICE_SECURITY_SAE:
10116 if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
10119 if (!service->passphrase) {
10120 if (!service->network)
10121 return -EOPNOTSUPP;
10123 if (!service->wps ||
10124 !connman_network_get_bool(service->network, "WiFi.UseWPS"))
10129 #if defined TIZEN_EXT
10130 case CONNMAN_SERVICE_SECURITY_DPP:
10131 if (has_valid_configuration_object(service) &&
10136 case CONNMAN_SERVICE_SECURITY_8021X:
10137 if (!service->eap) {
10138 connman_warn("EAP type has not been found. "
10139 "Most likely ConnMan is not able to "
10140 "find a configuration for given "
10142 "Check SSID or Name match with the "
10147 #if defined TIZEN_EXT
10149 * never request credentials if using EAP-TLS, EAP-SIM
10150 * or EAP-AKA (EAP-TLS, EAP-SIM and EAP-AKA networks
10151 * need to be fully provisioned)
10153 DBG("service eap: %s", service->eap);
10154 if (g_str_equal(service->eap, "tls") ||
10155 g_str_equal(service->eap, "sim") ||
10156 g_str_equal(service->eap, "aka") ||
10157 g_str_equal(service->eap, "aka'") ||
10158 g_str_equal(service->eap, "pwd") ||
10159 g_str_equal(service->eap, "fast"))
10163 * never request credentials if using EAP-TLS
10164 * (EAP-TLS networks need to be fully provisioned)
10166 if (g_str_equal(service->eap, "tls"))
10171 * Return -ENOKEY if either identity or passphrase is
10172 * missing. Agent provided credentials can be used as
10173 * fallback if needed.
10175 if (((!service->identity &&
10176 !service->agent_identity) ||
10177 !service->passphrase) ||
10178 service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
10182 #if defined TIZEN_EXT
10190 if (service->network) {
10191 if (!prepare_network(service))
10194 switch (service->security) {
10195 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
10196 case CONNMAN_SERVICE_SECURITY_NONE:
10197 case CONNMAN_SERVICE_SECURITY_WEP:
10198 case CONNMAN_SERVICE_SECURITY_PSK:
10199 case CONNMAN_SERVICE_SECURITY_WPA:
10200 case CONNMAN_SERVICE_SECURITY_RSN:
10201 #if defined TIZEN_EXT
10202 case CONNMAN_SERVICE_SECURITY_SAE:
10203 case CONNMAN_SERVICE_SECURITY_OWE:
10205 case CONNMAN_SERVICE_SECURITY_DPP:
10206 prepare_dpp(service);
10209 case CONNMAN_SERVICE_SECURITY_8021X:
10210 prepare_8021x(service);
10212 #if defined TIZEN_EXT
10218 if (__connman_stats_service_register(service) == 0) {
10219 __connman_stats_get(service, false,
10220 &service->stats.data);
10221 __connman_stats_get(service, true,
10222 &service->stats_roaming.data);
10225 err = __connman_network_connect(service->network);
10226 } else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
10228 err = __connman_provider_connect(service->provider,
10229 get_dbus_sender(service));
10231 return -EOPNOTSUPP;
10234 if (err != -EINPROGRESS) {
10235 __connman_service_ipconfig_indicate_state(service,
10236 CONNMAN_SERVICE_STATE_FAILURE,
10237 CONNMAN_IPCONFIG_TYPE_IPV4);
10238 __connman_service_ipconfig_indicate_state(service,
10239 CONNMAN_SERVICE_STATE_FAILURE,
10240 CONNMAN_IPCONFIG_TYPE_IPV6);
10241 __connman_stats_service_unregister(service);
10248 int __connman_service_connect(struct connman_service *service,
10249 enum connman_service_connect_reason reason)
10253 DBG("service %p state %s connect reason %s -> %s",
10254 service, state2string(service->state),
10255 reason2string(service->connect_reason),
10256 reason2string(reason));
10258 if (is_connected(service->state))
10261 if (is_connecting(service->state))
10264 switch (service->type) {
10265 case CONNMAN_SERVICE_TYPE_UNKNOWN:
10266 case CONNMAN_SERVICE_TYPE_SYSTEM:
10267 case CONNMAN_SERVICE_TYPE_GPS:
10268 case CONNMAN_SERVICE_TYPE_P2P:
10269 #if defined TIZEN_EXT_WIFI_MESH
10270 case CONNMAN_SERVICE_TYPE_MESH:
10274 case CONNMAN_SERVICE_TYPE_ETHERNET:
10275 case CONNMAN_SERVICE_TYPE_GADGET:
10276 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
10277 case CONNMAN_SERVICE_TYPE_CELLULAR:
10278 case CONNMAN_SERVICE_TYPE_VPN:
10279 case CONNMAN_SERVICE_TYPE_WIFI:
10283 if (!is_ipconfig_usable(service))
10286 __connman_service_clear_error(service);
10288 if (service->network && service->autoconnect &&
10289 __connman_network_native_autoconnect(service->network)) {
10290 DBG("service %p switch connecting reason to native", service);
10291 reason = CONNMAN_SERVICE_CONNECT_REASON_NATIVE;
10294 err = service_connect(service);
10296 DBG("service %p err %d", service, err);
10298 service->connect_reason = reason;
10299 #if defined TIZEN_EXT
10300 connect_reason_changed(service);
10306 if (err == -EINPROGRESS) {
10307 if (service->timeout == 0)
10308 service->timeout = g_timeout_add_seconds(
10309 CONNECT_TIMEOUT, connect_timeout, service);
10311 return -EINPROGRESS;
10314 if (service->network)
10315 __connman_network_disconnect(service->network);
10316 else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
10318 connman_provider_disconnect(service->provider);
10320 if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
10321 if (err == -ENOKEY || err == -EPERM) {
10322 DBusMessage *pending = NULL;
10323 const char *dbus_sender = get_dbus_sender(service);
10326 * We steal the reply here. The idea is that the
10327 * connecting client will see the connection status
10328 * after the real hidden network is connected or
10329 * connection failed.
10331 if (service->hidden) {
10332 pending = service->pending;
10333 service->pending = NULL;
10336 err = __connman_agent_request_passphrase_input(service,
10340 if (service->hidden && err != -EINPROGRESS)
10341 service->pending = pending;
10350 int __connman_service_disconnect(struct connman_service *service)
10354 DBG("service %p", service);
10356 service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
10357 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
10359 connman_agent_cancel(service);
10361 __connman_stats_service_unregister(service);
10363 if (service->network) {
10364 err = __connman_network_disconnect(service->network);
10365 } else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
10367 err = connman_provider_disconnect(service->provider);
10369 return -EOPNOTSUPP;
10371 if (err < 0 && err != -EINPROGRESS)
10374 __connman_6to4_remove(service->ipconfig_ipv4);
10376 if (service->ipconfig_ipv4)
10377 __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv4,
10380 __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv6,
10383 #if defined TIZEN_EXT
10385 * Skip the functions If there is any connected profiles
10386 * that use same interface
10388 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
10389 __connman_service_get_connected_count_of_iface(service) <= 0) {
10391 __connman_ipconfig_address_remove(service->ipconfig_ipv4);
10392 settings_changed(service, service->ipconfig_ipv4);
10394 __connman_ipconfig_address_remove(service->ipconfig_ipv6);
10395 settings_changed(service, service->ipconfig_ipv6);
10397 __connman_ipconfig_disable(service->ipconfig_ipv4);
10398 __connman_ipconfig_disable(service->ipconfig_ipv6);
10399 #if defined TIZEN_EXT
10406 int __connman_service_disconnect_all(void)
10408 struct connman_service *service;
10409 GSList *services = NULL, *list;
10414 for (iter = service_list; iter; iter = iter->next) {
10415 service = iter->data;
10417 if (!is_connected(service->state))
10420 services = g_slist_prepend(services, service);
10423 for (list = services; list; list = list->next) {
10424 struct connman_service *service = list->data;
10426 service->ignore = true;
10428 __connman_service_disconnect(service);
10431 g_slist_free(services);
10437 * lookup_by_identifier:
10438 * @identifier: service identifier
10440 * Look up a service by identifier (reference count will not be increased)
10442 static struct connman_service *lookup_by_identifier(const char *identifier)
10444 return g_hash_table_lookup(service_hash, identifier);
10447 struct connman_service *connman_service_lookup_from_identifier(const char* identifier)
10449 return identifier ? lookup_by_identifier(identifier) : NULL;
10452 struct provision_user_data {
10457 static void provision_changed(gpointer value, gpointer user_data)
10459 struct connman_service *service = value;
10460 struct provision_user_data *data = user_data;
10461 const char *path = data->ident;
10464 ret = __connman_config_provision_service_ident(service, path,
10465 service->config_file, service->config_entry);
10470 int __connman_service_provision_changed(const char *ident)
10472 struct provision_user_data data = {
10477 g_list_foreach(service_list, provision_changed, (void *)&data);
10480 * Because the provision_changed() might have set some services
10481 * as favorite, we must sort the sequence now.
10483 if (services_dirty) {
10484 services_dirty = false;
10486 service_list_sort();
10488 __connman_connection_update_gateway();
10494 void __connman_service_set_config(struct connman_service *service,
10495 const char *file_id, const char *entry)
10500 g_free(service->config_file);
10501 service->config_file = g_strdup(file_id);
10503 g_free(service->config_entry);
10504 service->config_entry = g_strdup(entry);
10508 * __connman_service_get:
10509 * @identifier: service identifier
10511 * Look up a service by identifier or create a new one if not found
10513 static struct connman_service *service_get(const char *identifier)
10515 struct connman_service *service;
10517 service = g_hash_table_lookup(service_hash, identifier);
10519 connman_service_ref(service);
10523 service = connman_service_create();
10526 #if defined TIZEN_EXT
10527 if (!simplified_log)
10529 DBG("service %p", service);
10531 service->identifier = g_strdup(identifier);
10533 service_list = g_list_insert_sorted(service_list, service,
10536 g_hash_table_insert(service_hash, service->identifier, service);
10541 static int service_register(struct connman_service *service)
10543 #if defined TIZEN_EXT
10544 if (!simplified_log)
10546 DBG("service %p", service);
10551 service->path = g_strdup_printf("%s/service/%s", CONNMAN_PATH,
10552 service->identifier);
10554 DBG("path %s", service->path);
10556 #if defined TIZEN_EXT
10558 service_load(service);
10559 #if defined TIZEN_EXT_INS
10560 ret = service_ext_load(service);
10561 if (ret == -ERANGE)
10562 service_ext_save(service);
10563 #endif /* defined TIZEN_EXT_INS */
10564 ret = __connman_config_provision_service(service);
10565 if (ret < 0 && !simplified_log)
10566 DBG("Failed to provision service");
10568 if (__connman_config_provision_service(service) < 0)
10569 service_load(service);
10570 #endif /* defined TIZEN_EXT */
10572 g_dbus_register_interface(connection, service->path,
10573 CONNMAN_SERVICE_INTERFACE,
10574 service_methods, service_signals,
10575 NULL, service, NULL);
10577 if (__connman_config_provision_service(service) < 0)
10578 service_load(service);
10580 service_list_sort();
10582 __connman_connection_update_gateway();
10587 static void service_up(struct connman_ipconfig *ipconfig,
10588 const char *ifname)
10590 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
10592 DBG("%s up", ifname);
10594 link_changed(service);
10596 service->stats.valid = false;
10597 service->stats_roaming.valid = false;
10600 static void service_down(struct connman_ipconfig *ipconfig,
10601 const char *ifname)
10603 DBG("%s down", ifname);
10606 static void service_lower_up(struct connman_ipconfig *ipconfig,
10607 const char *ifname)
10609 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
10611 DBG("%s lower up", ifname);
10613 stats_start(service);
10616 static void service_lower_down(struct connman_ipconfig *ipconfig,
10617 const char *ifname)
10619 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
10621 DBG("%s lower down", ifname);
10623 stats_stop(service);
10624 service_save(service);
10627 static void service_ip_bound(struct connman_ipconfig *ipconfig,
10628 const char *ifname)
10630 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
10631 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
10632 enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
10633 #if defined TIZEN_EXT
10637 DBG("%s ip bound", ifname);
10639 type = __connman_ipconfig_get_config_type(ipconfig);
10640 method = __connman_ipconfig_get_method(ipconfig);
10642 DBG("service %p ipconfig %p type %d method %d", service, ipconfig,
10645 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
10646 method == CONNMAN_IPCONFIG_METHOD_AUTO)
10647 #if defined TIZEN_EXT
10649 err = __connman_ipconfig_gateway_add(ipconfig, service);
10652 DBG("Failed to add gateway");
10655 __connman_service_ipconfig_indicate_state(service,
10656 CONNMAN_SERVICE_STATE_READY,
10657 CONNMAN_IPCONFIG_TYPE_IPV6);
10660 settings_changed(service, ipconfig);
10661 address_updated(service, type);
10664 static void service_ip_release(struct connman_ipconfig *ipconfig,
10665 const char *ifname)
10667 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
10668 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
10669 enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
10671 DBG("%s ip release", ifname);
10673 type = __connman_ipconfig_get_config_type(ipconfig);
10674 method = __connman_ipconfig_get_method(ipconfig);
10676 DBG("service %p ipconfig %p type %d method %d", service, ipconfig,
10679 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
10680 method == CONNMAN_IPCONFIG_METHOD_OFF)
10681 __connman_service_ipconfig_indicate_state(service,
10682 CONNMAN_SERVICE_STATE_DISCONNECT,
10683 CONNMAN_IPCONFIG_TYPE_IPV6);
10685 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
10686 method == CONNMAN_IPCONFIG_METHOD_OFF)
10687 __connman_service_ipconfig_indicate_state(service,
10688 CONNMAN_SERVICE_STATE_DISCONNECT,
10689 CONNMAN_IPCONFIG_TYPE_IPV4);
10691 settings_changed(service, ipconfig);
10694 static void service_route_changed(struct connman_ipconfig *ipconfig,
10695 const char *ifname)
10697 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
10699 DBG("%s route changed", ifname);
10701 settings_changed(service, ipconfig);
10704 static const struct connman_ipconfig_ops service_ops = {
10706 .down = service_down,
10707 .lower_up = service_lower_up,
10708 .lower_down = service_lower_down,
10709 .ip_bound = service_ip_bound,
10710 .ip_release = service_ip_release,
10711 .route_set = service_route_changed,
10712 .route_unset = service_route_changed,
10715 static struct connman_ipconfig *create_ip4config(struct connman_service *service,
10716 int index, enum connman_ipconfig_method method)
10718 struct connman_ipconfig *ipconfig_ipv4;
10720 ipconfig_ipv4 = __connman_ipconfig_create(index,
10721 CONNMAN_IPCONFIG_TYPE_IPV4);
10722 if (!ipconfig_ipv4)
10725 __connman_ipconfig_set_method(ipconfig_ipv4, method);
10727 __connman_ipconfig_set_data(ipconfig_ipv4, service);
10729 __connman_ipconfig_set_ops(ipconfig_ipv4, &service_ops);
10731 return ipconfig_ipv4;
10734 static struct connman_ipconfig *create_ip6config(struct connman_service *service,
10737 struct connman_ipconfig *ipconfig_ipv6;
10739 ipconfig_ipv6 = __connman_ipconfig_create(index,
10740 CONNMAN_IPCONFIG_TYPE_IPV6);
10741 if (!ipconfig_ipv6)
10744 __connman_ipconfig_set_data(ipconfig_ipv6, service);
10746 __connman_ipconfig_set_ops(ipconfig_ipv6, &service_ops);
10748 return ipconfig_ipv6;
10751 void __connman_service_read_ip4config(struct connman_service *service)
10755 if (!service->ipconfig_ipv4)
10758 keyfile = connman_storage_load_service(service->identifier);
10762 __connman_ipconfig_load(service->ipconfig_ipv4, keyfile,
10763 service->identifier, "IPv4.");
10765 g_key_file_free(keyfile);
10768 void connman_service_create_ip4config(struct connman_service *service,
10771 DBG("ipv4 %p", service->ipconfig_ipv4);
10773 if (service->ipconfig_ipv4)
10776 service->ipconfig_ipv4 = create_ip4config(service, index,
10777 CONNMAN_IPCONFIG_METHOD_DHCP);
10778 __connman_service_read_ip4config(service);
10781 void __connman_service_read_ip6config(struct connman_service *service)
10785 if (!service->ipconfig_ipv6)
10788 keyfile = connman_storage_load_service(service->identifier);
10792 __connman_ipconfig_load(service->ipconfig_ipv6, keyfile,
10793 service->identifier, "IPv6.");
10795 g_key_file_free(keyfile);
10798 void connman_service_create_ip6config(struct connman_service *service,
10801 DBG("ipv6 %p", service->ipconfig_ipv6);
10803 if (service->ipconfig_ipv6)
10806 service->ipconfig_ipv6 = create_ip6config(service, index);
10808 __connman_service_read_ip6config(service);
10812 * connman_service_lookup_from_network:
10813 * @network: network structure
10815 * Look up a service by network (reference count will not be increased)
10817 struct connman_service *connman_service_lookup_from_network(struct connman_network *network)
10819 struct connman_service *service;
10820 const char *ident, *group;
10826 ident = __connman_network_get_ident(network);
10830 group = connman_network_get_group(network);
10834 name = g_strdup_printf("%s_%s_%s",
10835 __connman_network_get_type(network), ident, group);
10836 service = lookup_by_identifier(name);
10842 struct connman_service *__connman_service_lookup_from_index(int index)
10844 struct connman_service *service;
10847 for (list = service_list; list; list = list->next) {
10848 service = list->data;
10850 if (__connman_ipconfig_get_index(service->ipconfig_ipv4)
10854 if (__connman_ipconfig_get_index(service->ipconfig_ipv6)
10862 const char *connman_service_get_identifier(struct connman_service *service)
10864 return service ? service->identifier : NULL;
10867 const char *__connman_service_get_path(struct connman_service *service)
10869 return service->path;
10872 const char *__connman_service_get_name(struct connman_service *service)
10874 return service->name;
10877 enum connman_service_state connman_service_get_state(struct connman_service *service)
10879 return service ? service->state : CONNMAN_SERVICE_STATE_UNKNOWN;
10882 static enum connman_service_type convert_network_type(struct connman_network *network)
10884 enum connman_network_type type = connman_network_get_type(network);
10887 case CONNMAN_NETWORK_TYPE_UNKNOWN:
10888 case CONNMAN_NETWORK_TYPE_VENDOR:
10890 case CONNMAN_NETWORK_TYPE_ETHERNET:
10891 return CONNMAN_SERVICE_TYPE_ETHERNET;
10892 case CONNMAN_NETWORK_TYPE_WIFI:
10893 return CONNMAN_SERVICE_TYPE_WIFI;
10894 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
10895 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
10896 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
10897 case CONNMAN_NETWORK_TYPE_CELLULAR:
10898 return CONNMAN_SERVICE_TYPE_CELLULAR;
10899 case CONNMAN_NETWORK_TYPE_GADGET:
10900 return CONNMAN_SERVICE_TYPE_GADGET;
10903 return CONNMAN_SERVICE_TYPE_UNKNOWN;
10906 static enum connman_service_security convert_wifi_security(const char *security)
10909 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
10910 else if (g_str_equal(security, "none"))
10911 return CONNMAN_SERVICE_SECURITY_NONE;
10912 else if (g_str_equal(security, "wep"))
10913 return CONNMAN_SERVICE_SECURITY_WEP;
10914 else if (g_str_equal(security, "psk"))
10915 return CONNMAN_SERVICE_SECURITY_PSK;
10916 else if (g_str_equal(security, "ieee8021x"))
10917 return CONNMAN_SERVICE_SECURITY_8021X;
10918 else if (g_str_equal(security, "wpa"))
10919 return CONNMAN_SERVICE_SECURITY_WPA;
10920 else if (g_str_equal(security, "rsn"))
10921 return CONNMAN_SERVICE_SECURITY_RSN;
10922 #if defined TIZEN_EXT
10923 else if (g_str_equal(security, "sae"))
10924 return CONNMAN_SERVICE_SECURITY_SAE;
10925 else if (g_str_equal(security, "owe"))
10926 return CONNMAN_SERVICE_SECURITY_OWE;
10927 else if (g_str_equal(security, "dpp"))
10928 return CONNMAN_SERVICE_SECURITY_DPP;
10929 else if (g_str_equal(security, "ft_psk") == TRUE)
10930 return CONNMAN_SERVICE_SECURITY_PSK;
10931 else if (g_str_equal(security, "ft_ieee8021x") == TRUE)
10932 return CONNMAN_SERVICE_SECURITY_8021X;
10935 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
10938 #if defined TIZEN_EXT
10939 int check_passphrase_ext(struct connman_network *network,
10940 const char *passphrase)
10943 enum connman_service_security security;
10945 str = connman_network_get_string(network, "WiFi.Security");
10946 security = convert_wifi_security(str);
10948 return __connman_service_check_passphrase(security, passphrase);
10952 static void update_wps_values(struct connman_service *service,
10953 struct connman_network *network)
10955 bool wps = connman_network_get_bool(network, "WiFi.WPS");
10956 bool wps_advertising = connman_network_get_bool(network,
10957 "WiFi.WPSAdvertising");
10959 if (service->wps != wps ||
10960 service->wps_advertizing != wps_advertising) {
10961 service->wps = wps;
10962 service->wps_advertizing = wps_advertising;
10963 security_changed(service);
10967 static void update_from_network(struct connman_service *service,
10968 struct connman_network *network)
10970 uint8_t strength = service->strength;
10973 DBG("service %p network %p", service, network);
10975 if (is_connected(service->state))
10978 if (is_connecting(service->state))
10981 str = connman_network_get_string(network, "Name");
10983 g_free(service->name);
10984 service->name = g_strdup(str);
10985 service->hidden = false;
10987 g_free(service->name);
10988 service->name = NULL;
10989 service->hidden = true;
10992 service->strength = connman_network_get_strength(network);
10993 service->roaming = connman_network_get_bool(network, "Roaming");
10995 if (service->strength == 0) {
10997 * Filter out 0-values; it's unclear what they mean
10998 * and they cause anomalous sorting of the priority list.
11000 service->strength = strength;
11003 str = connman_network_get_string(network, "WiFi.Security");
11004 service->security = convert_wifi_security(str);
11006 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
11007 update_wps_values(service, network);
11009 if (service->strength > strength && service->network) {
11010 connman_network_unref(service->network);
11011 service->network = connman_network_ref(network);
11013 strength_changed(service);
11016 if (!service->network)
11017 service->network = connman_network_ref(network);
11019 service_list_sort();
11022 static void trigger_autoconnect(struct connman_service *service)
11024 struct connman_device *device;
11027 if (!service->favorite)
11030 native = __connman_network_native_autoconnect(service->network);
11031 if (native && service->autoconnect) {
11032 DBG("trigger native autoconnect");
11033 connman_network_set_autoconnect(service->network, true);
11037 device = connman_network_get_device(service->network);
11038 if (device && connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_UNKNOWN))
11041 switch (service->type) {
11042 case CONNMAN_SERVICE_TYPE_UNKNOWN:
11043 case CONNMAN_SERVICE_TYPE_SYSTEM:
11044 case CONNMAN_SERVICE_TYPE_P2P:
11045 #if defined TIZEN_EXT_WIFI_MESH
11046 case CONNMAN_SERVICE_TYPE_MESH:
11050 case CONNMAN_SERVICE_TYPE_GADGET:
11051 case CONNMAN_SERVICE_TYPE_ETHERNET:
11052 if (service->autoconnect) {
11053 __connman_service_connect(service,
11054 CONNMAN_SERVICE_CONNECT_REASON_AUTO);
11059 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
11060 case CONNMAN_SERVICE_TYPE_GPS:
11061 case CONNMAN_SERVICE_TYPE_VPN:
11062 case CONNMAN_SERVICE_TYPE_WIFI:
11063 case CONNMAN_SERVICE_TYPE_CELLULAR:
11064 do_auto_connect(service, CONNMAN_SERVICE_CONNECT_REASON_AUTO);
11068 #if defined TIZEN_EXT
11069 /* TIZEN synchronizes below information when the service creates */
11070 if (service->eap != NULL)
11071 connman_network_set_string(service->network, "WiFi.EAP",
11073 if (service->identity != NULL)
11074 connman_network_set_string(service->network, "WiFi.Identity",
11075 service->identity);
11076 if (service->phase2 != NULL)
11077 connman_network_set_string(service->network, "WiFi.Phase2",
11079 if (service->eap != NULL)
11080 connman_network_set_string(service->network, "WiFi.Connector",
11081 service->connector);
11082 if (service->identity != NULL)
11083 connman_network_set_string(service->network, "WiFi.CSignKey",
11084 service->c_sign_key);
11085 if (service->phase2 != NULL)
11086 connman_network_set_string(service->network, "WiFi.NetAccessKey",
11087 service->net_access_key);
11092 * __connman_service_create_from_network:
11093 * @network: network structure
11095 * Look up service by network and if not found, create one
11097 struct connman_service * __connman_service_create_from_network(struct connman_network *network)
11099 struct connman_service *service;
11100 const char *ident, *group;
11102 unsigned int *auto_connect_types, *favorite_types;
11105 DBG("network %p", network);
11110 ident = __connman_network_get_ident(network);
11114 group = connman_network_get_group(network);
11118 name = g_strdup_printf("%s_%s_%s",
11119 __connman_network_get_type(network), ident, group);
11120 service = service_get(name);
11126 if (__connman_network_get_weakness(network))
11129 if (service->path) {
11130 update_from_network(service, network);
11131 __connman_connection_update_gateway();
11135 service->type = convert_network_type(network);
11137 auto_connect_types = connman_setting_get_uint_list("DefaultAutoConnectTechnologies");
11138 service->autoconnect = false;
11139 for (i = 0; auto_connect_types &&
11140 auto_connect_types[i] != 0; i++) {
11141 if (service->type == auto_connect_types[i]) {
11142 service->autoconnect = true;
11147 favorite_types = connman_setting_get_uint_list("DefaultFavoriteTechnologies");
11148 service->favorite = false;
11149 for (i = 0; favorite_types && favorite_types[i] != 0; i++) {
11150 if (service->type == favorite_types[i]) {
11151 service->favorite = true;
11156 service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
11157 service->state = combine_state(service->state_ipv4, service->state_ipv6);
11159 update_from_network(service, network);
11161 index = connman_network_get_index(network);
11163 if (!service->ipconfig_ipv4)
11164 service->ipconfig_ipv4 = create_ip4config(service, index,
11165 CONNMAN_IPCONFIG_METHOD_DHCP);
11167 if (!service->ipconfig_ipv6)
11168 service->ipconfig_ipv6 = create_ip6config(service, index);
11170 service_register(service);
11171 service_schedule_added(service);
11173 trigger_autoconnect(service);
11175 __connman_notifier_service_add(service, service->name);
11180 #if defined TIZEN_EXT
11181 void __connman_service_notify_strength_changed(struct connman_network *network)
11183 struct connman_service *service;
11184 uint8_t strength = 0;
11186 service = connman_service_lookup_from_network(network);
11190 if (!service->network)
11193 strength = connman_network_get_strength(service->network);
11194 if (strength == service->strength)
11197 service->strength = strength;
11198 if (!simplified_log)
11199 DBG("Strength %d", strength);
11200 strength_changed(service);
11201 service_list_sort();
11205 void __connman_service_update_from_network(struct connman_network *network)
11207 bool need_sort = false;
11208 struct connman_service *service;
11213 #if defined TIZEN_EXT_INS
11214 bool need_save = false;
11217 service = connman_service_lookup_from_network(network);
11221 if (!service->network)
11224 #if defined TIZEN_EXT
11225 if (service->storage_reload) {
11226 service_load(service);
11227 __connman_service_set_storage_reload(service, false);
11231 name = connman_network_get_string(service->network, "Name");
11232 if (g_strcmp0(service->name, name) != 0) {
11233 g_free(service->name);
11234 service->name = g_strdup(name);
11236 if (allow_property_changed(service))
11237 connman_dbus_property_changed_basic(service->path,
11238 CONNMAN_SERVICE_INTERFACE, "Name",
11239 DBUS_TYPE_STRING, &service->name);
11242 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
11243 update_wps_values(service, network);
11245 strength = connman_network_get_strength(service->network);
11246 if (strength == service->strength)
11249 service->strength = strength;
11252 strength_changed(service);
11255 roaming = connman_network_get_bool(service->network, "Roaming");
11256 if (roaming == service->roaming)
11259 stats_enable = stats_enabled(service);
11261 stats_stop(service);
11263 service->roaming = roaming;
11267 stats_start(service);
11269 roaming_changed(service);
11272 #if defined TIZEN_EXT_INS
11273 need_save |= update_last_connected_bssid(service);
11274 need_save |= update_assoc_reject(service);
11276 g_get_current_time((GTimeVal *)&service->modified);
11277 service_ext_save(service);
11283 service_list_sort();
11287 void __connman_service_remove_from_network(struct connman_network *network)
11289 struct connman_service *service;
11291 service = connman_service_lookup_from_network(network);
11293 DBG("network %p service %p", network, service);
11298 service->ignore = true;
11300 __connman_connection_gateway_remove(service,
11301 CONNMAN_IPCONFIG_TYPE_ALL);
11303 connman_service_unref(service);
11307 * __connman_service_create_from_provider:
11308 * @provider: provider structure
11310 * Look up service by provider and if not found, create one
11312 struct connman_service *
11313 __connman_service_create_from_provider(struct connman_provider *provider)
11315 struct connman_service *service;
11316 const char *ident, *str;
11318 int index = connman_provider_get_index(provider);
11320 DBG("provider %p", provider);
11322 ident = __connman_provider_get_ident(provider);
11326 name = g_strdup_printf("vpn_%s", ident);
11327 service = service_get(name);
11333 service->type = CONNMAN_SERVICE_TYPE_VPN;
11334 service->order = service->do_split_routing ? 0 : 10;
11335 service->provider = connman_provider_ref(provider);
11336 service->autoconnect = false;
11337 service->favorite = true;
11339 service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
11340 service->state = combine_state(service->state_ipv4, service->state_ipv6);
11342 str = connman_provider_get_string(provider, "Name");
11344 g_free(service->name);
11345 service->name = g_strdup(str);
11346 service->hidden = false;
11348 g_free(service->name);
11349 service->name = NULL;
11350 service->hidden = true;
11353 service->strength = 0;
11355 if (!service->ipconfig_ipv4)
11356 service->ipconfig_ipv4 = create_ip4config(service, index,
11357 CONNMAN_IPCONFIG_METHOD_MANUAL);
11359 if (!service->ipconfig_ipv6)
11360 service->ipconfig_ipv6 = create_ip6config(service, index);
11362 service_register(service);
11364 __connman_notifier_service_add(service, service->name);
11365 service_schedule_added(service);
11370 static void remove_unprovisioned_services(void)
11373 GKeyFile *keyfile, *configkeyfile;
11374 char *file, *section;
11377 services = connman_storage_get_services();
11381 for (; services[i]; i++) {
11382 file = section = NULL;
11383 keyfile = configkeyfile = NULL;
11385 keyfile = connman_storage_load_service(services[i]);
11389 file = g_key_file_get_string(keyfile, services[i],
11390 "Config.file", NULL);
11394 section = g_key_file_get_string(keyfile, services[i],
11395 "Config.ident", NULL);
11399 configkeyfile = __connman_storage_load_config(file);
11400 if (!configkeyfile) {
11402 * Config file is missing, remove the provisioned
11405 __connman_storage_remove_service(services[i]);
11409 if (!g_key_file_has_group(configkeyfile, section))
11411 * Config section is missing, remove the provisioned
11414 __connman_storage_remove_service(services[i]);
11418 g_key_file_free(keyfile);
11421 g_key_file_free(configkeyfile);
11427 g_strfreev(services);
11430 static int agent_probe(struct connman_agent *agent)
11432 DBG("agent %p", agent);
11436 static void agent_remove(struct connman_agent *agent)
11438 DBG("agent %p", agent);
11441 static void *agent_context_ref(void *context)
11443 struct connman_service *service = context;
11445 return (void *)connman_service_ref(service);
11448 static void agent_context_unref(void *context)
11450 struct connman_service *service = context;
11452 connman_service_unref(service);
11455 static struct connman_agent_driver agent_driver = {
11457 .interface = CONNMAN_AGENT_INTERFACE,
11458 .probe = agent_probe,
11459 .remove = agent_remove,
11460 .context_ref = agent_context_ref,
11461 .context_unref = agent_context_unref,
11464 #if defined TIZEN_EXT && defined TIZEN_EXT_INS
11465 static void ins_setting_init(void)
11468 const char *string;
11469 char **string_list;
11470 unsigned int string_count;
11472 ins_settings.last_user_selection = connman_setting_get_bool("INSLastUserSelection");
11473 ins_settings.last_user_selection_time = connman_setting_get_uint("INSLastUserSelectionTime");
11474 ins_settings.last_connected = connman_setting_get_bool("INSLastConnected");
11476 string = connman_setting_get_string("INSPreferredFreq");
11477 if (g_strcmp0(string, "5GHz") == 0)
11478 ins_settings.preferred_freq = CONNMAN_INS_PREFERRED_FREQ_5GHZ;
11479 else if (g_strcmp0(string, "2.4GHz") == 0)
11480 ins_settings.preferred_freq = CONNMAN_INS_PREFERRED_FREQ_24GHZ;
11482 ins_settings.preferred_freq = CONNMAN_INS_PREFERRED_FREQ_UNKNOWN;
11484 ins_settings.security_priority_count = connman_setting_get_uint("INSSecurityPriorityCount");
11485 ins_settings.security_priority_score = connman_setting_get_uint("INSSecurityPriorityScore");
11486 string_count = ins_settings.security_priority_count;
11488 memset(ins_settings.security_priority, 0, sizeof(ins_settings.security_priority));
11489 string_list = connman_setting_get_string_list("INSSecurityPriority");
11490 for (i = 0; string_list && string_list[i]; i++) {
11491 unsigned int security_score = string_count * ins_settings.security_priority_score;
11493 if (g_strcmp0(string_list[i], "WEP") == 0)
11494 ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_WEP] = security_score;
11495 else if (g_strcmp0(string_list[i], "PSK") == 0)
11496 ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_PSK] = security_score;
11497 else if (g_strcmp0(string_list[i], "8021X") == 0)
11498 ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_8021X] = security_score;
11499 else if (g_strcmp0(string_list[i], "WPA") == 0)
11500 ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_WPA] = security_score;
11501 else if (g_strcmp0(string_list[i], "RSN") == 0)
11502 ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_RSN] = security_score;
11503 else if (g_strcmp0(string_list[i], "SAE") == 0)
11504 ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_SAE] = security_score;
11505 else if (g_strcmp0(string_list[i], "OWE") == 0)
11506 ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_OWE] = security_score;
11507 else if (g_strcmp0(string_list[i], "DPP") == 0)
11508 ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_DPP] = security_score;
11513 ins_settings.signal = connman_setting_get_bool("INSSignal");
11514 ins_settings.internet = connman_setting_get_bool("INSInternet");
11516 ins_settings.last_user_selection_score = connman_setting_get_uint("INSLastUserSelectionScore");
11517 ins_settings.last_connected_score = connman_setting_get_uint("INSLastConnectedScore");
11518 ins_settings.preferred_freq_score = connman_setting_get_uint("INSPreferredFreqScore");
11519 ins_settings.internet_score = connman_setting_get_uint("INSInternetScore");
11522 * In ConnMan, signal strength is used after being converted
11523 * to positive value(signal strength + 120).
11524 * So the value for comparison should also be converted to the same.
11526 ins_settings.signal_level3_5ghz = connman_setting_get_int("INSSignalLevel3_5GHz") + 120;
11527 ins_settings.signal_level3_24ghz = connman_setting_get_int("INSSignalLevel3_24GHz") + 120;
11529 DBG("last_user_selection [%s]", ins_settings.last_user_selection ? "true" : "false");
11530 DBG("last_user_selection_time [%d]", ins_settings.last_user_selection_time);
11531 DBG("last_user_selection_score [%d]", ins_settings.last_user_selection_score);
11533 DBG("last_connected [%s]", ins_settings.last_connected ? "true" : "false");
11534 DBG("last_connected_score [%d]", ins_settings.last_connected_score);
11536 DBG("preferred_freq [%s]", ins_settings.preferred_freq ? "true" : "false");
11537 DBG("preferred_freq_score [%d]", ins_settings.preferred_freq_score);
11539 DBG("security_priority_count [%d]", ins_settings.security_priority_count);
11540 for (i = 0; i < CONNMAN_SERVICE_SECURITY_MAX; i++) {
11541 if (ins_settings.security_priority[i])
11542 DBG("security_priority %s [%d]", security2string(i),
11543 ins_settings.security_priority[i]);
11545 DBG("security_priority_score [%d]", ins_settings.security_priority_score);
11547 DBG("signal [%s]", ins_settings.signal ? "true" : "false");
11549 DBG("internet [%s]", ins_settings.internet ? "true" : "false");
11550 DBG("internet_score [%d]", ins_settings.internet_score);
11552 DBG("signal_level3_5ghz [%d]", ins_settings.signal_level3_5ghz);
11553 DBG("signal_level3_24ghz [%d]", ins_settings.signal_level3_24ghz);
11555 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
11557 int __connman_service_init(void)
11563 err = connman_agent_driver_register(&agent_driver);
11565 connman_error("Cannot register agent driver for %s",
11566 agent_driver.name);
11570 set_always_connecting_technologies();
11572 connection = connman_dbus_get_connection();
11574 service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
11575 NULL, service_free);
11577 services_notify = g_new0(struct _services_notify, 1);
11578 services_notify->remove = g_hash_table_new_full(g_str_hash,
11579 g_str_equal, g_free, NULL);
11580 services_notify->add = g_hash_table_new(g_str_hash, g_str_equal);
11582 remove_unprovisioned_services();
11584 #if defined TIZEN_EXT && defined TIZEN_EXT_INS
11585 ins_setting_init();
11586 #endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
11591 void __connman_service_cleanup(void)
11595 if (vpn_autoconnect_id) {
11596 g_source_remove(vpn_autoconnect_id);
11597 vpn_autoconnect_id = 0;
11600 if (autoconnect_id != 0) {
11601 g_source_remove(autoconnect_id);
11602 autoconnect_id = 0;
11605 connman_agent_driver_unregister(&agent_driver);
11607 g_list_free(service_list);
11608 service_list = NULL;
11610 g_hash_table_destroy(service_hash);
11611 service_hash = NULL;
11613 g_slist_free(counter_list);
11614 counter_list = NULL;
11616 if (services_notify->id != 0) {
11617 g_source_remove(services_notify->id);
11618 service_send_changed(NULL);
11621 g_hash_table_destroy(services_notify->remove);
11622 g_hash_table_destroy(services_notify->add);
11623 g_free(services_notify);
11625 dbus_connection_unref(connection);