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
34 #include <connman/storage.h>
35 #include <connman/setting.h>
36 #include <connman/agent.h>
40 #define CONNECT_TIMEOUT 120
43 #define WIFI_BSSID_STR_LEN 18
44 #define MAX_WIFI_PROFILES 200
47 static DBusConnection *connection = NULL;
49 static GList *service_list = NULL;
50 static GHashTable *service_hash = NULL;
51 static GSList *counter_list = NULL;
52 static unsigned int autoconnect_id = 0;
53 static unsigned int vpn_autoconnect_id = 0;
54 static struct connman_service *current_default = NULL;
55 static bool services_dirty = false;
58 static bool auto_connect_mode = TRUE;
60 struct saved_profiles {
67 struct connman_stats {
70 struct connman_stats_data data_last;
71 struct connman_stats_data data;
75 struct connman_stats_counter {
77 struct connman_stats stats;
78 struct connman_stats stats_roaming;
81 struct connman_service {
85 enum connman_service_type type;
86 enum connman_service_security security;
87 enum connman_service_state state;
88 enum connman_service_state state_ipv4;
89 enum connman_service_state state_ipv6;
90 enum connman_service_error error;
91 enum connman_service_connect_reason connect_reason;
103 struct connman_ipconfig *ipconfig_ipv4;
104 struct connman_ipconfig *ipconfig_ipv6;
105 struct connman_network *network;
106 struct connman_provider *provider;
108 char **nameservers_config;
109 char **nameservers_auto;
110 int nameservers_timeout;
117 char **timeservers_config;
118 /* 802.1x settings from the config files */
121 char *anonymous_identity;
122 char *agent_identity;
125 char *altsubject_match;
126 char *domain_suffix_match;
128 char *client_cert_file;
129 char *private_key_file;
130 char *private_key_passphrase;
132 DBusMessage *pending;
133 DBusMessage *provider_pending;
135 struct connman_stats stats;
136 struct connman_stats stats_roaming;
137 GHashTable *counter_table;
138 enum connman_service_proxy_method proxy;
139 enum connman_service_proxy_method proxy_config;
144 bool wps_advertizing;
145 guint online_timeout;
146 int online_check_interval_ipv4;
147 int online_check_interval_ipv6;
148 bool do_split_routing;
153 #if defined TIZEN_EXT
155 * Description: TIZEN implements system global connection management.
156 * It's only for PDP (cellular) bearer. Wi-Fi is managed
157 * by ConnMan automatically. Reference count can help to
158 * manage open/close connection requests by each application.
160 int user_pdn_connection_refcount;
163 * Description: In case of EAP security type,
164 * user can select the keymgmt type for roaming(802.11r).
165 * - FT, CCKM, OKC, ...
168 int disconnect_reason;
169 int assoc_status_code;
175 * Description: To indicate that disconnection triggered by user.
177 bool disconnection_requested;
179 enum connman_dnsconfig_method dns_config_method_ipv4;
180 enum connman_dnsconfig_method dns_config_method_ipv6;
182 #if defined TIZEN_EXT
185 char *net_access_key;
189 static bool allow_property_changed(struct connman_service *service);
191 static struct connman_ipconfig *create_ip4config(struct connman_service *service,
192 int index, enum connman_ipconfig_method method);
193 static struct connman_ipconfig *create_ip6config(struct connman_service *service,
195 static void dns_changed(struct connman_service *service);
199 struct connman_service *service;
202 #if defined TIZEN_EXT
204 * Public APIs to use user_pdn_connection_refcount
206 void connman_service_user_pdn_connection_ref(struct connman_service *service)
208 __sync_fetch_and_add(&service->user_pdn_connection_refcount, 1);
210 DBG("User made PDN connection referenced: %d",
211 service->user_pdn_connection_refcount);
214 gboolean connman_service_user_pdn_connection_unref_and_test(
215 struct connman_service *service)
217 __sync_synchronize();
219 DBG("User made PDN connection referenced: %d, which will be decreased",
220 service->user_pdn_connection_refcount);
222 if (service->user_pdn_connection_refcount < 1)
225 if (__sync_sub_and_fetch(&service->user_pdn_connection_refcount, 1) == 0)
231 gboolean connman_service_is_no_ref_user_pdn_connection(
232 struct connman_service *cellular)
234 if (cellular == NULL)
237 __sync_synchronize();
238 if (cellular->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
239 cellular->user_pdn_connection_refcount == 0)
246 static void compare_path(gpointer value, gpointer user_data)
248 struct connman_service *service = value;
249 struct find_data *data = user_data;
254 if (g_strcmp0(service->path, data->path) == 0)
255 data->service = service;
258 static struct connman_service *find_service(const char *path)
260 struct find_data data = { .path = path, .service = NULL };
262 DBG("path %s", path);
264 g_list_foreach(service_list, compare_path, &data);
269 static const char *reason2string(enum connman_service_connect_reason reason)
273 case CONNMAN_SERVICE_CONNECT_REASON_NONE:
275 case CONNMAN_SERVICE_CONNECT_REASON_USER:
277 case CONNMAN_SERVICE_CONNECT_REASON_AUTO:
279 case CONNMAN_SERVICE_CONNECT_REASON_SESSION:
286 const char *__connman_service_type2string(enum connman_service_type type)
289 case CONNMAN_SERVICE_TYPE_UNKNOWN:
291 case CONNMAN_SERVICE_TYPE_SYSTEM:
293 case CONNMAN_SERVICE_TYPE_ETHERNET:
295 case CONNMAN_SERVICE_TYPE_WIFI:
297 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
299 case CONNMAN_SERVICE_TYPE_CELLULAR:
301 case CONNMAN_SERVICE_TYPE_GPS:
303 case CONNMAN_SERVICE_TYPE_VPN:
305 case CONNMAN_SERVICE_TYPE_GADGET:
307 case CONNMAN_SERVICE_TYPE_P2P:
309 #if defined TIZEN_EXT_WIFI_MESH
310 case CONNMAN_SERVICE_TYPE_MESH:
318 enum connman_service_type __connman_service_string2type(const char *str)
321 return CONNMAN_SERVICE_TYPE_UNKNOWN;
323 if (strcmp(str, "ethernet") == 0)
324 return CONNMAN_SERVICE_TYPE_ETHERNET;
325 if (strcmp(str, "gadget") == 0)
326 return CONNMAN_SERVICE_TYPE_GADGET;
327 if (strcmp(str, "wifi") == 0)
328 return CONNMAN_SERVICE_TYPE_WIFI;
329 if (strcmp(str, "cellular") == 0)
330 return CONNMAN_SERVICE_TYPE_CELLULAR;
331 if (strcmp(str, "bluetooth") == 0)
332 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
333 if (strcmp(str, "vpn") == 0)
334 return CONNMAN_SERVICE_TYPE_VPN;
335 if (strcmp(str, "gps") == 0)
336 return CONNMAN_SERVICE_TYPE_GPS;
337 if (strcmp(str, "system") == 0)
338 return CONNMAN_SERVICE_TYPE_SYSTEM;
339 if (strcmp(str, "p2p") == 0)
340 return CONNMAN_SERVICE_TYPE_P2P;
342 return CONNMAN_SERVICE_TYPE_UNKNOWN;
345 enum connman_service_security __connman_service_string2security(const char *str)
348 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
350 if (!strcmp(str, "psk"))
351 return CONNMAN_SERVICE_SECURITY_PSK;
352 if (!strcmp(str, "ieee8021x") || !strcmp(str, "8021x"))
353 return CONNMAN_SERVICE_SECURITY_8021X;
354 if (!strcmp(str, "none") || !strcmp(str, "open"))
355 return CONNMAN_SERVICE_SECURITY_NONE;
356 if (!strcmp(str, "wep"))
357 return CONNMAN_SERVICE_SECURITY_WEP;
358 #if defined TIZEN_EXT
359 if (!strcmp(str, "rsn"))
360 return CONNMAN_SERVICE_SECURITY_RSN;
361 if (!strcmp(str, "sae"))
362 return CONNMAN_SERVICE_SECURITY_SAE;
363 if (!strcmp(str, "owe"))
364 return CONNMAN_SERVICE_SECURITY_OWE;
365 if (!strcmp(str, "dpp"))
366 return CONNMAN_SERVICE_SECURITY_DPP;
369 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
372 static const char *security2string(enum connman_service_security security)
375 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
377 case CONNMAN_SERVICE_SECURITY_NONE:
379 case CONNMAN_SERVICE_SECURITY_WEP:
381 case CONNMAN_SERVICE_SECURITY_PSK:
382 case CONNMAN_SERVICE_SECURITY_WPA:
383 #if defined TIZEN_EXT
385 case CONNMAN_SERVICE_SECURITY_RSN:
387 case CONNMAN_SERVICE_SECURITY_SAE:
389 case CONNMAN_SERVICE_SECURITY_OWE:
391 case CONNMAN_SERVICE_SECURITY_DPP:
394 case CONNMAN_SERVICE_SECURITY_RSN:
397 case CONNMAN_SERVICE_SECURITY_8021X:
404 static const char *state2string(enum connman_service_state state)
407 case CONNMAN_SERVICE_STATE_UNKNOWN:
409 case CONNMAN_SERVICE_STATE_IDLE:
411 case CONNMAN_SERVICE_STATE_ASSOCIATION:
412 return "association";
413 case CONNMAN_SERVICE_STATE_CONFIGURATION:
414 return "configuration";
415 case CONNMAN_SERVICE_STATE_READY:
417 case CONNMAN_SERVICE_STATE_ONLINE:
419 case CONNMAN_SERVICE_STATE_DISCONNECT:
421 case CONNMAN_SERVICE_STATE_FAILURE:
428 static const char *error2string(enum connman_service_error error)
431 case CONNMAN_SERVICE_ERROR_UNKNOWN:
433 case CONNMAN_SERVICE_ERROR_OUT_OF_RANGE:
434 return "out-of-range";
435 case CONNMAN_SERVICE_ERROR_PIN_MISSING:
436 return "pin-missing";
437 case CONNMAN_SERVICE_ERROR_DHCP_FAILED:
438 return "dhcp-failed";
439 case CONNMAN_SERVICE_ERROR_CONNECT_FAILED:
440 return "connect-failed";
441 case CONNMAN_SERVICE_ERROR_LOGIN_FAILED:
442 return "login-failed";
443 case CONNMAN_SERVICE_ERROR_AUTH_FAILED:
444 return "auth-failed";
445 case CONNMAN_SERVICE_ERROR_INVALID_KEY:
446 return "invalid-key";
447 case CONNMAN_SERVICE_ERROR_BLOCKED:
454 static const char *proxymethod2string(enum connman_service_proxy_method method)
457 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
459 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
461 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
463 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
470 static enum connman_service_proxy_method string2proxymethod(const char *method)
472 if (g_strcmp0(method, "direct") == 0)
473 return CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
474 else if (g_strcmp0(method, "auto") == 0)
475 return CONNMAN_SERVICE_PROXY_METHOD_AUTO;
476 else if (g_strcmp0(method, "manual") == 0)
477 return CONNMAN_SERVICE_PROXY_METHOD_MANUAL;
479 return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
483 static const char *__connman_dnsconfig_method2string(enum connman_dnsconfig_method method)
486 case CONNMAN_DNSCONFIG_METHOD_UNKNOWN:
488 case CONNMAN_DNSCONFIG_METHOD_MANUAL:
490 case CONNMAN_DNSCONFIG_METHOD_DHCP:
497 static enum connman_dnsconfig_method __connman_dnsconfig_string2method(
500 if (g_strcmp0(method, "manual") == 0)
501 return CONNMAN_DNSCONFIG_METHOD_MANUAL;
502 else if (g_strcmp0(method, "dhcp") == 0)
503 return CONNMAN_DNSCONFIG_METHOD_DHCP;
505 return CONNMAN_DNSCONFIG_METHOD_UNKNOWN;
509 static void set_split_routing(struct connman_service *service, bool value)
511 if (service->type != CONNMAN_SERVICE_TYPE_VPN)
514 service->do_split_routing = value;
516 if (service->do_split_routing)
522 int __connman_service_load_modifiable(struct connman_service *service)
525 GError *error = NULL;
529 DBG("service %p", service);
531 keyfile = connman_storage_load_service(service->identifier);
535 switch (service->type) {
536 case CONNMAN_SERVICE_TYPE_UNKNOWN:
537 case CONNMAN_SERVICE_TYPE_SYSTEM:
538 case CONNMAN_SERVICE_TYPE_GPS:
539 case CONNMAN_SERVICE_TYPE_P2P:
540 #if defined TIZEN_EXT_WIFI_MESH
541 case CONNMAN_SERVICE_TYPE_MESH:
544 case CONNMAN_SERVICE_TYPE_VPN:
545 set_split_routing(service, g_key_file_get_boolean(keyfile,
547 "SplitRouting", NULL));
550 case CONNMAN_SERVICE_TYPE_WIFI:
551 case CONNMAN_SERVICE_TYPE_GADGET:
552 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
553 case CONNMAN_SERVICE_TYPE_CELLULAR:
554 case CONNMAN_SERVICE_TYPE_ETHERNET:
555 autoconnect = g_key_file_get_boolean(keyfile,
556 service->identifier, "AutoConnect", &error);
558 service->autoconnect = autoconnect;
559 g_clear_error(&error);
563 str = g_key_file_get_string(keyfile,
564 service->identifier, "Modified", NULL);
566 g_time_val_from_iso8601(str, &service->modified);
570 g_key_file_free(keyfile);
575 static int service_load(struct connman_service *service)
578 GError *error = NULL;
582 unsigned int ssid_len;
585 DBG("service %p", service);
587 keyfile = connman_storage_load_service(service->identifier);
589 service->new_service = true;
592 service->new_service = false;
594 switch (service->type) {
595 case CONNMAN_SERVICE_TYPE_UNKNOWN:
596 case CONNMAN_SERVICE_TYPE_SYSTEM:
597 case CONNMAN_SERVICE_TYPE_GPS:
598 case CONNMAN_SERVICE_TYPE_P2P:
599 #if defined TIZEN_EXT_WIFI_MESH
600 case CONNMAN_SERVICE_TYPE_MESH:
603 case CONNMAN_SERVICE_TYPE_VPN:
604 set_split_routing(service, g_key_file_get_boolean(keyfile,
606 "SplitRouting", NULL));
608 autoconnect = g_key_file_get_boolean(keyfile,
609 service->identifier, "AutoConnect", &error);
611 service->autoconnect = autoconnect;
612 g_clear_error(&error);
614 case CONNMAN_SERVICE_TYPE_WIFI:
615 if (!service->name) {
618 name = g_key_file_get_string(keyfile,
619 service->identifier, "Name", NULL);
621 g_free(service->name);
622 service->name = name;
625 if (service->network)
626 connman_network_set_name(service->network,
630 if (service->network &&
631 !connman_network_get_blob(service->network,
632 "WiFi.SSID", &ssid_len)) {
635 hex_ssid = g_key_file_get_string(keyfile,
641 unsigned int i, j = 0, hex;
642 size_t hex_ssid_len = strlen(hex_ssid);
644 ssid = g_try_malloc0(hex_ssid_len / 2);
651 for (i = 0; i < hex_ssid_len; i += 2) {
652 sscanf(hex_ssid + i, "%02x", &hex);
656 connman_network_set_blob(service->network,
657 "WiFi.SSID", ssid, hex_ssid_len / 2);
666 case CONNMAN_SERVICE_TYPE_GADGET:
667 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
668 case CONNMAN_SERVICE_TYPE_CELLULAR:
669 service->favorite = g_key_file_get_boolean(keyfile,
670 service->identifier, "Favorite", NULL);
674 case CONNMAN_SERVICE_TYPE_ETHERNET:
675 autoconnect = g_key_file_get_boolean(keyfile,
676 service->identifier, "AutoConnect", &error);
678 service->autoconnect = autoconnect;
679 g_clear_error(&error);
683 str = g_key_file_get_string(keyfile,
684 service->identifier, "Modified", NULL);
686 g_time_val_from_iso8601(str, &service->modified);
690 str = g_key_file_get_string(keyfile,
691 service->identifier, "Passphrase", NULL);
693 g_free(service->passphrase);
694 service->passphrase = str;
697 if (service->ipconfig_ipv4)
698 __connman_ipconfig_load(service->ipconfig_ipv4, keyfile,
699 service->identifier, "IPv4.");
701 if (service->ipconfig_ipv6)
702 __connman_ipconfig_load(service->ipconfig_ipv6, keyfile,
703 service->identifier, "IPv6.");
705 service->nameservers_config = g_key_file_get_string_list(keyfile,
706 service->identifier, "Nameservers", &length, NULL);
707 if (service->nameservers_config && length == 0) {
708 g_strfreev(service->nameservers_config);
709 service->nameservers_config = NULL;
715 dns_method = g_key_file_get_string(keyfile, service->identifier,
716 "Nameservers.IPv4method", NULL);
718 service->dns_config_method_ipv4 = __connman_dnsconfig_string2method(dns_method);
722 dns_method = g_key_file_get_string(keyfile, service->identifier,
723 "Nameservers.IPv6method", NULL);
725 service->dns_config_method_ipv6 = __connman_dnsconfig_string2method(dns_method);
730 service->timeservers_config = g_key_file_get_string_list(keyfile,
731 service->identifier, "Timeservers", &length, NULL);
732 if (service->timeservers_config && length == 0) {
733 g_strfreev(service->timeservers_config);
734 service->timeservers_config = NULL;
737 service->domains = g_key_file_get_string_list(keyfile,
738 service->identifier, "Domains", &length, NULL);
739 if (service->domains && length == 0) {
740 g_strfreev(service->domains);
741 service->domains = NULL;
744 str = g_key_file_get_string(keyfile,
745 service->identifier, "Proxy.Method", NULL);
747 service->proxy_config = string2proxymethod(str);
751 service->proxies = g_key_file_get_string_list(keyfile,
752 service->identifier, "Proxy.Servers", &length, NULL);
753 if (service->proxies && length == 0) {
754 g_strfreev(service->proxies);
755 service->proxies = NULL;
758 service->excludes = g_key_file_get_string_list(keyfile,
759 service->identifier, "Proxy.Excludes", &length, NULL);
760 if (service->excludes && length == 0) {
761 g_strfreev(service->excludes);
762 service->excludes = NULL;
765 str = g_key_file_get_string(keyfile,
766 service->identifier, "Proxy.URL", NULL);
768 g_free(service->pac);
772 service->mdns_config = g_key_file_get_boolean(keyfile,
773 service->identifier, "mDNS", NULL);
775 service->hidden_service = g_key_file_get_boolean(keyfile,
776 service->identifier, "Hidden", NULL);
778 #if defined TIZEN_EXT
779 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
780 service->security == CONNMAN_SERVICE_SECURITY_8021X) {
781 str = g_key_file_get_string(keyfile,
782 service->identifier, "EAP", NULL);
784 g_free(service->eap);
788 str = g_key_file_get_string(keyfile,
789 service->identifier, "Phase2", NULL);
791 g_free(service->phase2);
792 service->phase2 = str;
795 str = g_key_file_get_string(keyfile,
796 service->identifier, "Identity", NULL);
798 g_free(service->identity);
799 service->identity = str;
802 str = g_key_file_get_string(keyfile,
803 service->identifier, "CACertFile", NULL);
805 g_free(service->ca_cert_file);
806 service->ca_cert_file = str;
809 str = g_key_file_get_string(keyfile,
810 service->identifier, "ClientCertFile", NULL);
812 g_free(service->client_cert_file);
813 service->client_cert_file = str;
816 str = g_key_file_get_string(keyfile,
817 service->identifier, "PrivateKeyFile", NULL);
819 g_free(service->private_key_file);
820 service->private_key_file = str;
823 str = g_key_file_get_string(keyfile,
824 service->identifier, "PrivateKeyPassphrase", NULL);
826 g_free(service->private_key_passphrase);
827 service->private_key_passphrase = str;
831 #if defined TIZEN_EXT
832 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
833 service->security == CONNMAN_SERVICE_SECURITY_DPP) {
834 str = g_key_file_get_string(keyfile,
835 service->identifier, "Connector", NULL);
837 g_free(service->connector);
838 service->connector = str;
840 str = g_key_file_get_string(keyfile,
841 service->identifier, "CSignKey", NULL);
843 g_free(service->c_sign_key);
844 service->c_sign_key = str;
846 str = g_key_file_get_string(keyfile,
847 service->identifier, "NetAccessKey", NULL);
849 g_free(service->net_access_key);
850 service->net_access_key = str;
856 g_key_file_free(keyfile);
861 static int service_save(struct connman_service *service)
866 const char *cst_str = NULL;
869 DBG("service %p new %d", service, service->new_service);
871 if (service->new_service)
874 keyfile = __connman_storage_open_service(service->identifier);
879 g_key_file_set_string(keyfile, service->identifier,
880 "Name", service->name);
882 switch (service->type) {
883 case CONNMAN_SERVICE_TYPE_UNKNOWN:
884 case CONNMAN_SERVICE_TYPE_SYSTEM:
885 case CONNMAN_SERVICE_TYPE_GPS:
886 case CONNMAN_SERVICE_TYPE_P2P:
887 #if defined TIZEN_EXT_WIFI_MESH
888 case CONNMAN_SERVICE_TYPE_MESH:
891 case CONNMAN_SERVICE_TYPE_VPN:
892 g_key_file_set_boolean(keyfile, service->identifier,
893 "SplitRouting", service->do_split_routing);
894 if (service->favorite)
895 g_key_file_set_boolean(keyfile, service->identifier,
896 "AutoConnect", service->autoconnect);
898 case CONNMAN_SERVICE_TYPE_WIFI:
899 if (service->network) {
900 const unsigned char *ssid;
901 unsigned int ssid_len = 0;
903 ssid = connman_network_get_blob(service->network,
904 "WiFi.SSID", &ssid_len);
906 if (ssid && ssid_len > 0 && ssid[0] != '\0') {
907 char *identifier = service->identifier;
911 ssid_str = g_string_sized_new(ssid_len * 2);
917 for (i = 0; i < ssid_len; i++)
918 g_string_append_printf(ssid_str,
921 g_key_file_set_string(keyfile, identifier,
922 "SSID", ssid_str->str);
924 g_string_free(ssid_str, TRUE);
927 freq = connman_network_get_frequency(service->network);
928 g_key_file_set_integer(keyfile, service->identifier,
933 case CONNMAN_SERVICE_TYPE_GADGET:
934 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
935 case CONNMAN_SERVICE_TYPE_CELLULAR:
936 g_key_file_set_boolean(keyfile, service->identifier,
937 "Favorite", service->favorite);
939 g_key_file_remove_key(keyfile, service->identifier,
944 case CONNMAN_SERVICE_TYPE_ETHERNET:
945 if (service->favorite)
946 g_key_file_set_boolean(keyfile, service->identifier,
947 "AutoConnect", service->autoconnect);
951 str = g_time_val_to_iso8601(&service->modified);
953 g_key_file_set_string(keyfile, service->identifier,
958 if (service->passphrase && strlen(service->passphrase) > 0)
959 g_key_file_set_string(keyfile, service->identifier,
960 "Passphrase", service->passphrase);
962 g_key_file_remove_key(keyfile, service->identifier,
965 if (service->ipconfig_ipv4)
966 __connman_ipconfig_save(service->ipconfig_ipv4, keyfile,
967 service->identifier, "IPv4.");
969 if (service->ipconfig_ipv6)
970 __connman_ipconfig_save(service->ipconfig_ipv6, keyfile,
971 service->identifier, "IPv6.");
973 if (service->nameservers_config) {
974 guint len = g_strv_length(service->nameservers_config);
976 g_key_file_set_string_list(keyfile, service->identifier,
978 (const gchar **) service->nameservers_config, len);
980 g_key_file_remove_key(keyfile, service->identifier,
981 "Nameservers", NULL);
983 #if defined TIZEN_EXT
984 if(service->dns_config_method_ipv4 != 0) {
986 method = __connman_dnsconfig_method2string(
987 service->dns_config_method_ipv4);
988 g_key_file_set_string(keyfile, service->identifier,
989 "Nameservers.IPv4method", method);
991 g_key_file_remove_key(keyfile, service->identifier,
992 "Nameservers.IPv4method", NULL);
994 if(service->dns_config_method_ipv6 != 0) {
996 method = __connman_dnsconfig_method2string(
997 service->dns_config_method_ipv6);
998 g_key_file_set_string(keyfile, service->identifier,
999 "Nameservers.IPv6method", method);
1001 g_key_file_remove_key(keyfile, service->identifier,
1002 "Nameservers.IPv6method", NULL);
1005 if (service->timeservers_config) {
1006 guint len = g_strv_length(service->timeservers_config);
1008 g_key_file_set_string_list(keyfile, service->identifier,
1010 (const gchar **) service->timeservers_config, len);
1012 g_key_file_remove_key(keyfile, service->identifier,
1013 "Timeservers", NULL);
1015 if (service->domains) {
1016 guint len = g_strv_length(service->domains);
1018 g_key_file_set_string_list(keyfile, service->identifier,
1020 (const gchar **) service->domains, len);
1022 g_key_file_remove_key(keyfile, service->identifier,
1025 cst_str = proxymethod2string(service->proxy_config);
1027 g_key_file_set_string(keyfile, service->identifier,
1028 "Proxy.Method", cst_str);
1030 if (service->proxies) {
1031 guint len = g_strv_length(service->proxies);
1033 g_key_file_set_string_list(keyfile, service->identifier,
1035 (const gchar **) service->proxies, len);
1037 g_key_file_remove_key(keyfile, service->identifier,
1038 "Proxy.Servers", NULL);
1040 if (service->excludes) {
1041 guint len = g_strv_length(service->excludes);
1043 g_key_file_set_string_list(keyfile, service->identifier,
1045 (const gchar **) service->excludes, len);
1047 g_key_file_remove_key(keyfile, service->identifier,
1048 "Proxy.Excludes", NULL);
1050 if (service->pac && strlen(service->pac) > 0)
1051 g_key_file_set_string(keyfile, service->identifier,
1052 "Proxy.URL", service->pac);
1054 g_key_file_remove_key(keyfile, service->identifier,
1057 if (service->mdns_config)
1058 g_key_file_set_boolean(keyfile, service->identifier,
1061 g_key_file_remove_key(keyfile, service->identifier,
1064 if (service->hidden_service)
1065 g_key_file_set_boolean(keyfile, service->identifier, "Hidden",
1068 if (service->config_file && strlen(service->config_file) > 0)
1069 g_key_file_set_string(keyfile, service->identifier,
1070 "Config.file", service->config_file);
1072 if (service->config_entry &&
1073 strlen(service->config_entry) > 0)
1074 g_key_file_set_string(keyfile, service->identifier,
1075 "Config.ident", service->config_entry);
1077 #if defined TIZEN_EXT
1078 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
1079 service->security == CONNMAN_SERVICE_SECURITY_8021X) {
1080 if (service->eap != NULL && strlen(service->eap) > 0)
1081 g_key_file_set_string(keyfile, service->identifier,
1082 "EAP", service->eap);
1084 g_key_file_remove_key(keyfile, service->identifier,
1087 if (service->phase2 != NULL && strlen(service->phase2) > 0)
1088 g_key_file_set_string(keyfile, service->identifier,
1089 "Phase2", service->phase2);
1091 g_key_file_remove_key(keyfile, service->identifier,
1094 if (service->identity != NULL && strlen(service->identity) > 0)
1095 g_key_file_set_string(keyfile, service->identifier,
1096 "Identity", service->identity);
1098 g_key_file_remove_key(keyfile, service->identifier,
1101 if (service->ca_cert_file != NULL && strlen(service->ca_cert_file) > 0)
1102 g_key_file_set_string(keyfile, service->identifier,
1103 "CACertFile", service->ca_cert_file);
1105 g_key_file_remove_key(keyfile, service->identifier,
1106 "CACertFile", NULL);
1108 if (service->client_cert_file != NULL && strlen(service->client_cert_file) > 0)
1109 g_key_file_set_string(keyfile, service->identifier,
1110 "ClientCertFile", service->client_cert_file);
1112 g_key_file_remove_key(keyfile, service->identifier,
1113 "ClientCertFile", NULL);
1115 if (service->private_key_file != NULL && strlen(service->private_key_file) > 0)
1116 g_key_file_set_string(keyfile, service->identifier,
1117 "PrivateKeyFile", service->private_key_file);
1119 g_key_file_remove_key(keyfile, service->identifier,
1120 "PrivateKeyFile", NULL);
1122 if (service->private_key_passphrase != NULL && strlen(service->private_key_passphrase) > 0)
1123 g_key_file_set_string(keyfile, service->identifier,
1124 "PrivateKeyPassphrase", service->private_key_passphrase);
1126 g_key_file_remove_key(keyfile, service->identifier,
1127 "PrivateKeyPassphrase", NULL);
1129 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
1130 service->security == CONNMAN_SERVICE_SECURITY_DPP) {
1131 if (service->connector != NULL && strlen(service->connector) > 0)
1132 g_key_file_set_string(keyfile, service->identifier,
1133 "Connector", service->connector);
1135 g_key_file_remove_key(keyfile, service->identifier,
1138 if (service->c_sign_key != NULL && strlen(service->c_sign_key) > 0)
1139 g_key_file_set_string(keyfile, service->identifier,
1140 "CSignKey", service->c_sign_key);
1142 g_key_file_remove_key(keyfile, service->identifier,
1145 if (service->net_access_key != NULL && strlen(service->net_access_key) > 0)
1146 g_key_file_set_string(keyfile, service->identifier,
1147 "NetAccessKey", service->net_access_key);
1149 g_key_file_remove_key(keyfile, service->identifier,
1150 "NetAccessKey", NULL);
1155 __connman_storage_save_service(keyfile, service->identifier);
1157 g_key_file_free(keyfile);
1162 #if defined TIZEN_EXT
1163 static gint sort_entry(gconstpointer a, gconstpointer b, gpointer user_data)
1165 GTimeVal *aval = (GTimeVal *)a;
1166 GTimeVal *bval = (GTimeVal *)b;
1168 /* Note that the sort order is ascending */
1169 if (aval->tv_sec > bval->tv_sec)
1172 if (aval->tv_sec < bval->tv_sec)
1178 static void free_entry(gpointer data)
1180 struct saved_profiles *entry = data;
1181 g_free(entry->profile_name);
1185 static void __connman_manage_saved_profiles()
1188 gchar **services = NULL;
1190 int i, num_profiles = 0;
1191 GSequenceIter *iter;
1192 GSequence *profile_list;
1193 struct saved_profiles *entry;
1195 profile_list = g_sequence_new(free_entry);
1199 services = connman_storage_get_services();
1201 /* Check the count of saved profiles */
1202 for (i = 0; services && services[i]; i++) {
1203 if (strncmp(services[i], "wifi_", 5) != 0)
1206 keyfile = connman_storage_load_service(services[i]);
1210 gchar *str = g_key_file_get_string(keyfile,
1211 services[i], "Modified", NULL);
1213 g_key_file_free(keyfile);
1217 g_time_val_from_iso8601(str, &modified);
1220 entry = g_try_new(struct saved_profiles, 1);
1222 g_sequence_free(profile_list);
1223 g_key_file_free(keyfile);
1227 entry->modified = modified;
1228 entry->profile_name = g_strdup(services[i]);
1230 g_sequence_insert_sorted(profile_list, entry,
1235 DBG("number of profiles: %d", num_profiles);
1237 if (num_profiles > MAX_WIFI_PROFILES) {
1238 iter = g_sequence_get_begin_iter(profile_list);
1240 entry = g_sequence_get(iter);
1242 if (__connman_storage_remove_service(entry->profile_name) == false)
1243 DBG("Failed to remove service profile: %s", entry->profile_name);
1246 g_sequence_free(profile_list);
1250 void __connman_service_save(struct connman_service *service)
1255 service_save(service);
1256 #if defined TIZEN_EXT
1258 * Description: Manage the wireless profiles saved in connman.
1259 * If the number of saved profiles is more than 200, remove the
1260 * profile that is not updated for longer duration.
1262 __connman_manage_saved_profiles();
1266 static enum connman_service_state combine_state(
1267 enum connman_service_state state_a,
1268 enum connman_service_state state_b)
1270 enum connman_service_state result;
1272 if (state_a == state_b) {
1277 if (state_a == CONNMAN_SERVICE_STATE_UNKNOWN) {
1282 if (state_b == CONNMAN_SERVICE_STATE_UNKNOWN) {
1287 if (state_a == CONNMAN_SERVICE_STATE_IDLE) {
1292 if (state_b == CONNMAN_SERVICE_STATE_IDLE) {
1297 if (state_a == CONNMAN_SERVICE_STATE_ONLINE) {
1302 if (state_b == CONNMAN_SERVICE_STATE_ONLINE) {
1307 if (state_a == CONNMAN_SERVICE_STATE_READY) {
1312 if (state_b == CONNMAN_SERVICE_STATE_READY) {
1317 if (state_a == CONNMAN_SERVICE_STATE_CONFIGURATION) {
1322 if (state_b == CONNMAN_SERVICE_STATE_CONFIGURATION) {
1327 if (state_a == CONNMAN_SERVICE_STATE_ASSOCIATION) {
1332 if (state_b == CONNMAN_SERVICE_STATE_ASSOCIATION) {
1337 if (state_a == CONNMAN_SERVICE_STATE_DISCONNECT) {
1342 if (state_b == CONNMAN_SERVICE_STATE_DISCONNECT) {
1347 result = CONNMAN_SERVICE_STATE_FAILURE;
1353 static bool is_connecting(enum connman_service_state state)
1356 case CONNMAN_SERVICE_STATE_UNKNOWN:
1357 case CONNMAN_SERVICE_STATE_IDLE:
1358 case CONNMAN_SERVICE_STATE_FAILURE:
1359 case CONNMAN_SERVICE_STATE_DISCONNECT:
1360 case CONNMAN_SERVICE_STATE_READY:
1361 case CONNMAN_SERVICE_STATE_ONLINE:
1363 case CONNMAN_SERVICE_STATE_ASSOCIATION:
1364 case CONNMAN_SERVICE_STATE_CONFIGURATION:
1371 static bool is_connected(enum connman_service_state state)
1374 case CONNMAN_SERVICE_STATE_UNKNOWN:
1375 case CONNMAN_SERVICE_STATE_IDLE:
1376 case CONNMAN_SERVICE_STATE_ASSOCIATION:
1377 case CONNMAN_SERVICE_STATE_CONFIGURATION:
1378 case CONNMAN_SERVICE_STATE_DISCONNECT:
1379 case CONNMAN_SERVICE_STATE_FAILURE:
1381 case CONNMAN_SERVICE_STATE_READY:
1382 case CONNMAN_SERVICE_STATE_ONLINE:
1389 static bool is_idle(enum connman_service_state state)
1392 case CONNMAN_SERVICE_STATE_IDLE:
1393 case CONNMAN_SERVICE_STATE_DISCONNECT:
1394 case CONNMAN_SERVICE_STATE_FAILURE:
1396 case CONNMAN_SERVICE_STATE_UNKNOWN:
1397 case CONNMAN_SERVICE_STATE_ASSOCIATION:
1398 case CONNMAN_SERVICE_STATE_CONFIGURATION:
1399 case CONNMAN_SERVICE_STATE_READY:
1400 case CONNMAN_SERVICE_STATE_ONLINE:
1407 static int nameservers_changed_cb(void *user_data)
1409 struct connman_service *service = user_data;
1411 DBG("service %p", service);
1413 service->nameservers_timeout = 0;
1414 if ((is_idle(service->state) && !service->nameservers) ||
1415 is_connected(service->state))
1416 dns_changed(service);
1421 static void nameservers_changed(struct connman_service *service)
1423 if (!service->nameservers_timeout)
1424 service->nameservers_timeout = g_idle_add(nameservers_changed_cb,
1428 static bool nameserver_available(struct connman_service *service,
1429 enum connman_ipconfig_type type,
1434 family = connman_inet_check_ipaddress(ns);
1436 if (family == AF_INET) {
1437 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
1440 return is_connected(service->state_ipv4);
1443 if (family == AF_INET6) {
1444 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
1447 return is_connected(service->state_ipv6);
1453 static int searchdomain_add_all(struct connman_service *service)
1457 if (!is_connected(service->state))
1460 index = __connman_service_get_index(service);
1464 if (service->domains) {
1465 while (service->domains[i]) {
1466 connman_resolver_append(index, service->domains[i],
1474 if (service->domainname)
1475 connman_resolver_append(index, service->domainname, NULL);
1481 static int searchdomain_remove_all(struct connman_service *service)
1485 if (!is_connected(service->state))
1488 index = __connman_service_get_index(service);
1492 while (service->domains && service->domains[i]) {
1493 connman_resolver_remove(index, service->domains[i], NULL);
1497 if (service->domainname)
1498 connman_resolver_remove(index, service->domainname, NULL);
1503 static int nameserver_add(struct connman_service *service,
1504 enum connman_ipconfig_type type,
1505 const char *nameserver)
1509 if (!nameserver_available(service, type, nameserver))
1512 index = __connman_service_get_index(service);
1516 #if defined TIZEN_EXT
1517 DBG("Resolver append nameserver: %s", nameserver);
1519 ret = connman_resolver_append(index, NULL, nameserver);
1521 nameservers_changed(service);
1526 static int nameserver_add_all(struct connman_service *service,
1527 enum connman_ipconfig_type type)
1531 if (service->nameservers_config) {
1532 while (service->nameservers_config[i]) {
1533 #if defined TIZEN_EXT
1534 DBG("type %d add service->nameservers_config[%d]:%s",type,
1535 i, service->nameservers_config[i]);
1536 if(strncmp(service->nameservers_config[i], "::", 2) == 0) {
1537 DBG("Invalid nameserver");
1543 case CONNMAN_IPCONFIG_TYPE_IPV4:
1544 if (connman_inet_check_ipaddress(
1545 service->nameservers_config[i]) == AF_INET &&
1546 service->dns_config_method_ipv4 ==
1547 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
1548 nameserver_add(service, type,
1549 service->nameservers_config[i]);
1552 case CONNMAN_IPCONFIG_TYPE_IPV6:
1553 if (connman_inet_check_ipaddress(
1554 service->nameservers_config[i]) == AF_INET6 &&
1555 service->dns_config_method_ipv6 ==
1556 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
1557 nameserver_add(service, type,
1558 service->nameservers_config[i]);
1561 case CONNMAN_IPCONFIG_TYPE_ALL:
1562 if (connman_inet_check_ipaddress(
1563 service->nameservers_config[i]) == AF_INET &&
1564 service->dns_config_method_ipv4 ==
1565 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
1566 nameserver_add(service, type,
1567 service->nameservers_config[i]);
1569 if (connman_inet_check_ipaddress(
1570 service->nameservers_config[i]) == AF_INET6 &&
1571 service->dns_config_method_ipv6 ==
1572 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
1573 nameserver_add(service, type,
1574 service->nameservers_config[i]);
1577 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1578 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
1581 DBG("default case do nothing");
1585 nameserver_add(service, type,
1586 service->nameservers_config[i]);
1590 } else if (service->nameservers) {
1591 while (service->nameservers[i]) {
1592 #if defined TIZEN_EXT
1593 DBG("type %d service->nameservers[%d]: %s",type,
1594 i, service->nameservers[i]);
1597 case CONNMAN_IPCONFIG_TYPE_IPV4:
1598 if (connman_inet_check_ipaddress(
1599 service->nameservers[i]) == AF_INET &&
1600 service->dns_config_method_ipv4 ==
1601 CONNMAN_DNSCONFIG_METHOD_DHCP) {
1602 nameserver_add(service, type,
1603 service->nameservers[i]);
1606 case CONNMAN_IPCONFIG_TYPE_IPV6:
1607 if (connman_inet_check_ipaddress(
1608 service->nameservers[i]) == AF_INET6 &&
1609 service->dns_config_method_ipv6 ==
1610 CONNMAN_DNSCONFIG_METHOD_DHCP) {
1611 nameserver_add(service, type,
1612 service->nameservers[i]);
1615 case CONNMAN_IPCONFIG_TYPE_ALL:
1616 if (connman_inet_check_ipaddress(
1617 service->nameservers[i]) == AF_INET &&
1618 service->dns_config_method_ipv4 ==
1619 CONNMAN_DNSCONFIG_METHOD_DHCP) {
1620 nameserver_add(service, type,
1621 service->nameservers[i]);
1623 if (connman_inet_check_ipaddress(
1624 service->nameservers[i]) == AF_INET6 &&
1625 service->dns_config_method_ipv6 ==
1626 CONNMAN_DNSCONFIG_METHOD_DHCP) {
1627 nameserver_add(service, type,
1628 service->nameservers[i]);
1631 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1632 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
1635 DBG("default case do nothing");
1639 nameserver_add(service, type,
1640 service->nameservers[i]);
1647 __connman_resolver_append_fallback_nameservers();
1649 #if defined TIZEN_EXT
1650 const char *global_dns = connman_option_get_string("GlobalNameserver");
1652 nameserver_add(service, type, global_dns);
1655 searchdomain_add_all(service);
1660 static int nameserver_remove(struct connman_service *service,
1661 enum connman_ipconfig_type type,
1662 const char *nameserver)
1666 if (!nameserver_available(service, type, nameserver))
1669 index = __connman_service_get_index(service);
1673 #if defined TIZEN_EXT
1674 DBG("Resolver remove nameserver: %s", nameserver);
1676 ret = connman_resolver_remove(index, NULL, nameserver);
1678 nameservers_changed(service);
1683 static int nameserver_remove_all(struct connman_service *service,
1684 enum connman_ipconfig_type type)
1686 #if defined TIZEN_EXT
1688 * Skip this function if there is any connected profiles
1689 * that use same interface
1691 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
1692 __connman_service_get_connected_count_of_iface(service) > 0)
1697 index = __connman_service_get_index(service);
1701 while (service->nameservers_config && service->nameservers_config[i]) {
1703 #if defined TIZEN_EXT
1704 DBG("type %d Remove service->nameservers_config[%d]: %s",
1705 type, i, service->nameservers_config[i]);
1707 case CONNMAN_IPCONFIG_TYPE_IPV4:
1708 if (connman_inet_check_ipaddress(
1709 service->nameservers_config[i]) == AF_INET &&
1710 (service->dns_config_method_ipv4 ==
1711 CONNMAN_DNSCONFIG_METHOD_DHCP ||
1712 service->dns_config_method_ipv4 ==
1713 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
1714 nameserver_remove(service, type,
1715 service->nameservers_config[i]);
1718 case CONNMAN_IPCONFIG_TYPE_IPV6:
1719 if (connman_inet_check_ipaddress(
1720 service->nameservers_config[i]) == AF_INET6 &&
1721 (service->dns_config_method_ipv6 ==
1722 CONNMAN_DNSCONFIG_METHOD_DHCP ||
1723 service->dns_config_method_ipv6 ==
1724 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
1725 nameserver_remove(service, type,
1726 service->nameservers_config[i]);
1729 case CONNMAN_IPCONFIG_TYPE_ALL:
1730 if (connman_inet_check_ipaddress(
1731 service->nameservers_config[i]) == AF_INET &&
1732 (service->dns_config_method_ipv4 ==
1733 CONNMAN_DNSCONFIG_METHOD_DHCP ||
1734 service->dns_config_method_ipv4 ==
1735 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
1736 nameserver_remove(service, type,
1737 service->nameservers_config[i]);
1739 if (connman_inet_check_ipaddress(
1740 service->nameservers_config[i]) == AF_INET6 &&
1741 (service->dns_config_method_ipv6 ==
1742 CONNMAN_DNSCONFIG_METHOD_DHCP ||
1743 service->dns_config_method_ipv6 ==
1744 CONNMAN_DNSCONFIG_METHOD_MANUAL)) {
1745 nameserver_remove(service, type,
1746 service->nameservers_config[i]);
1749 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1750 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
1753 DBG("default case do nothing");
1757 nameserver_remove(service, type,
1758 service->nameservers_config[i]);
1764 while (service->nameservers && service->nameservers[i]) {
1765 #if defined TIZEN_EXT
1766 DBG("type %d Remove service->nameservers[%d]: %s",type, i,
1767 service->nameservers[i]);
1769 case CONNMAN_IPCONFIG_TYPE_IPV4:
1770 if (connman_inet_check_ipaddress(
1771 service->nameservers[i]) == AF_INET &&
1772 (service->dns_config_method_ipv4 ==
1773 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
1774 service->dns_config_method_ipv4 ==
1775 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
1776 nameserver_remove(service, type,
1777 service->nameservers[i]);
1780 case CONNMAN_IPCONFIG_TYPE_IPV6:
1781 if (connman_inet_check_ipaddress(
1782 service->nameservers[i]) == AF_INET6 &&
1783 (service->dns_config_method_ipv6 ==
1784 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
1785 service->dns_config_method_ipv6 ==
1786 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
1787 nameserver_remove(service, type,
1788 service->nameservers[i]);
1791 case CONNMAN_IPCONFIG_TYPE_ALL:
1792 if (connman_inet_check_ipaddress(
1793 service->nameservers[i]) == AF_INET &&
1794 (service->dns_config_method_ipv4 ==
1795 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
1796 service->dns_config_method_ipv4 ==
1797 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
1798 nameserver_remove(service, type,
1799 service->nameservers[i]);
1801 if (connman_inet_check_ipaddress(
1802 service->nameservers[i]) == AF_INET6 &&
1803 (service->dns_config_method_ipv6 ==
1804 CONNMAN_DNSCONFIG_METHOD_MANUAL ||
1805 service->dns_config_method_ipv6 ==
1806 CONNMAN_DNSCONFIG_METHOD_DHCP)) {
1807 nameserver_remove(service, type,
1808 service->nameservers[i]);
1811 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
1812 DBG("CONNMAN_IPCONFIG_TYPE_UNKNOWN do nothing");
1815 DBG("default case do nothing");
1819 nameserver_remove(service, type, service->nameservers[i]);
1824 #if defined TIZEN_EXT
1825 const char *global_dns = connman_option_get_string("GlobalNameserver");
1827 nameserver_remove(service, type, global_dns);
1829 searchdomain_remove_all(service);
1835 * The is_auto variable is set to true when IPv6 autoconf nameservers are
1836 * inserted to resolver via netlink message (see rtnl.c:rtnl_newnduseropt()
1837 * for details) and not through service.c
1839 #if defined TIZEN_EXT
1840 int __connman_service_nameserver_append(struct connman_service *service,
1841 const char *nameserver, bool is_auto,
1842 enum connman_ipconfig_type type)
1844 int __connman_service_nameserver_append(struct connman_service *service,
1845 const char *nameserver, bool is_auto)
1851 DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
1857 nameservers = service->nameservers_auto;
1859 nameservers = service->nameservers;
1861 for (i = 0; nameservers && nameservers[i]; i++)
1862 #if defined TIZEN_EXT
1864 DBG("nameservers[%d] %s, nameserver %s", i, nameservers[i], nameserver);
1866 if (g_strcmp0(nameservers[i], nameserver) == 0)
1868 #if defined TIZEN_EXT
1873 len = g_strv_length(nameservers);
1874 nameservers = g_try_renew(char *, nameservers, len + 2);
1877 nameservers = g_try_new0(char *, len + 2);
1883 nameservers[len] = g_strdup(nameserver);
1884 nameservers[len + 1] = NULL;
1887 if(type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
1888 service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
1889 service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
1891 if(type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
1892 service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_UNKNOWN)
1893 service->dns_config_method_ipv6 = CONNMAN_DNSCONFIG_METHOD_DHCP;
1897 service->nameservers_auto = nameservers;
1899 service->nameservers = nameservers;
1900 nameserver_add(service, CONNMAN_IPCONFIG_TYPE_ALL, nameserver);
1903 nameservers_changed(service);
1905 searchdomain_add_all(service);
1910 #if defined TIZEN_EXT
1911 int __connman_service_nameserver_remove(struct connman_service *service,
1912 const char *nameserver, bool is_auto,
1913 enum connman_ipconfig_type type)
1915 int __connman_service_nameserver_remove(struct connman_service *service,
1916 const char *nameserver, bool is_auto)
1919 char **servers, **nameservers;
1923 DBG("service %p nameserver %s auto %d", service, nameserver, is_auto);
1929 nameservers = service->nameservers_auto;
1931 nameservers = service->nameservers;
1936 for (i = 0; nameservers[i]; i++)
1937 if (g_strcmp0(nameservers[i], nameserver) == 0) {
1945 len = g_strv_length(nameservers);
1952 servers = g_try_new0(char *, len);
1956 for (i = 0, j = 0; i < len; i++) {
1957 if (g_strcmp0(nameservers[i], nameserver)) {
1958 servers[j] = nameservers[i];
1961 g_free(nameservers[i]);
1963 nameservers[i] = NULL;
1965 servers[len - 1] = NULL;
1968 g_strfreev(nameservers);
1969 nameservers = servers;
1972 service->nameservers_auto = nameservers;
1974 service->nameservers = nameservers;
1975 #if defined TIZEN_EXT
1976 DBG("nameserver remove ip_type: %d", type);
1977 nameserver_remove(service, type,
1980 nameserver_remove(service, CONNMAN_IPCONFIG_TYPE_ALL,
1988 void __connman_service_nameserver_clear(struct connman_service *service)
1990 nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
1992 g_strfreev(service->nameservers);
1993 service->nameservers = NULL;
1995 nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
1998 static void add_nameserver_route(int family, int index, char *nameserver,
2003 if (connman_inet_compare_subnet(index, nameserver))
2006 if (connman_inet_add_host_route(index, nameserver, gw) < 0)
2007 /* For P-t-P link the above route add will fail */
2008 connman_inet_add_host_route(index, nameserver, NULL);
2012 if (connman_inet_add_ipv6_host_route(index, nameserver,
2014 connman_inet_add_ipv6_host_route(index, nameserver,
2020 static void nameserver_add_routes(int index, char **nameservers,
2023 int i, ns_family, gw_family;
2025 gw_family = connman_inet_check_ipaddress(gw);
2029 for (i = 0; nameservers[i]; i++) {
2030 ns_family = connman_inet_check_ipaddress(nameservers[i]);
2031 if (ns_family < 0 || ns_family != gw_family)
2034 add_nameserver_route(ns_family, index, nameservers[i], gw);
2038 static void nameserver_del_routes(int index, char **nameservers,
2039 enum connman_ipconfig_type type)
2043 for (i = 0; nameservers[i]; i++) {
2044 family = connman_inet_check_ipaddress(nameservers[i]);
2050 if (type != CONNMAN_IPCONFIG_TYPE_IPV6)
2051 connman_inet_del_host_route(index,
2055 if (type != CONNMAN_IPCONFIG_TYPE_IPV4)
2056 connman_inet_del_ipv6_host_route(index,
2063 void __connman_service_nameserver_add_routes(struct connman_service *service,
2071 index = __connman_service_get_index(service);
2073 if (service->nameservers_config) {
2075 * Configured nameserver takes preference over the
2076 * discoverd nameserver gathered from DHCP, VPN, etc.
2078 nameserver_add_routes(index, service->nameservers_config, gw);
2079 } else if (service->nameservers) {
2081 * We add nameservers host routes for nameservers that
2082 * are not on our subnet. For those who are, the subnet
2083 * route will be installed by the time the dns proxy code
2084 * tries to reach them. The subnet route is installed
2085 * when setting the interface IP address.
2087 nameserver_add_routes(index, service->nameservers, gw);
2091 void __connman_service_nameserver_del_routes(struct connman_service *service,
2092 enum connman_ipconfig_type type)
2099 index = __connman_service_get_index(service);
2101 if (service->nameservers_config)
2102 nameserver_del_routes(index, service->nameservers_config,
2104 else if (service->nameservers)
2105 nameserver_del_routes(index, service->nameservers, type);
2108 static void address_updated(struct connman_service *service,
2109 enum connman_ipconfig_type type)
2111 if (is_connected(service->state) &&
2112 service == connman_service_get_default()) {
2113 nameserver_remove_all(service, type);
2114 nameserver_add_all(service, type);
2116 __connman_timeserver_sync(service);
2120 static struct connman_stats *stats_get(struct connman_service *service)
2122 if (service->roaming)
2123 return &service->stats_roaming;
2125 return &service->stats;
2128 static bool stats_enabled(struct connman_service *service)
2130 struct connman_stats *stats = stats_get(service);
2132 return stats->enabled;
2135 static void stats_start(struct connman_service *service)
2137 struct connman_stats *stats = stats_get(service);
2139 DBG("service %p", service);
2144 stats->enabled = true;
2145 stats->data_last.time = stats->data.time;
2147 g_timer_start(stats->timer);
2150 static void stats_stop(struct connman_service *service)
2152 struct connman_stats *stats = stats_get(service);
2153 unsigned int seconds;
2155 DBG("service %p", service);
2160 if (!stats->enabled)
2163 g_timer_stop(stats->timer);
2165 seconds = g_timer_elapsed(stats->timer, NULL);
2166 stats->data.time = stats->data_last.time + seconds;
2168 stats->enabled = false;
2171 static void reset_stats(struct connman_service *service)
2173 DBG("service %p", service);
2176 service->stats.valid = false;
2178 service->stats.data.rx_packets = 0;
2179 service->stats.data.tx_packets = 0;
2180 service->stats.data.rx_bytes = 0;
2181 service->stats.data.tx_bytes = 0;
2182 service->stats.data.rx_errors = 0;
2183 service->stats.data.tx_errors = 0;
2184 service->stats.data.rx_dropped = 0;
2185 service->stats.data.tx_dropped = 0;
2186 service->stats.data.time = 0;
2187 service->stats.data_last.time = 0;
2189 g_timer_reset(service->stats.timer);
2192 service->stats_roaming.valid = false;
2194 service->stats_roaming.data.rx_packets = 0;
2195 service->stats_roaming.data.tx_packets = 0;
2196 service->stats_roaming.data.rx_bytes = 0;
2197 service->stats_roaming.data.tx_bytes = 0;
2198 service->stats_roaming.data.rx_errors = 0;
2199 service->stats_roaming.data.tx_errors = 0;
2200 service->stats_roaming.data.rx_dropped = 0;
2201 service->stats_roaming.data.tx_dropped = 0;
2202 service->stats_roaming.data.time = 0;
2203 service->stats_roaming.data_last.time = 0;
2205 g_timer_reset(service->stats_roaming.timer);
2208 #if defined TIZEN_EXT
2209 static gboolean __connman_service_is_internet_profile(
2210 struct connman_service *cellular)
2212 const char internet_suffix[] = "_1";
2214 DBG("Service path: %s", cellular->path);
2216 if (g_str_has_suffix(cellular->path, internet_suffix) == TRUE)
2222 struct connman_service *connman_service_get_default_connection(void)
2225 struct connman_service *service;
2226 struct connman_service *default_service = NULL;
2228 for (list = service_list; list; list = list->next) {
2229 service = list->data;
2231 DBG("service: %p %s %s %s", service, service->name,
2232 state2string(service->state),
2233 __connman_service_type2string(service->type));
2235 #if defined TIZEN_MAINTAIN_ONLINE
2236 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
2237 service->state == CONNMAN_SERVICE_STATE_ONLINE) {
2239 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
2240 is_connected(service->state) == TRUE) {
2243 } else if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
2244 __connman_service_is_internet_profile(service) == TRUE) {
2245 if (default_service == NULL)
2246 default_service = service;
2247 else if (is_connected(service->state) == TRUE &&
2248 is_connected(default_service->state) == FALSE)
2249 default_service = service;
2250 } else if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET &&
2251 is_connected(service->state) == TRUE) {
2252 if (default_service == NULL)
2253 default_service = service;
2254 } else if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH &&
2255 is_connected(service->state) == TRUE) {
2256 if (default_service == NULL)
2257 default_service = service;
2261 return default_service;
2265 struct connman_service *connman_service_get_default(void)
2267 #if defined TIZEN_MAINTAIN_ONLINE
2268 return connman_service_get_default_connection();
2270 struct connman_service *service;
2275 service = service_list->data;
2277 if (!is_connected(service->state))
2284 bool __connman_service_index_is_default(int index)
2286 struct connman_service *service;
2291 service = connman_service_get_default();
2293 return __connman_service_get_index(service) == index;
2296 static void default_changed(void)
2298 struct connman_service *service = connman_service_get_default();
2300 if (service == current_default)
2303 DBG("current default %p %s", current_default,
2304 current_default ? current_default->identifier : "");
2305 DBG("new default %p %s", service, service ? service->identifier : "");
2307 #if defined TIZEN_EXT
2308 current_default = service;
2310 __connman_service_timeserver_changed(service, NULL);
2312 __connman_service_timeserver_changed(current_default, NULL);
2314 current_default = service;
2318 if (service->hostname &&
2319 connman_setting_get_bool("AllowHostnameUpdates"))
2320 __connman_utsname_set_hostname(service->hostname);
2322 if (service->domainname &&
2323 connman_setting_get_bool("AllowDomainnameUpdates"))
2324 __connman_utsname_set_domainname(service->domainname);
2327 __connman_notifier_default_changed(service);
2330 static void state_changed(struct connman_service *service)
2334 __connman_notifier_service_state_changed(service, service->state);
2336 str = state2string(service->state);
2340 #if !defined TIZEN_EXT
2341 if (!allow_property_changed(service))
2345 #if defined TIZEN_EXT
2346 DBG(" %s, %s", str, service->path);
2348 connman_dbus_property_changed_basic(service->path,
2349 CONNMAN_SERVICE_INTERFACE, "State",
2350 DBUS_TYPE_STRING, &str);
2353 #if defined TIZEN_EXT
2354 static void connect_reason_changed(struct connman_service *service)
2359 if (!allow_property_changed(service))
2362 connman_dbus_property_changed_basic(service->path,
2363 CONNMAN_SERVICE_INTERFACE,
2366 &service->connect_reason);
2369 static void disconnection_requested_changed(struct connman_service *service)
2371 dbus_bool_t disconnection_requested;
2376 if (!allow_property_changed(service))
2379 disconnection_requested = service->disconnection_requested;
2380 connman_dbus_property_changed_basic(service->path,
2381 CONNMAN_SERVICE_INTERFACE,
2382 "DisconnectionRequested",
2384 &disconnection_requested);
2387 void connman_service_set_disconnection_requested(struct connman_service *service,
2388 bool disconnection_requested)
2390 if (service == NULL)
2393 service->disconnection_requested = disconnection_requested;
2394 disconnection_requested_changed(service);
2398 static void strength_changed(struct connman_service *service)
2400 if (service->strength == 0)
2403 if (!allow_property_changed(service))
2406 connman_dbus_property_changed_basic(service->path,
2407 CONNMAN_SERVICE_INTERFACE, "Strength",
2408 DBUS_TYPE_BYTE, &service->strength);
2411 static void favorite_changed(struct connman_service *service)
2413 dbus_bool_t favorite;
2418 if (!allow_property_changed(service))
2421 favorite = service->favorite;
2422 connman_dbus_property_changed_basic(service->path,
2423 CONNMAN_SERVICE_INTERFACE, "Favorite",
2424 DBUS_TYPE_BOOLEAN, &favorite);
2427 static void immutable_changed(struct connman_service *service)
2429 dbus_bool_t immutable;
2434 if (!allow_property_changed(service))
2437 immutable = service->immutable;
2438 connman_dbus_property_changed_basic(service->path,
2439 CONNMAN_SERVICE_INTERFACE, "Immutable",
2440 DBUS_TYPE_BOOLEAN, &immutable);
2443 static void roaming_changed(struct connman_service *service)
2445 dbus_bool_t roaming;
2450 if (!allow_property_changed(service))
2453 roaming = service->roaming;
2454 connman_dbus_property_changed_basic(service->path,
2455 CONNMAN_SERVICE_INTERFACE, "Roaming",
2456 DBUS_TYPE_BOOLEAN, &roaming);
2459 static void autoconnect_changed(struct connman_service *service)
2461 dbus_bool_t autoconnect;
2466 if (!allow_property_changed(service))
2469 autoconnect = service->autoconnect;
2470 connman_dbus_property_changed_basic(service->path,
2471 CONNMAN_SERVICE_INTERFACE, "AutoConnect",
2472 DBUS_TYPE_BOOLEAN, &autoconnect);
2475 static void append_security(DBusMessageIter *iter, void *user_data)
2477 struct connman_service *service = user_data;
2480 str = security2string(service->security);
2482 dbus_message_iter_append_basic(iter,
2483 DBUS_TYPE_STRING, &str);
2486 * Some access points incorrectly advertise WPS even when they
2487 * are configured as open or no security, so filter
2491 switch (service->security) {
2492 case CONNMAN_SERVICE_SECURITY_PSK:
2493 case CONNMAN_SERVICE_SECURITY_WPA:
2494 case CONNMAN_SERVICE_SECURITY_RSN:
2495 #if defined TIZEN_EXT
2496 case CONNMAN_SERVICE_SECURITY_SAE:
2499 dbus_message_iter_append_basic(iter,
2500 DBUS_TYPE_STRING, &str);
2502 #if defined TIZEN_EXT
2503 case CONNMAN_SERVICE_SECURITY_OWE:
2505 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
2506 case CONNMAN_SERVICE_SECURITY_NONE:
2507 case CONNMAN_SERVICE_SECURITY_WEP:
2508 case CONNMAN_SERVICE_SECURITY_8021X:
2512 if (service->wps_advertizing) {
2513 str = "wps_advertising";
2514 dbus_message_iter_append_basic(iter,
2515 DBUS_TYPE_STRING, &str);
2520 static void security_changed(struct connman_service *service)
2525 if (!allow_property_changed(service))
2528 connman_dbus_property_changed_array(service->path,
2529 CONNMAN_SERVICE_INTERFACE, "Security",
2530 DBUS_TYPE_STRING, append_security, service);
2533 static void append_ethernet(DBusMessageIter *iter, void *user_data)
2535 struct connman_service *service = user_data;
2537 if (service->ipconfig_ipv4)
2538 __connman_ipconfig_append_ethernet(service->ipconfig_ipv4,
2540 else if (service->ipconfig_ipv6)
2541 __connman_ipconfig_append_ethernet(service->ipconfig_ipv6,
2545 static void append_ipv4(DBusMessageIter *iter, void *user_data)
2547 struct connman_service *service = user_data;
2549 if (!is_connected(service->state_ipv4))
2552 if (service->ipconfig_ipv4)
2553 __connman_ipconfig_append_ipv4(service->ipconfig_ipv4, iter);
2556 static void append_ipv6(DBusMessageIter *iter, void *user_data)
2558 struct connman_service *service = user_data;
2560 if (!is_connected(service->state_ipv6))
2563 if (service->ipconfig_ipv6)
2564 __connman_ipconfig_append_ipv6(service->ipconfig_ipv6, iter,
2565 service->ipconfig_ipv4);
2568 static void append_ipv4config(DBusMessageIter *iter, void *user_data)
2570 struct connman_service *service = user_data;
2572 if (service->ipconfig_ipv4)
2573 __connman_ipconfig_append_ipv4config(service->ipconfig_ipv4,
2577 static void append_ipv6config(DBusMessageIter *iter, void *user_data)
2579 struct connman_service *service = user_data;
2581 if (service->ipconfig_ipv6)
2582 __connman_ipconfig_append_ipv6config(service->ipconfig_ipv6,
2586 static void append_nameservers(DBusMessageIter *iter,
2587 struct connman_service *service, char **servers)
2590 bool available = true;
2592 for (i = 0; servers[i]; i++) {
2594 available = nameserver_available(service,
2595 CONNMAN_IPCONFIG_TYPE_ALL,
2599 dbus_message_iter_append_basic(iter,
2600 DBUS_TYPE_STRING, &servers[i]);
2604 #if defined TIZEN_EXT
2605 static void append_nameserver_manual(DBusMessageIter *iter,
2606 struct connman_service *service, const char *server)
2608 bool available = true;
2611 available = nameserver_available(service,
2612 CONNMAN_IPCONFIG_TYPE_ALL, server);
2615 dbus_message_iter_append_basic(iter,
2616 DBUS_TYPE_STRING, &server);
2619 static void append_nameserver_dhcp(DBusMessageIter *iter,
2620 struct connman_service *service, const char *server)
2622 bool available = true;
2625 available = nameserver_available(service,
2626 CONNMAN_IPCONFIG_TYPE_ALL, server);
2629 dbus_message_iter_append_basic(iter,
2630 DBUS_TYPE_STRING, &server);
2634 static void append_dns(DBusMessageIter *iter, void *user_data)
2636 struct connman_service *service = user_data;
2637 #if defined TIZEN_EXT
2641 if (!is_connected(service->state))
2647 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4);
2649 char *str1 = g_strdup_printf("ipv4.%s", str);
2650 dbus_message_iter_append_basic(iter,
2651 DBUS_TYPE_STRING, &str1);
2655 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6);
2657 char *str1 = g_strdup_printf("ipv6.%s", str);
2658 dbus_message_iter_append_basic(iter,
2659 DBUS_TYPE_STRING, &str1);
2664 if (service->nameservers_config) {
2665 #if defined TIZEN_EXT
2667 while (service->nameservers_config[i]) {
2668 if (connman_inet_check_ipaddress(
2669 service->nameservers_config[i]) == AF_INET &&
2670 service->dns_config_method_ipv4 ==
2671 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2672 append_nameserver_manual(iter, service,
2673 service->nameservers_config[i]);
2676 if (connman_inet_check_ipaddress(
2677 service->nameservers_config[i]) == AF_INET6 &&
2678 service->dns_config_method_ipv6 ==
2679 CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2680 append_nameserver_manual(iter, service,
2681 service->nameservers_config[i]);
2685 /* In case of mixed DNS Config Type one of IPv4/IPv6 can be
2686 * dynamic while other is static so try to append the DNS
2687 * Address which is dynamic also */
2688 if (service->nameservers != NULL) {
2690 while (service->nameservers[i]) {
2691 if (connman_inet_check_ipaddress(
2692 service->nameservers[i]) == AF_INET &&
2693 service->dns_config_method_ipv4 ==
2694 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2695 append_nameserver_dhcp(iter, service,
2696 service->nameservers[i]);
2699 if (connman_inet_check_ipaddress(
2700 service->nameservers[i]) == AF_INET6 &&
2701 service->dns_config_method_ipv6 ==
2702 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2703 append_nameserver_dhcp(iter, service,
2704 service->nameservers[i]);
2710 append_nameservers(iter, service, service->nameservers_config);
2714 if (service->nameservers)
2715 #if defined TIZEN_EXT
2718 while (service->nameservers[i]) {
2719 if (connman_inet_check_ipaddress(
2720 service->nameservers[i]) == AF_INET &&
2721 service->dns_config_method_ipv4 ==
2722 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2723 append_nameserver_dhcp(iter, service,
2724 service->nameservers[i]);
2727 if (connman_inet_check_ipaddress(
2728 service->nameservers[i]) == AF_INET6 &&
2729 service->dns_config_method_ipv6 ==
2730 CONNMAN_DNSCONFIG_METHOD_DHCP) {
2731 append_nameserver_dhcp(iter, service,
2732 service->nameservers[i]);
2738 append_nameservers(iter, service,
2739 service->nameservers);
2742 if (service->nameservers_auto)
2743 append_nameservers(iter, service,
2744 service->nameservers_auto);
2746 if (!service->nameservers && !service->nameservers_auto) {
2749 DBG("append fallback nameservers");
2751 ns = connman_setting_get_string_list("FallbackNameservers");
2753 append_nameservers(iter, service, ns);
2758 static void append_dnsconfig(DBusMessageIter *iter, void *user_data)
2760 struct connman_service *service = user_data;
2763 /* Append DNS Config Type */
2765 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv4);
2767 char *str1 = g_strdup_printf("ipv4.%s", str);
2768 dbus_message_iter_append_basic(iter,
2769 DBUS_TYPE_STRING, &str1);
2773 str = __connman_dnsconfig_method2string(service->dns_config_method_ipv6);
2775 char *str1 = g_strdup_printf("ipv6.%s", str);
2776 dbus_message_iter_append_basic(iter,
2777 DBUS_TYPE_STRING, &str1);
2782 if (!service->nameservers_config)
2785 #if defined TIZEN_EXT
2787 while (service->nameservers_config[i]) {
2788 if (connman_inet_check_ipaddress(service->nameservers_config[i]) == AF_INET &&
2789 service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2790 append_nameserver_manual(iter, NULL, service->nameservers_config[i]);
2793 if (connman_inet_check_ipaddress(service->nameservers_config[i]) == AF_INET6 &&
2794 service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL) {
2795 append_nameserver_manual(iter, NULL, service->nameservers_config[i]);
2800 append_nameservers(iter, NULL, service->nameservers_config);
2804 static void append_ts(DBusMessageIter *iter, void *user_data)
2806 GSList *list = user_data;
2809 char *timeserver = list->data;
2812 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
2815 list = g_slist_next(list);
2819 static void append_tsconfig(DBusMessageIter *iter, void *user_data)
2821 struct connman_service *service = user_data;
2824 if (!service->timeservers_config)
2827 for (i = 0; service->timeservers_config[i]; i++) {
2828 dbus_message_iter_append_basic(iter,
2830 &service->timeservers_config[i]);
2834 static void append_domainconfig(DBusMessageIter *iter, void *user_data)
2836 struct connman_service *service = user_data;
2839 if (!service->domains)
2842 for (i = 0; service->domains[i]; i++)
2843 dbus_message_iter_append_basic(iter,
2844 DBUS_TYPE_STRING, &service->domains[i]);
2847 static void append_domain(DBusMessageIter *iter, void *user_data)
2849 struct connman_service *service = user_data;
2851 if (!is_connected(service->state) &&
2852 !is_connecting(service->state))
2855 if (service->domains)
2856 append_domainconfig(iter, user_data);
2857 else if (service->domainname)
2858 dbus_message_iter_append_basic(iter,
2859 DBUS_TYPE_STRING, &service->domainname);
2862 static void append_proxies(DBusMessageIter *iter, void *user_data)
2864 struct connman_service *service = user_data;
2867 if (!service->proxies)
2870 for (i = 0; service->proxies[i]; i++)
2871 dbus_message_iter_append_basic(iter,
2872 DBUS_TYPE_STRING, &service->proxies[i]);
2875 static void append_excludes(DBusMessageIter *iter, void *user_data)
2877 struct connman_service *service = user_data;
2880 if (!service->excludes)
2883 for (i = 0; service->excludes[i]; i++)
2884 dbus_message_iter_append_basic(iter,
2885 DBUS_TYPE_STRING, &service->excludes[i]);
2888 static void append_proxy(DBusMessageIter *iter, void *user_data)
2890 struct connman_service *service = user_data;
2891 enum connman_service_proxy_method proxy;
2892 const char *pac = NULL;
2893 const char *method = proxymethod2string(
2894 CONNMAN_SERVICE_PROXY_METHOD_DIRECT);
2896 if (!is_connected(service->state))
2899 proxy = connman_service_get_proxy_method(service);
2902 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
2904 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
2906 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
2907 connman_dbus_dict_append_array(iter, "Servers",
2908 DBUS_TYPE_STRING, append_proxies,
2911 connman_dbus_dict_append_array(iter, "Excludes",
2912 DBUS_TYPE_STRING, append_excludes,
2915 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
2916 /* Maybe DHCP, or WPAD, has provided an url for a pac file */
2917 if (service->ipconfig_ipv4)
2918 pac = __connman_ipconfig_get_proxy_autoconfig(
2919 service->ipconfig_ipv4);
2920 else if (service->ipconfig_ipv6)
2921 pac = __connman_ipconfig_get_proxy_autoconfig(
2922 service->ipconfig_ipv6);
2924 if (!service->pac && !pac)
2930 connman_dbus_dict_append_basic(iter, "URL",
2931 DBUS_TYPE_STRING, &pac);
2935 method = proxymethod2string(proxy);
2938 connman_dbus_dict_append_basic(iter, "Method",
2939 DBUS_TYPE_STRING, &method);
2942 static void append_proxyconfig(DBusMessageIter *iter, void *user_data)
2944 struct connman_service *service = user_data;
2947 if (service->proxy_config == CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN)
2950 switch (service->proxy_config) {
2951 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
2953 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
2955 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
2956 if (service->proxies)
2957 connman_dbus_dict_append_array(iter, "Servers",
2959 append_proxies, service);
2961 if (service->excludes)
2962 connman_dbus_dict_append_array(iter, "Excludes",
2964 append_excludes, service);
2966 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
2968 connman_dbus_dict_append_basic(iter, "URL",
2969 DBUS_TYPE_STRING, &service->pac);
2973 method = proxymethod2string(service->proxy_config);
2975 connman_dbus_dict_append_basic(iter, "Method",
2976 DBUS_TYPE_STRING, &method);
2979 static void append_provider(DBusMessageIter *iter, void *user_data)
2981 struct connman_service *service = user_data;
2983 if (!is_connected(service->state))
2986 if (service->provider)
2987 __connman_provider_append_properties(service->provider, iter);
2991 static void settings_changed(struct connman_service *service,
2992 struct connman_ipconfig *ipconfig)
2994 enum connman_ipconfig_type type;
2996 type = __connman_ipconfig_get_config_type(ipconfig);
2998 __connman_notifier_ipconfig_changed(service, ipconfig);
3000 if (!allow_property_changed(service))
3003 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
3004 connman_dbus_property_changed_dict(service->path,
3005 CONNMAN_SERVICE_INTERFACE, "IPv4",
3006 append_ipv4, service);
3007 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
3008 connman_dbus_property_changed_dict(service->path,
3009 CONNMAN_SERVICE_INTERFACE, "IPv6",
3010 append_ipv6, service);
3013 static void ipv4_configuration_changed(struct connman_service *service)
3015 if (!allow_property_changed(service))
3018 connman_dbus_property_changed_dict(service->path,
3019 CONNMAN_SERVICE_INTERFACE,
3020 "IPv4.Configuration",
3025 void __connman_service_notify_ipv4_configuration(
3026 struct connman_service *service)
3031 ipv4_configuration_changed(service);
3034 static void ipv6_configuration_changed(struct connman_service *service)
3036 if (!allow_property_changed(service))
3039 connman_dbus_property_changed_dict(service->path,
3040 CONNMAN_SERVICE_INTERFACE,
3041 "IPv6.Configuration",
3046 static void dns_changed(struct connman_service *service)
3048 if (!allow_property_changed(service))
3051 connman_dbus_property_changed_array(service->path,
3052 CONNMAN_SERVICE_INTERFACE, "Nameservers",
3053 DBUS_TYPE_STRING, append_dns, service);
3056 static void dns_configuration_changed(struct connman_service *service)
3058 if (!allow_property_changed(service))
3061 connman_dbus_property_changed_array(service->path,
3062 CONNMAN_SERVICE_INTERFACE,
3063 "Nameservers.Configuration",
3064 DBUS_TYPE_STRING, append_dnsconfig, service);
3066 dns_changed(service);
3069 static void domain_changed(struct connman_service *service)
3071 if (!allow_property_changed(service))
3074 connman_dbus_property_changed_array(service->path,
3075 CONNMAN_SERVICE_INTERFACE, "Domains",
3076 DBUS_TYPE_STRING, append_domain, service);
3079 static void domain_configuration_changed(struct connman_service *service)
3081 if (!allow_property_changed(service))
3084 connman_dbus_property_changed_array(service->path,
3085 CONNMAN_SERVICE_INTERFACE,
3086 "Domains.Configuration",
3087 DBUS_TYPE_STRING, append_domainconfig, service);
3090 static void proxy_changed(struct connman_service *service)
3092 if (!allow_property_changed(service))
3095 connman_dbus_property_changed_dict(service->path,
3096 CONNMAN_SERVICE_INTERFACE, "Proxy",
3097 append_proxy, service);
3100 static void proxy_configuration_changed(struct connman_service *service)
3102 if (!allow_property_changed(service))
3105 connman_dbus_property_changed_dict(service->path,
3106 CONNMAN_SERVICE_INTERFACE, "Proxy.Configuration",
3107 append_proxyconfig, service);
3109 proxy_changed(service);
3112 static void mdns_changed(struct connman_service *service)
3114 dbus_bool_t mdns = service->mdns;
3116 if (!allow_property_changed(service))
3119 connman_dbus_property_changed_basic(service->path,
3120 CONNMAN_SERVICE_INTERFACE, "mDNS", DBUS_TYPE_BOOLEAN,
3124 static void mdns_configuration_changed(struct connman_service *service)
3126 dbus_bool_t mdns_config = service->mdns_config;
3128 if (!allow_property_changed(service))
3131 connman_dbus_property_changed_basic(service->path,
3132 CONNMAN_SERVICE_INTERFACE, "mDNS.Configuration",
3133 DBUS_TYPE_BOOLEAN, &mdns_config);
3136 static int set_mdns(struct connman_service *service,
3141 result = __connman_resolver_set_mdns(
3142 __connman_service_get_index(service), enabled);
3145 if (service->mdns != enabled) {
3146 service->mdns = enabled;
3147 mdns_changed(service);
3154 static void timeservers_configuration_changed(struct connman_service *service)
3156 if (!allow_property_changed(service))
3159 connman_dbus_property_changed_array(service->path,
3160 CONNMAN_SERVICE_INTERFACE,
3161 "Timeservers.Configuration",
3163 append_tsconfig, service);
3166 static void link_changed(struct connman_service *service)
3168 if (!allow_property_changed(service))
3171 connman_dbus_property_changed_dict(service->path,
3172 CONNMAN_SERVICE_INTERFACE, "Ethernet",
3173 append_ethernet, service);
3176 static void stats_append_counters(DBusMessageIter *dict,
3177 struct connman_stats_data *stats,
3178 struct connman_stats_data *counters,
3181 if (counters->rx_packets != stats->rx_packets || append_all) {
3182 counters->rx_packets = stats->rx_packets;
3183 connman_dbus_dict_append_basic(dict, "RX.Packets",
3184 DBUS_TYPE_UINT32, &stats->rx_packets);
3187 if (counters->tx_packets != stats->tx_packets || append_all) {
3188 counters->tx_packets = stats->tx_packets;
3189 connman_dbus_dict_append_basic(dict, "TX.Packets",
3190 DBUS_TYPE_UINT32, &stats->tx_packets);
3193 if (counters->rx_bytes != stats->rx_bytes || append_all) {
3194 counters->rx_bytes = stats->rx_bytes;
3195 connman_dbus_dict_append_basic(dict, "RX.Bytes",
3196 DBUS_TYPE_UINT32, &stats->rx_bytes);
3199 if (counters->tx_bytes != stats->tx_bytes || append_all) {
3200 counters->tx_bytes = stats->tx_bytes;
3201 connman_dbus_dict_append_basic(dict, "TX.Bytes",
3202 DBUS_TYPE_UINT32, &stats->tx_bytes);
3205 if (counters->rx_errors != stats->rx_errors || append_all) {
3206 counters->rx_errors = stats->rx_errors;
3207 connman_dbus_dict_append_basic(dict, "RX.Errors",
3208 DBUS_TYPE_UINT32, &stats->rx_errors);
3211 if (counters->tx_errors != stats->tx_errors || append_all) {
3212 counters->tx_errors = stats->tx_errors;
3213 connman_dbus_dict_append_basic(dict, "TX.Errors",
3214 DBUS_TYPE_UINT32, &stats->tx_errors);
3217 if (counters->rx_dropped != stats->rx_dropped || append_all) {
3218 counters->rx_dropped = stats->rx_dropped;
3219 connman_dbus_dict_append_basic(dict, "RX.Dropped",
3220 DBUS_TYPE_UINT32, &stats->rx_dropped);
3223 if (counters->tx_dropped != stats->tx_dropped || append_all) {
3224 counters->tx_dropped = stats->tx_dropped;
3225 connman_dbus_dict_append_basic(dict, "TX.Dropped",
3226 DBUS_TYPE_UINT32, &stats->tx_dropped);
3229 if (counters->time != stats->time || append_all) {
3230 counters->time = stats->time;
3231 connman_dbus_dict_append_basic(dict, "Time",
3232 DBUS_TYPE_UINT32, &stats->time);
3236 static void stats_append(struct connman_service *service,
3237 const char *counter,
3238 struct connman_stats_counter *counters,
3241 DBusMessageIter array, dict;
3244 DBG("service %p counter %s", service, counter);
3246 msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
3250 dbus_message_append_args(msg, DBUS_TYPE_OBJECT_PATH,
3251 &service->path, DBUS_TYPE_INVALID);
3253 dbus_message_iter_init_append(msg, &array);
3256 connman_dbus_dict_open(&array, &dict);
3258 stats_append_counters(&dict, &service->stats.data,
3259 &counters->stats.data, append_all);
3261 connman_dbus_dict_close(&array, &dict);
3263 /* roaming counter */
3264 connman_dbus_dict_open(&array, &dict);
3266 stats_append_counters(&dict, &service->stats_roaming.data,
3267 &counters->stats_roaming.data, append_all);
3269 connman_dbus_dict_close(&array, &dict);
3271 __connman_counter_send_usage(counter, msg);
3274 static void stats_update(struct connman_service *service,
3275 unsigned int rx_packets, unsigned int tx_packets,
3276 unsigned int rx_bytes, unsigned int tx_bytes,
3277 unsigned int rx_errors, unsigned int tx_errors,
3278 unsigned int rx_dropped, unsigned int tx_dropped)
3280 struct connman_stats *stats = stats_get(service);
3281 struct connman_stats_data *data_last = &stats->data_last;
3282 struct connman_stats_data *data = &stats->data;
3283 unsigned int seconds;
3285 DBG("service %p", service);
3289 rx_packets - data_last->rx_packets;
3291 tx_packets - data_last->tx_packets;
3293 rx_bytes - data_last->rx_bytes;
3295 tx_bytes - data_last->tx_bytes;
3297 rx_errors - data_last->rx_errors;
3299 tx_errors - data_last->tx_errors;
3301 rx_dropped - data_last->rx_dropped;
3303 tx_dropped - data_last->tx_dropped;
3305 stats->valid = true;
3308 data_last->rx_packets = rx_packets;
3309 data_last->tx_packets = tx_packets;
3310 data_last->rx_bytes = rx_bytes;
3311 data_last->tx_bytes = tx_bytes;
3312 data_last->rx_errors = rx_errors;
3313 data_last->tx_errors = tx_errors;
3314 data_last->rx_dropped = rx_dropped;
3315 data_last->tx_dropped = tx_dropped;
3317 seconds = g_timer_elapsed(stats->timer, NULL);
3318 stats->data.time = stats->data_last.time + seconds;
3321 void __connman_service_notify(struct connman_service *service,
3322 unsigned int rx_packets, unsigned int tx_packets,
3323 unsigned int rx_bytes, unsigned int tx_bytes,
3324 unsigned int rx_errors, unsigned int tx_errors,
3325 unsigned int rx_dropped, unsigned int tx_dropped)
3327 GHashTableIter iter;
3328 gpointer key, value;
3329 const char *counter;
3330 struct connman_stats_counter *counters;
3331 struct connman_stats_data *data;
3337 if (!is_connected(service->state))
3340 stats_update(service,
3341 rx_packets, tx_packets,
3343 rx_errors, tx_errors,
3344 rx_dropped, tx_dropped);
3346 data = &stats_get(service)->data;
3347 err = __connman_stats_update(service, service->roaming, data);
3349 connman_error("Failed to store statistics for %s",
3350 service->identifier);
3352 g_hash_table_iter_init(&iter, service->counter_table);
3353 while (g_hash_table_iter_next(&iter, &key, &value)) {
3357 stats_append(service, counter, counters, counters->append_all);
3358 counters->append_all = false;
3362 int __connman_service_counter_register(const char *counter)
3364 struct connman_service *service;
3366 struct connman_stats_counter *counters;
3368 DBG("counter %s", counter);
3370 counter_list = g_slist_prepend(counter_list, (gpointer)counter);
3372 for (list = service_list; list; list = list->next) {
3373 service = list->data;
3375 counters = g_try_new0(struct connman_stats_counter, 1);
3379 counters->append_all = true;
3381 g_hash_table_replace(service->counter_table, (gpointer)counter,
3388 void __connman_service_counter_unregister(const char *counter)
3390 struct connman_service *service;
3393 DBG("counter %s", counter);
3395 for (list = service_list; list; list = list->next) {
3396 service = list->data;
3398 g_hash_table_remove(service->counter_table, counter);
3401 counter_list = g_slist_remove(counter_list, counter);
3404 int connman_service_iterate_services(connman_service_iterate_cb cb,
3410 for (list = service_list; list && ret == 0; list = list->next)
3411 ret = cb((struct connman_service *)list->data, user_data);
3416 #if defined TIZEN_EXT
3417 static void append_wifi_ext_info(DBusMessageIter *dict,
3418 struct connman_network *network)
3420 char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
3421 char *bssid_str = bssid_buff;
3423 unsigned int ssid_len;
3424 unsigned char *bssid;
3425 unsigned int maxrate;
3427 unsigned int keymgmt;
3429 const char *enc_mode;
3432 char country_code_buff[WIFI_COUNTRY_CODE_LEN + 1] = {0,};
3433 char *country_code_str = country_code_buff;
3434 unsigned char *country_code;
3435 uint16_t connection_mode;
3437 ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len);
3438 bssid = connman_network_get_bssid(network);
3439 maxrate = connman_network_get_maxrate(network);
3440 maxspeed = connman_network_get_maxspeed(network);
3441 frequency = connman_network_get_frequency(network);
3442 enc_mode = connman_network_get_enc_mode(network);
3443 passpoint = connman_network_get_bool(network, "WiFi.HS20AP");
3444 keymgmt = connman_network_get_keymgmt(network);
3445 country_code = connman_network_get_countrycode(network);
3446 connection_mode = connman_network_get_connection_mode(network);
3448 snprintf(bssid_str, WIFI_BSSID_STR_LEN, "%02x:%02x:%02x:%02x:%02x:%02x",
3449 bssid[0], bssid[1], bssid[2],
3450 bssid[3], bssid[4], bssid[5]);
3452 snprintf(country_code_str, (WIFI_COUNTRY_CODE_LEN + 1), "%c%c",
3453 country_code[0], country_code[1]);
3456 connman_dbus_dict_append_fixed_array(dict, "SSID",
3457 DBUS_TYPE_BYTE, &ssid, ssid_len);
3458 connman_dbus_dict_append_basic(dict, "BSSID",
3459 DBUS_TYPE_STRING, &bssid_str);
3460 connman_dbus_dict_append_basic(dict, "MaxRate",
3461 DBUS_TYPE_UINT32, &maxrate);
3462 connman_dbus_dict_append_basic(dict, "MaxSpeed",
3463 DBUS_TYPE_INT32, &maxspeed);
3464 connman_dbus_dict_append_basic(dict, "Frequency",
3465 DBUS_TYPE_UINT16, &frequency);
3466 connman_dbus_dict_append_basic(dict, "EncryptionMode",
3467 DBUS_TYPE_STRING, &enc_mode);
3468 connman_dbus_dict_append_basic(dict, "Passpoint",
3469 DBUS_TYPE_BOOLEAN, &passpoint);
3470 connman_dbus_dict_append_basic(dict, "Keymgmt",
3471 DBUS_TYPE_UINT32, &keymgmt);
3472 connman_dbus_dict_append_basic(dict, "Country", DBUS_TYPE_STRING,
3474 connman_dbus_dict_append_basic(dict, "ConnMode",
3475 DBUS_TYPE_UINT16, &connection_mode);
3477 str = connman_network_get_string(network, "WiFi.Security");
3478 if (str != NULL && g_str_equal(str, "ieee8021x") == TRUE) {
3479 str = connman_network_get_string(network, "WiFi.EAP");
3481 connman_dbus_dict_append_basic(dict, "EAP",
3482 DBUS_TYPE_STRING, &str);
3484 str = connman_network_get_string(network, "WiFi.Phase2");
3486 connman_dbus_dict_append_basic(dict, "Phase2",
3487 DBUS_TYPE_STRING, &str);
3489 str = connman_network_get_string(network, "WiFi.Identity");
3491 connman_dbus_dict_append_basic(dict, "Identity",
3492 DBUS_TYPE_STRING, &str);
3494 str = connman_network_get_string(network, "WiFi.CACertFile");
3496 connman_dbus_dict_append_basic(dict, "CACertFile",
3497 DBUS_TYPE_STRING, &str);
3499 str = connman_network_get_string(network,
3500 "WiFi.ClientCertFile");
3502 connman_dbus_dict_append_basic(dict, "ClientCertFile",
3503 DBUS_TYPE_STRING, &str);
3505 str = connman_network_get_string(network,
3506 "WiFi.PrivateKeyFile");
3508 connman_dbus_dict_append_basic(dict, "PrivateKeyFile",
3509 DBUS_TYPE_STRING, &str);
3513 static void append_bssid_info(DBusMessageIter *iter, void *user_data)
3515 GSList *bssid_list = NULL;
3516 struct connman_network *network = user_data;
3517 struct connman_bssids *bssids;
3518 char bssid_buf[MAC_ADDRESS_LENGTH] = {0,};
3519 char *bssid_str = bssid_buf;
3521 bssid_list = (GSList *)connman_network_get_bssid_list(network);
3524 for (list = bssid_list; list; list = list->next) {
3525 bssids = (struct connman_bssids *)list->data;
3526 g_snprintf(bssid_buf, MAC_ADDRESS_LENGTH, "%02x:%02x:%02x:%02x:%02x:%02x",
3527 bssids->bssid[0], bssids->bssid[1], bssids->bssid[2],
3528 bssids->bssid[3], bssids->bssid[4], bssids->bssid[5]);
3530 connman_dbus_dict_append_basic(iter, "BSSID",
3531 DBUS_TYPE_STRING, &bssid_str);
3533 connman_dbus_dict_append_basic(iter, "Strength",
3534 DBUS_TYPE_UINT16, &bssids->strength);
3536 connman_dbus_dict_append_basic(iter, "Frequency",
3537 DBUS_TYPE_UINT16, &bssids->frequency);
3543 static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
3544 struct connman_service *service)
3550 #if defined TIZEN_EXT
3551 unsigned int frequency = 0U;
3552 unsigned char *wifi_vsie;
3553 unsigned int wifi_vsie_len;
3554 GSList *vsie_list = NULL;
3556 if (service->network) {
3557 frequency = connman_network_get_frequency(service->network);
3558 connman_dbus_dict_append_basic(dict, "Frequency",
3559 DBUS_TYPE_UINT16, &frequency);
3560 vsie_list = (GSList *)connman_network_get_vsie_list(service->network);
3565 for (list = vsie_list; list; list = list->next) {
3566 wifi_vsie = (unsigned char *)list->data;
3567 wifi_vsie_len = wifi_vsie[1] + 2;
3569 connman_dbus_dict_append_fixed_array(dict, "Vsie", DBUS_TYPE_BYTE,
3570 &wifi_vsie, wifi_vsie_len);
3575 str = __connman_service_type2string(service->type);
3577 connman_dbus_dict_append_basic(dict, "Type",
3578 DBUS_TYPE_STRING, &str);
3580 connman_dbus_dict_append_array(dict, "Security",
3581 DBUS_TYPE_STRING, append_security, service);
3583 str = state2string(service->state);
3585 connman_dbus_dict_append_basic(dict, "State",
3586 DBUS_TYPE_STRING, &str);
3589 str = state2string(service->state_ipv6);
3591 connman_dbus_dict_append_basic(dict, "StateIPv6",
3592 DBUS_TYPE_STRING, &str);
3595 str = error2string(service->error);
3597 connman_dbus_dict_append_basic(dict, "Error",
3598 DBUS_TYPE_STRING, &str);
3600 if (service->strength > 0)
3601 connman_dbus_dict_append_basic(dict, "Strength",
3602 DBUS_TYPE_BYTE, &service->strength);
3604 val = service->favorite;
3605 connman_dbus_dict_append_basic(dict, "Favorite",
3606 DBUS_TYPE_BOOLEAN, &val);
3608 val = service->immutable;
3609 connman_dbus_dict_append_basic(dict, "Immutable",
3610 DBUS_TYPE_BOOLEAN, &val);
3612 if (service->favorite)
3613 val = service->autoconnect;
3615 val = service->favorite;
3617 connman_dbus_dict_append_basic(dict, "AutoConnect",
3618 DBUS_TYPE_BOOLEAN, &val);
3621 connman_dbus_dict_append_basic(dict, "Name",
3622 DBUS_TYPE_STRING, &service->name);
3624 switch (service->type) {
3625 case CONNMAN_SERVICE_TYPE_UNKNOWN:
3626 case CONNMAN_SERVICE_TYPE_SYSTEM:
3627 case CONNMAN_SERVICE_TYPE_GPS:
3628 case CONNMAN_SERVICE_TYPE_VPN:
3629 case CONNMAN_SERVICE_TYPE_P2P:
3630 #if defined TIZEN_EXT_WIFI_MESH
3631 case CONNMAN_SERVICE_TYPE_MESH:
3634 case CONNMAN_SERVICE_TYPE_CELLULAR:
3635 val = service->roaming;
3636 connman_dbus_dict_append_basic(dict, "Roaming",
3637 DBUS_TYPE_BOOLEAN, &val);
3639 connman_dbus_dict_append_dict(dict, "Ethernet",
3640 append_ethernet, service);
3642 case CONNMAN_SERVICE_TYPE_WIFI:
3643 #if defined TIZEN_EXT
3644 if (service->network != NULL) {
3645 append_wifi_ext_info(dict, service->network);
3646 connman_dbus_dict_append_dict(dict, "BSSID.List",
3647 append_bssid_info, service->network);
3650 connman_dbus_dict_append_dict(dict, "Ethernet",
3651 append_ethernet, service);
3653 service->disconnect_reason = connman_network_get_disconnect_reason(service->network);
3654 connman_dbus_dict_append_basic(dict, "DisconnectReason",
3655 DBUS_TYPE_INT32, &service->disconnect_reason);
3657 connman_dbus_dict_append_basic(dict, "AssocStatusCode",
3658 DBUS_TYPE_INT32, &service->assoc_status_code);
3660 connman_dbus_dict_append_basic(dict, "Hidden",
3661 DBUS_TYPE_BOOLEAN, &service->hidden_service);
3665 case CONNMAN_SERVICE_TYPE_ETHERNET:
3666 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
3667 case CONNMAN_SERVICE_TYPE_GADGET:
3668 connman_dbus_dict_append_dict(dict, "Ethernet",
3669 append_ethernet, service);
3673 connman_dbus_dict_append_dict(dict, "IPv4", append_ipv4, service);
3675 connman_dbus_dict_append_dict(dict, "IPv4.Configuration",
3676 append_ipv4config, service);
3678 connman_dbus_dict_append_dict(dict, "IPv6", append_ipv6, service);
3680 connman_dbus_dict_append_dict(dict, "IPv6.Configuration",
3681 append_ipv6config, service);
3683 connman_dbus_dict_append_array(dict, "Nameservers",
3684 DBUS_TYPE_STRING, append_dns, service);
3686 connman_dbus_dict_append_array(dict, "Nameservers.Configuration",
3687 DBUS_TYPE_STRING, append_dnsconfig, service);
3689 if (service->state == CONNMAN_SERVICE_STATE_READY ||
3690 service->state == CONNMAN_SERVICE_STATE_ONLINE)
3691 list = __connman_timeserver_get_all(service);
3695 connman_dbus_dict_append_array(dict, "Timeservers",
3696 DBUS_TYPE_STRING, append_ts, list);
3698 g_slist_free_full(list, g_free);
3700 connman_dbus_dict_append_array(dict, "Timeservers.Configuration",
3701 DBUS_TYPE_STRING, append_tsconfig, service);
3703 connman_dbus_dict_append_array(dict, "Domains",
3704 DBUS_TYPE_STRING, append_domain, service);
3706 connman_dbus_dict_append_array(dict, "Domains.Configuration",
3707 DBUS_TYPE_STRING, append_domainconfig, service);
3709 connman_dbus_dict_append_dict(dict, "Proxy", append_proxy, service);
3711 connman_dbus_dict_append_dict(dict, "Proxy.Configuration",
3712 append_proxyconfig, service);
3714 val = service->mdns;
3715 connman_dbus_dict_append_basic(dict, "mDNS", DBUS_TYPE_BOOLEAN,
3718 val = service->mdns_config;
3719 connman_dbus_dict_append_basic(dict, "mDNS.Configuration",
3720 DBUS_TYPE_BOOLEAN, &val);
3722 connman_dbus_dict_append_dict(dict, "Provider",
3723 append_provider, service);
3725 if (service->network)
3726 connman_network_append_acddbus(dict, service->network);
3729 static void append_struct_service(DBusMessageIter *iter,
3730 connman_dbus_append_cb_t function,
3731 struct connman_service *service)
3733 DBusMessageIter entry, dict;
3735 dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &entry);
3737 dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
3740 connman_dbus_dict_open(&entry, &dict);
3742 function(&dict, service);
3743 connman_dbus_dict_close(&entry, &dict);
3745 dbus_message_iter_close_container(iter, &entry);
3748 static void append_dict_properties(DBusMessageIter *dict, void *user_data)
3750 struct connman_service *service = user_data;
3752 append_properties(dict, TRUE, service);
3755 static void append_struct(gpointer value, gpointer user_data)
3757 struct connman_service *service = value;
3758 DBusMessageIter *iter = user_data;
3763 append_struct_service(iter, append_dict_properties, service);
3766 void __connman_service_list_struct(DBusMessageIter *iter)
3768 g_list_foreach(service_list, append_struct, iter);
3771 bool __connman_service_is_hidden(struct connman_service *service)
3773 return service->hidden;
3777 __connman_service_is_split_routing(struct connman_service *service)
3779 return service->do_split_routing;
3782 bool __connman_service_index_is_split_routing(int index)
3784 struct connman_service *service;
3789 service = __connman_service_lookup_from_index(index);
3793 return __connman_service_is_split_routing(service);
3796 int __connman_service_get_index(struct connman_service *service)
3801 if (service->network)
3802 return connman_network_get_index(service->network);
3803 else if (service->provider)
3804 return connman_provider_get_index(service->provider);
3809 void __connman_service_set_hidden(struct connman_service *service)
3811 if (!service || service->hidden)
3814 service->hidden_service = true;
3817 void __connman_service_set_hostname(struct connman_service *service,
3818 const char *hostname)
3820 if (!service || service->hidden)
3823 g_free(service->hostname);
3824 service->hostname = NULL;
3826 if (hostname && g_str_is_ascii(hostname))
3827 service->hostname = g_strdup(hostname);
3830 const char *__connman_service_get_hostname(struct connman_service *service)
3835 return service->hostname;
3838 void __connman_service_set_domainname(struct connman_service *service,
3839 const char *domainname)
3841 if (!service || service->hidden)
3844 g_free(service->domainname);
3845 service->domainname = NULL;
3847 if (domainname && g_str_is_ascii(domainname))
3848 service->domainname = g_strdup(domainname);
3850 domain_changed(service);
3853 const char *connman_service_get_domainname(struct connman_service *service)
3858 if (service->domains)
3859 return service->domains[0];
3861 return service->domainname;
3864 const char *connman_service_get_dbuspath(struct connman_service *service)
3869 return service->path;
3872 char **connman_service_get_nameservers(struct connman_service *service)
3877 if (service->nameservers_config)
3878 return g_strdupv(service->nameservers_config);
3879 else if (service->nameservers ||
3880 service->nameservers_auto) {
3881 int len = 0, len_auto = 0, i;
3884 if (service->nameservers)
3885 len = g_strv_length(service->nameservers);
3886 if (service->nameservers_auto)
3887 len_auto = g_strv_length(service->nameservers_auto);
3889 nameservers = g_try_new0(char *, len + len_auto + 1);
3893 for (i = 0; i < len; i++)
3894 nameservers[i] = g_strdup(service->nameservers[i]);
3896 for (i = 0; i < len_auto; i++)
3897 nameservers[i + len] =
3898 g_strdup(service->nameservers_auto[i]);
3903 return g_strdupv(connman_setting_get_string_list("FallbackNameservers"));
3906 char **connman_service_get_timeservers_config(struct connman_service *service)
3911 return service->timeservers_config;
3914 char **connman_service_get_timeservers(struct connman_service *service)
3919 return service->timeservers;
3922 #if defined TIZEN_EXT
3924 * Description: Telephony plug-in requires manual PROXY setting function
3926 int connman_service_set_proxy(struct connman_service *service,
3927 const char *proxy, gboolean active)
3929 char **proxies_array = NULL;
3931 if (service == NULL)
3934 switch (service->type) {
3935 case CONNMAN_SERVICE_TYPE_CELLULAR:
3936 case CONNMAN_SERVICE_TYPE_ETHERNET:
3937 case CONNMAN_SERVICE_TYPE_WIFI:
3944 g_strfreev(service->proxies);
3945 service->proxies = NULL;
3948 proxies_array = g_strsplit(proxy, " ", 0);
3950 service->proxies = proxies_array;
3952 if (proxy == NULL) {
3953 service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
3954 DBG("proxy changed (%d)", active);
3956 service->proxy_config = CONNMAN_SERVICE_PROXY_METHOD_MANUAL;
3957 DBG("proxy chagned %s (%d)", proxy, active);
3960 if (active == TRUE) {
3961 proxy_changed(service);
3963 __connman_notifier_proxy_changed(service);
3970 void connman_service_set_proxy_method(struct connman_service *service,
3971 enum connman_service_proxy_method method)
3973 if (!service || service->hidden)
3976 service->proxy = method;
3978 proxy_changed(service);
3980 if (method != CONNMAN_SERVICE_PROXY_METHOD_AUTO)
3981 __connman_notifier_proxy_changed(service);
3984 enum connman_service_proxy_method connman_service_get_proxy_method(
3985 struct connman_service *service)
3988 return CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
3990 if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN) {
3991 if (service->proxy_config == CONNMAN_SERVICE_PROXY_METHOD_AUTO &&
3993 return service->proxy;
3995 return service->proxy_config;
3998 return service->proxy;
4001 char **connman_service_get_proxy_servers(struct connman_service *service)
4003 return g_strdupv(service->proxies);
4006 char **connman_service_get_proxy_excludes(struct connman_service *service)
4008 return g_strdupv(service->excludes);
4011 const char *connman_service_get_proxy_url(struct connman_service *service)
4016 return service->pac;
4019 void __connman_service_set_proxy_autoconfig(struct connman_service *service,
4022 if (!service || service->hidden)
4025 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_AUTO;
4027 if (service->ipconfig_ipv4) {
4028 if (__connman_ipconfig_set_proxy_autoconfig(
4029 service->ipconfig_ipv4, url) < 0)
4031 } else if (service->ipconfig_ipv6) {
4032 if (__connman_ipconfig_set_proxy_autoconfig(
4033 service->ipconfig_ipv6, url) < 0)
4038 proxy_changed(service);
4040 __connman_notifier_proxy_changed(service);
4043 const char *connman_service_get_proxy_autoconfig(struct connman_service *service)
4048 if (service->ipconfig_ipv4)
4049 return __connman_ipconfig_get_proxy_autoconfig(
4050 service->ipconfig_ipv4);
4051 else if (service->ipconfig_ipv6)
4052 return __connman_ipconfig_get_proxy_autoconfig(
4053 service->ipconfig_ipv6);
4057 #if defined TIZEN_EXT
4058 int connman_service_get_ipv6_dns_method(struct connman_service *service)
4061 DBG("Service is NULL");
4065 return service->dns_config_method_ipv6;
4069 void __connman_service_set_timeservers(struct connman_service *service,
4077 g_strfreev(service->timeservers);
4078 service->timeservers = NULL;
4080 for (i = 0; timeservers && timeservers[i]; i++)
4081 __connman_service_timeserver_append(service, timeservers[i]);
4084 int __connman_service_timeserver_append(struct connman_service *service,
4085 const char *timeserver)
4089 DBG("service %p timeserver %s", service, timeserver);
4094 if (service->timeservers) {
4097 for (i = 0; service->timeservers[i]; i++)
4098 if (g_strcmp0(service->timeservers[i], timeserver) == 0)
4101 len = g_strv_length(service->timeservers);
4102 service->timeservers = g_try_renew(char *, service->timeservers,
4106 service->timeservers = g_try_new0(char *, len + 2);
4109 if (!service->timeservers)
4112 service->timeservers[len] = g_strdup(timeserver);
4113 service->timeservers[len + 1] = NULL;
4118 int __connman_service_timeserver_remove(struct connman_service *service,
4119 const char *timeserver)
4122 int len, i, j, found = 0;
4124 DBG("service %p timeserver %s", service, timeserver);
4129 if (!service->timeservers)
4132 for (i = 0; service->timeservers &&
4133 service->timeservers[i]; i++)
4134 if (g_strcmp0(service->timeservers[i], timeserver) == 0) {
4142 len = g_strv_length(service->timeservers);
4145 g_strfreev(service->timeservers);
4146 service->timeservers = NULL;
4151 servers = g_try_new0(char *, len);
4155 for (i = 0, j = 0; i < len; i++) {
4156 if (g_strcmp0(service->timeservers[i], timeserver) != 0) {
4157 servers[j] = g_strdup(service->timeservers[i]);
4163 servers[len - 1] = NULL;
4165 g_strfreev(service->timeservers);
4166 service->timeservers = servers;
4171 void __connman_service_timeserver_changed(struct connman_service *service,
4177 if (!allow_property_changed(service))
4180 connman_dbus_property_changed_array(service->path,
4181 CONNMAN_SERVICE_INTERFACE, "Timeservers",
4182 DBUS_TYPE_STRING, append_ts, ts_list);
4185 void __connman_service_set_pac(struct connman_service *service,
4188 if (service->hidden)
4190 g_free(service->pac);
4191 service->pac = g_strdup(pac);
4193 proxy_changed(service);
4196 #if defined TIZEN_EXT
4197 void __connman_service_set_proxy(struct connman_service *service,
4198 const char *proxies)
4200 char **proxies_array = NULL;
4202 g_strfreev(service->proxies);
4203 service->proxies = NULL;
4205 if (proxies != NULL)
4206 proxies_array = g_strsplit(proxies, " ", 0);
4208 service->proxies = proxies_array;
4212 void __connman_service_set_identity(struct connman_service *service,
4213 const char *identity)
4215 if (service->immutable || service->hidden)
4218 g_free(service->identity);
4219 service->identity = g_strdup(identity);
4221 if (service->network)
4222 connman_network_set_string(service->network,
4227 void __connman_service_set_anonymous_identity(struct connman_service *service,
4228 const char *anonymous_identity)
4230 if (service->immutable || service->hidden)
4233 g_free(service->anonymous_identity);
4234 service->anonymous_identity = g_strdup(anonymous_identity);
4236 if (service->network)
4237 connman_network_set_string(service->network,
4238 "WiFi.AnonymousIdentity",
4239 service->anonymous_identity);
4242 void __connman_service_set_subject_match(struct connman_service *service,
4243 const char *subject_match)
4245 if (service->immutable || service->hidden)
4248 g_free(service->subject_match);
4249 service->subject_match = g_strdup(subject_match);
4251 if (service->network)
4252 connman_network_set_string(service->network,
4253 "WiFi.SubjectMatch",
4254 service->subject_match);
4257 void __connman_service_set_altsubject_match(struct connman_service *service,
4258 const char *altsubject_match)
4260 if (service->immutable || service->hidden)
4263 g_free(service->altsubject_match);
4264 service->altsubject_match = g_strdup(altsubject_match);
4266 if (service->network)
4267 connman_network_set_string(service->network,
4268 "WiFi.AltSubjectMatch",
4269 service->altsubject_match);
4272 void __connman_service_set_domain_suffix_match(struct connman_service *service,
4273 const char *domain_suffix_match)
4275 if (service->immutable || service->hidden)
4278 g_free(service->domain_suffix_match);
4279 service->domain_suffix_match = g_strdup(domain_suffix_match);
4281 if (service->network)
4282 connman_network_set_string(service->network,
4283 "WiFi.DomainSuffixMatch",
4284 service->domain_suffix_match);
4287 void __connman_service_set_domain_match(struct connman_service *service,
4288 const char *domain_match)
4290 if (service->immutable || service->hidden)
4293 g_free(service->domain_match);
4294 service->domain_match = g_strdup(domain_match);
4296 if (service->network)
4297 connman_network_set_string(service->network,
4299 service->domain_match);
4302 void __connman_service_set_agent_identity(struct connman_service *service,
4303 const char *agent_identity)
4305 if (service->hidden)
4307 g_free(service->agent_identity);
4308 service->agent_identity = g_strdup(agent_identity);
4310 if (service->network)
4311 connman_network_set_string(service->network,
4312 "WiFi.AgentIdentity",
4313 service->agent_identity);
4316 int __connman_service_check_passphrase(enum connman_service_security security,
4317 const char *passphrase)
4325 length = strlen(passphrase);
4328 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
4329 case CONNMAN_SERVICE_SECURITY_NONE:
4330 case CONNMAN_SERVICE_SECURITY_WPA:
4331 #if !defined TIZEN_EXT
4332 case CONNMAN_SERVICE_SECURITY_RSN:
4335 DBG("service security '%s' (%d) not handled",
4336 security2string(security), security);
4340 case CONNMAN_SERVICE_SECURITY_PSK:
4341 #if defined TIZEN_EXT
4342 case CONNMAN_SERVICE_SECURITY_RSN:
4343 /* TO CHECK: We need to check the key length supported by SAE */
4344 case CONNMAN_SERVICE_SECURITY_SAE:
4346 /* A raw key is always 64 bytes length,
4347 * its content is in hex representation.
4348 * A PSK key must be between [8..63].
4351 for (i = 0; i < 64; i++)
4352 if (!isxdigit((unsigned char)
4355 } else if (length < 8 || length > 63)
4358 case CONNMAN_SERVICE_SECURITY_WEP:
4359 /* length of WEP key is 10 or 26
4360 * length of WEP passphrase is 5 or 13
4362 if (length == 10 || length == 26) {
4363 for (i = 0; i < length; i++)
4364 if (!isxdigit((unsigned char)
4367 } else if (length != 5 && length != 13)
4371 case CONNMAN_SERVICE_SECURITY_8021X:
4372 #if defined TIZEN_EXT
4373 case CONNMAN_SERVICE_SECURITY_OWE:
4374 case CONNMAN_SERVICE_SECURITY_DPP:
4382 int __connman_service_set_passphrase(struct connman_service *service,
4383 const char *passphrase)
4387 if (service->hidden)
4390 if (service->immutable &&
4391 service->security != CONNMAN_SERVICE_SECURITY_8021X)
4394 #if defined TIZEN_EXT
4395 if (service->immutable &&
4396 service->security != CONNMAN_SERVICE_SECURITY_DPP)
4398 /* The encrypted passphrase is used here
4399 * and validation is done by net-config before being encrypted.
4402 if (service->security != CONNMAN_SERVICE_SECURITY_PSK &&
4403 service->security != CONNMAN_SERVICE_SECURITY_RSN &&
4404 service->security != CONNMAN_SERVICE_SECURITY_SAE &&
4405 service->security != CONNMAN_SERVICE_SECURITY_WEP)
4407 err = __connman_service_check_passphrase(service->security, passphrase);
4412 g_free(service->passphrase);
4413 service->passphrase = g_strdup(passphrase);
4415 if (service->network)
4416 connman_network_set_string(service->network, "WiFi.Passphrase",
4417 service->passphrase);
4422 const char *__connman_service_get_passphrase(struct connman_service *service)
4427 return service->passphrase;
4430 static DBusMessage *get_properties(DBusConnection *conn,
4431 DBusMessage *msg, void *user_data)
4433 struct connman_service *service = user_data;
4435 DBusMessageIter array, dict;
4437 reply = dbus_message_new_method_return(msg);
4441 dbus_message_iter_init_append(reply, &array);
4443 connman_dbus_dict_open(&array, &dict);
4444 append_properties(&dict, FALSE, service);
4445 connman_dbus_dict_close(&array, &dict);
4450 static char **remove_empty_strings(char **strv)
4457 strv[index++] = *iter;
4467 static int update_proxy_configuration(struct connman_service *service,
4468 DBusMessageIter *array)
4470 DBusMessageIter dict;
4471 enum connman_service_proxy_method method;
4472 GString *servers_str = NULL;
4473 GString *excludes_str = NULL;
4474 const char *url = NULL;
4476 method = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
4478 dbus_message_iter_recurse(array, &dict);
4480 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
4481 DBusMessageIter entry, variant;
4485 dbus_message_iter_recurse(&dict, &entry);
4487 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
4490 dbus_message_iter_get_basic(&entry, &key);
4491 dbus_message_iter_next(&entry);
4493 if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
4496 dbus_message_iter_recurse(&entry, &variant);
4498 type = dbus_message_iter_get_arg_type(&variant);
4500 if (g_str_equal(key, "Method")) {
4503 if (type != DBUS_TYPE_STRING)
4506 dbus_message_iter_get_basic(&variant, &val);
4507 method = string2proxymethod(val);
4508 } else if (g_str_equal(key, "URL")) {
4509 if (type != DBUS_TYPE_STRING)
4512 dbus_message_iter_get_basic(&variant, &url);
4513 } else if (g_str_equal(key, "Servers")) {
4514 DBusMessageIter str_array;
4516 if (type != DBUS_TYPE_ARRAY)
4519 servers_str = g_string_new(NULL);
4523 dbus_message_iter_recurse(&variant, &str_array);
4525 while (dbus_message_iter_get_arg_type(&str_array) ==
4529 dbus_message_iter_get_basic(&str_array, &val);
4531 if (servers_str->len > 0)
4532 g_string_append_printf(servers_str,
4535 g_string_append(servers_str, val);
4537 dbus_message_iter_next(&str_array);
4539 } else if (g_str_equal(key, "Excludes")) {
4540 DBusMessageIter str_array;
4542 if (type != DBUS_TYPE_ARRAY)
4545 excludes_str = g_string_new(NULL);
4549 dbus_message_iter_recurse(&variant, &str_array);
4551 while (dbus_message_iter_get_arg_type(&str_array) ==
4555 dbus_message_iter_get_basic(&str_array, &val);
4557 if (excludes_str->len > 0)
4558 g_string_append_printf(excludes_str,
4561 g_string_append(excludes_str, val);
4563 dbus_message_iter_next(&str_array);
4567 dbus_message_iter_next(&dict);
4571 case CONNMAN_SERVICE_PROXY_METHOD_DIRECT:
4573 case CONNMAN_SERVICE_PROXY_METHOD_MANUAL:
4574 if (!servers_str && !service->proxies)
4578 g_strfreev(service->proxies);
4580 if (servers_str->len > 0) {
4581 char **proxies = g_strsplit_set(
4582 servers_str->str, " ", 0);
4583 proxies = remove_empty_strings(proxies);
4584 service->proxies = proxies;
4586 service->proxies = NULL;
4590 g_strfreev(service->excludes);
4592 if (excludes_str->len > 0) {
4593 char **excludes = g_strsplit_set(
4594 excludes_str->str, " ", 0);
4595 excludes = remove_empty_strings(excludes);
4596 service->excludes = excludes;
4598 service->excludes = NULL;
4601 if (!service->proxies)
4602 method = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
4605 case CONNMAN_SERVICE_PROXY_METHOD_AUTO:
4606 g_free(service->pac);
4608 if (url && strlen(url) > 0)
4609 service->pac = g_strstrip(g_strdup(url));
4611 service->pac = NULL;
4613 /* if we are connected:
4614 - if service->pac == NULL
4615 - if __connman_ipconfig_get_proxy_autoconfig(
4616 service->ipconfig) == NULL
4617 --> We should start WPAD */
4620 case CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN:
4625 g_string_free(servers_str, TRUE);
4628 g_string_free(excludes_str, TRUE);
4630 service->proxy_config = method;
4636 g_string_free(servers_str, TRUE);
4639 g_string_free(excludes_str, TRUE);
4644 int __connman_service_reset_ipconfig(struct connman_service *service,
4645 enum connman_ipconfig_type type, DBusMessageIter *array,
4646 enum connman_service_state *new_state)
4648 struct connman_ipconfig *ipconfig, *new_ipconfig;
4649 enum connman_ipconfig_method old_method, new_method;
4650 enum connman_service_state state;
4653 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
4654 ipconfig = service->ipconfig_ipv4;
4655 state = service->state_ipv4;
4656 new_method = CONNMAN_IPCONFIG_METHOD_DHCP;
4657 } else if (type == CONNMAN_IPCONFIG_TYPE_IPV6) {
4658 ipconfig = service->ipconfig_ipv6;
4659 state = service->state_ipv6;
4660 new_method = CONNMAN_IPCONFIG_METHOD_AUTO;
4667 old_method = __connman_ipconfig_get_method(ipconfig);
4668 index = __connman_ipconfig_get_index(ipconfig);
4670 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4671 new_ipconfig = create_ip4config(service, index,
4672 CONNMAN_IPCONFIG_METHOD_UNKNOWN);
4674 new_ipconfig = create_ip6config(service, index);
4677 err = __connman_ipconfig_set_config(new_ipconfig, array);
4679 __connman_ipconfig_unref(new_ipconfig);
4683 new_method = __connman_ipconfig_get_method(new_ipconfig);
4686 if (is_connecting(state) || is_connected(state))
4687 __connman_network_clear_ipconfig(service->network, ipconfig);
4689 __connman_ipconfig_unref(ipconfig);
4691 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4692 service->ipconfig_ipv4 = new_ipconfig;
4693 else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
4694 service->ipconfig_ipv6 = new_ipconfig;
4696 if (is_connecting(state) || is_connected(state))
4697 __connman_ipconfig_enable(new_ipconfig);
4699 if (new_state && new_method != old_method) {
4700 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4701 *new_state = service->state_ipv4;
4703 *new_state = service->state_ipv6;
4705 settings_changed(service, new_ipconfig);
4706 address_updated(service, type);
4708 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
4711 DBG("err %d ipconfig %p type %d method %d state %s", err,
4712 new_ipconfig, type, new_method,
4713 !new_state ? "-" : state2string(*new_state));
4719 * We set the timeout to 1 sec so that we have a chance to get
4720 * necessary IPv6 router advertisement messages that might have
4723 #define ONLINE_CHECK_INITIAL_INTERVAL 1
4724 #define ONLINE_CHECK_MAX_INTERVAL 12
4726 void __connman_service_wispr_start(struct connman_service *service,
4727 enum connman_ipconfig_type type)
4729 DBG("service %p type %s", service, __connman_ipconfig_type2string(type));
4731 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
4732 service->online_check_interval_ipv4 =
4733 ONLINE_CHECK_INITIAL_INTERVAL;
4735 service->online_check_interval_ipv6 =
4736 ONLINE_CHECK_INITIAL_INTERVAL;
4738 __connman_wispr_start(service, type);
4741 static DBusMessage *set_property(DBusConnection *conn,
4742 DBusMessage *msg, void *user_data)
4744 struct connman_service *service = user_data;
4745 DBusMessageIter iter, value;
4749 DBG("service %p", service);
4751 if (!dbus_message_iter_init(msg, &iter))
4752 return __connman_error_invalid_arguments(msg);
4754 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
4755 return __connman_error_invalid_arguments(msg);
4757 dbus_message_iter_get_basic(&iter, &name);
4758 dbus_message_iter_next(&iter);
4760 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
4761 return __connman_error_invalid_arguments(msg);
4763 dbus_message_iter_recurse(&iter, &value);
4765 type = dbus_message_iter_get_arg_type(&value);
4767 if (g_str_equal(name, "AutoConnect")) {
4768 dbus_bool_t autoconnect;
4770 if (type != DBUS_TYPE_BOOLEAN)
4771 return __connman_error_invalid_arguments(msg);
4773 if (!service->favorite)
4774 return __connman_error_invalid_service(msg);
4776 dbus_message_iter_get_basic(&value, &autoconnect);
4778 if (service->autoconnect == autoconnect)
4779 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
4781 service->autoconnect = autoconnect;
4783 autoconnect_changed(service);
4786 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
4788 service_save(service);
4789 } else if (g_str_equal(name, "Nameservers.Configuration")) {
4790 DBusMessageIter entry;
4794 #if defined TIZEN_EXT
4795 enum connman_ipconfig_type ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4799 if (__connman_provider_is_immutable(service->provider) ||
4801 return __connman_error_not_supported(msg);
4803 if (type != DBUS_TYPE_ARRAY)
4804 return __connman_error_invalid_arguments(msg);
4806 str = g_string_new(NULL);
4808 return __connman_error_invalid_arguments(msg);
4810 index = __connman_service_get_index(service);
4811 gw = __connman_ipconfig_get_gateway_from_index(index,
4812 CONNMAN_IPCONFIG_TYPE_ALL);
4814 #if !defined TIZEN_EXT
4815 if (gw && strlen(gw))
4816 __connman_service_nameserver_del_routes(service,
4817 CONNMAN_IPCONFIG_TYPE_ALL);
4820 dbus_message_iter_recurse(&value, &entry);
4822 #if defined TIZEN_EXT
4823 /* IPv4/IPv6 Last DNS config method */
4824 int last_dns_ipv4 = service->dns_config_method_ipv4;
4825 int last_dns_ipv6 = service->dns_config_method_ipv6;
4826 DBG("Last DNS Config Method IPv4: %d IPv6: %d", last_dns_ipv4, last_dns_ipv6);
4829 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
4831 dbus_message_iter_get_basic(&entry, &val);
4832 dbus_message_iter_next(&entry);
4834 /* First unpack the DNS Config Method */
4835 DBG("DNS Config Method: %s", val);
4836 if((g_strcmp0(val, "ipv4.manual") == 0)) {
4837 service->dns_config_method_ipv4 =
4838 CONNMAN_DNSCONFIG_METHOD_MANUAL;
4840 if(last_dns_ipv4 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
4841 if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
4842 ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
4844 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4847 } else if(g_strcmp0(val, "ipv4.dhcp") == 0) {
4848 service->dns_config_method_ipv4 =
4849 CONNMAN_DNSCONFIG_METHOD_DHCP;
4850 if(last_dns_ipv4 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
4851 ip_type = CONNMAN_IPCONFIG_TYPE_IPV4;
4854 } else if(g_strcmp0(val, "ipv6.manual") == 0) {
4855 service->dns_config_method_ipv6 =
4856 CONNMAN_DNSCONFIG_METHOD_MANUAL;
4857 if(last_dns_ipv6 != CONNMAN_DNSCONFIG_METHOD_MANUAL) {
4858 if(ip_type == CONNMAN_IPCONFIG_TYPE_UNKNOWN)
4859 ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
4861 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4864 } else if(g_strcmp0(val, "ipv6.dhcp") == 0) {
4865 service->dns_config_method_ipv6 =
4866 CONNMAN_DNSCONFIG_METHOD_DHCP;
4867 if(last_dns_ipv6 == CONNMAN_DNSCONFIG_METHOD_MANUAL)
4868 ip_type = CONNMAN_IPCONFIG_TYPE_IPV6;
4877 g_string_append_printf(str, " %s", val);
4879 g_string_append(str, val);
4882 #if defined TIZEN_EXT
4883 if (service->dns_config_method_ipv4 == CONNMAN_DNSCONFIG_METHOD_DHCP &&
4884 service->dns_config_method_ipv6 == CONNMAN_DNSCONFIG_METHOD_DHCP) {
4885 DBG("Both IPv4 and IPv6 DNS Method DHCP");
4886 ip_type = CONNMAN_IPCONFIG_TYPE_ALL;
4888 if (gw && strlen(gw))
4889 __connman_service_nameserver_del_routes(service,
4892 DBG("%s ip_type: %d nameserver remove all", name, ip_type);
4893 nameserver_remove_all(service, ip_type);
4895 nameserver_remove_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
4897 g_strfreev(service->nameservers_config);
4900 char **nameservers, **iter;
4902 nameservers = g_strsplit_set(str->str, " ", 0);
4904 for (iter = nameservers; *iter; iter++)
4905 if (connman_inet_check_ipaddress(*iter) <= 0)
4908 nameservers = remove_empty_strings(nameservers);
4909 service->nameservers_config = nameservers;
4911 service->nameservers_config = NULL;
4914 g_string_free(str, TRUE);
4916 if (gw && strlen(gw))
4917 __connman_service_nameserver_add_routes(service, gw);
4919 #if defined TIZEN_EXT
4920 DBG("%s ip_type: %d nameserver add all", name, ip_type);
4921 nameserver_add_all(service, ip_type);
4923 nameserver_add_all(service, CONNMAN_IPCONFIG_TYPE_ALL);
4925 dns_configuration_changed(service);
4927 if (__connman_service_is_connected_state(service,
4928 CONNMAN_IPCONFIG_TYPE_IPV4))
4929 __connman_service_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
4931 if (__connman_service_is_connected_state(service,
4932 CONNMAN_IPCONFIG_TYPE_IPV6))
4933 __connman_service_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV6);
4935 service_save(service);
4936 } else if (g_str_equal(name, "Timeservers.Configuration")) {
4937 DBusMessageIter entry;
4940 if (service->immutable)
4941 return __connman_error_not_supported(msg);
4943 if (type != DBUS_TYPE_ARRAY)
4944 return __connman_error_invalid_arguments(msg);
4946 str = g_string_new(NULL);
4948 return __connman_error_invalid_arguments(msg);
4950 dbus_message_iter_recurse(&value, &entry);
4952 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
4954 dbus_message_iter_get_basic(&entry, &val);
4955 dbus_message_iter_next(&entry);
4961 g_string_append_printf(str, " %s", val);
4963 g_string_append(str, val);
4966 g_strfreev(service->timeservers_config);
4967 service->timeservers_config = NULL;
4970 char **timeservers = g_strsplit_set(str->str, " ", 0);
4971 timeservers = remove_empty_strings(timeservers);
4972 service->timeservers_config = timeservers;
4975 g_string_free(str, TRUE);
4977 service_save(service);
4978 timeservers_configuration_changed(service);
4980 if (service == connman_service_get_default())
4981 __connman_timeserver_sync(service);
4983 } else if (g_str_equal(name, "Domains.Configuration")) {
4984 DBusMessageIter entry;
4987 if (service->immutable)
4988 return __connman_error_not_supported(msg);
4990 if (type != DBUS_TYPE_ARRAY)
4991 return __connman_error_invalid_arguments(msg);
4993 str = g_string_new(NULL);
4995 return __connman_error_invalid_arguments(msg);
4997 dbus_message_iter_recurse(&value, &entry);
4999 while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
5001 dbus_message_iter_get_basic(&entry, &val);
5002 dbus_message_iter_next(&entry);
5008 g_string_append_printf(str, " %s", val);
5010 g_string_append(str, val);
5013 searchdomain_remove_all(service);
5014 g_strfreev(service->domains);
5017 char **domains = g_strsplit_set(str->str, " ", 0);
5018 domains = remove_empty_strings(domains);
5019 service->domains = domains;
5021 service->domains = NULL;
5023 g_string_free(str, TRUE);
5025 searchdomain_add_all(service);
5026 domain_configuration_changed(service);
5027 domain_changed(service);
5029 service_save(service);
5030 } else if (g_str_equal(name, "Proxy.Configuration")) {
5033 if (service->immutable)
5034 return __connman_error_not_supported(msg);
5036 if (type != DBUS_TYPE_ARRAY)
5037 return __connman_error_invalid_arguments(msg);
5039 err = update_proxy_configuration(service, &value);
5042 return __connman_error_failed(msg, -err);
5044 proxy_configuration_changed(service);
5046 __connman_notifier_proxy_changed(service);
5048 service_save(service);
5049 } else if (g_str_equal(name, "mDNS.Configuration")) {
5052 if (service->immutable)
5053 return __connman_error_not_supported(msg);
5055 if (type != DBUS_TYPE_BOOLEAN)
5056 return __connman_error_invalid_arguments(msg);
5058 dbus_message_iter_get_basic(&value, &val);
5059 service->mdns_config = val;
5061 mdns_configuration_changed(service);
5063 set_mdns(service, service->mdns_config);
5065 service_save(service);
5066 } else if (g_str_equal(name, "IPv4.Configuration") ||
5067 g_str_equal(name, "IPv6.Configuration")) {
5069 enum connman_service_state state =
5070 CONNMAN_SERVICE_STATE_UNKNOWN;
5071 enum connman_ipconfig_type type =
5072 CONNMAN_IPCONFIG_TYPE_UNKNOWN;
5075 if (service->type == CONNMAN_SERVICE_TYPE_VPN ||
5077 return __connman_error_not_supported(msg);
5081 if (!service->ipconfig_ipv4 &&
5082 !service->ipconfig_ipv6)
5083 return __connman_error_invalid_property(msg);
5085 if (g_str_equal(name, "IPv4.Configuration"))
5086 type = CONNMAN_IPCONFIG_TYPE_IPV4;
5088 type = CONNMAN_IPCONFIG_TYPE_IPV6;
5090 err = __connman_service_reset_ipconfig(service, type, &value,
5094 if (is_connected(state) || is_connecting(state)) {
5095 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
5096 __connman_network_enable_ipconfig(service->network,
5097 service->ipconfig_ipv4);
5099 __connman_network_enable_ipconfig(service->network,
5100 service->ipconfig_ipv6);
5103 return __connman_error_failed(msg, -err);
5106 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
5107 ipv4_configuration_changed(service);
5109 ipv6_configuration_changed(service);
5111 if (is_connecting(service->state) ||
5112 is_connected(service->state)) {
5113 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
5114 __connman_network_enable_ipconfig(service->network,
5115 service->ipconfig_ipv4);
5117 __connman_network_enable_ipconfig(service->network,
5118 service->ipconfig_ipv6);
5121 service_save(service);
5122 #if defined TIZEN_EXT
5123 /* When AP is connected using WPS without SSID then its password needs
5124 * to be saved for autoconnection */
5125 } else if (g_str_equal(name, "Passphrase")) {
5128 if (type != DBUS_TYPE_STRING)
5129 return __connman_error_invalid_arguments(msg);
5131 dbus_message_iter_get_basic(&value, &passphrase);
5133 __connman_service_set_passphrase(service, passphrase);
5136 return __connman_error_invalid_property(msg);
5138 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5141 static void set_error(struct connman_service *service,
5142 enum connman_service_error error)
5146 if (service->error == error)
5149 service->error = error;
5154 #if !defined TIZEN_EXT
5155 if (!allow_property_changed(service))
5159 str = error2string(service->error);
5164 connman_dbus_property_changed_basic(service->path,
5165 CONNMAN_SERVICE_INTERFACE, "Error",
5166 DBUS_TYPE_STRING, &str);
5169 static void remove_timeout(struct connman_service *service)
5171 if (service->timeout > 0) {
5172 g_source_remove(service->timeout);
5173 service->timeout = 0;
5177 static void reply_pending(struct connman_service *service, int error)
5179 remove_timeout(service);
5181 if (service->pending) {
5182 connman_dbus_reply_pending(service->pending, error, NULL);
5183 service->pending = NULL;
5186 if (service->provider_pending) {
5187 connman_dbus_reply_pending(service->provider_pending,
5188 error, service->path);
5189 service->provider_pending = NULL;
5193 static void service_complete(struct connman_service *service)
5195 reply_pending(service, EIO);
5197 if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
5198 __connman_service_auto_connect(service->connect_reason);
5200 g_get_current_time(&service->modified);
5201 service_save(service);
5204 static DBusMessage *clear_property(DBusConnection *conn,
5205 DBusMessage *msg, void *user_data)
5207 struct connman_service *service = user_data;
5210 DBG("service %p", service);
5212 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name,
5215 if (g_str_equal(name, "Error")) {
5216 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
5218 __connman_service_clear_error(service);
5219 service_complete(service);
5221 return __connman_error_invalid_property(msg);
5223 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5226 static bool is_ipconfig_usable(struct connman_service *service)
5228 if (!__connman_ipconfig_is_usable(service->ipconfig_ipv4) &&
5229 !__connman_ipconfig_is_usable(service->ipconfig_ipv6))
5235 static bool is_ignore(struct connman_service *service)
5237 if (!service->autoconnect)
5240 if (service->roaming &&
5241 !connman_setting_get_bool("AutoConnectRoamingServices"))
5244 if (service->ignore)
5247 if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
5250 if (!is_ipconfig_usable(service))
5256 static void disconnect_on_last_session(enum connman_service_type type)
5260 for (list = service_list; list; list = list->next) {
5261 struct connman_service *service = list->data;
5263 if (service->type != type)
5266 if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_SESSION)
5269 __connman_service_disconnect(service);
5274 static int active_sessions[MAX_CONNMAN_SERVICE_TYPES] = {};
5275 static int always_connect[MAX_CONNMAN_SERVICE_TYPES] = {};
5276 static int active_count = 0;
5278 void __connman_service_set_active_session(bool enable, GSList *list)
5289 enum connman_service_type type = GPOINTER_TO_INT(list->data);
5292 case CONNMAN_SERVICE_TYPE_ETHERNET:
5293 case CONNMAN_SERVICE_TYPE_WIFI:
5294 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
5295 case CONNMAN_SERVICE_TYPE_CELLULAR:
5296 case CONNMAN_SERVICE_TYPE_GADGET:
5298 active_sessions[type]++;
5300 active_sessions[type]--;
5303 case CONNMAN_SERVICE_TYPE_UNKNOWN:
5304 case CONNMAN_SERVICE_TYPE_SYSTEM:
5305 case CONNMAN_SERVICE_TYPE_GPS:
5306 case CONNMAN_SERVICE_TYPE_VPN:
5307 case CONNMAN_SERVICE_TYPE_P2P:
5308 #if defined TIZEN_EXT_WIFI_MESH
5309 case CONNMAN_SERVICE_TYPE_MESH:
5314 if (active_sessions[type] == 0)
5315 disconnect_on_last_session(type);
5317 list = g_slist_next(list);
5320 DBG("eth %d wifi %d bt %d cellular %d gadget %d sessions %d",
5321 active_sessions[CONNMAN_SERVICE_TYPE_ETHERNET],
5322 active_sessions[CONNMAN_SERVICE_TYPE_WIFI],
5323 active_sessions[CONNMAN_SERVICE_TYPE_BLUETOOTH],
5324 active_sessions[CONNMAN_SERVICE_TYPE_CELLULAR],
5325 active_sessions[CONNMAN_SERVICE_TYPE_GADGET],
5329 struct preferred_tech_data {
5330 GList *preferred_list;
5331 enum connman_service_type type;
5334 static void preferred_tech_add_by_type(gpointer data, gpointer user_data)
5336 struct connman_service *service = data;
5337 struct preferred_tech_data *tech_data = user_data;
5339 if (service->type == tech_data->type) {
5340 tech_data->preferred_list =
5341 g_list_append(tech_data->preferred_list, service);
5343 DBG("type %d service %p %s", tech_data->type, service,
5348 static GList *preferred_tech_list_get(void)
5350 unsigned int *tech_array;
5351 struct preferred_tech_data tech_data = { 0, };
5354 tech_array = connman_setting_get_uint_list("PreferredTechnologies");
5358 if (connman_setting_get_bool("SingleConnectedTechnology")) {
5360 for (list = service_list; list; list = list->next) {
5361 struct connman_service *service = list->data;
5363 if (!is_connected(service->state))
5366 if (service->connect_reason ==
5367 CONNMAN_SERVICE_CONNECT_REASON_USER) {
5368 DBG("service %p name %s is user connected",
5369 service, service->name);
5370 #if defined TIZEN_EXT
5371 /* We can connect to a favorite service like
5372 * wifi even we have a userconnect for cellular
5373 * because we have refount for cellular service
5375 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
5378 if (service->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
5386 for (i = 0; tech_array[i] != 0; i += 1) {
5387 tech_data.type = tech_array[i];
5388 g_list_foreach(service_list, preferred_tech_add_by_type,
5392 return tech_data.preferred_list;
5395 static void set_always_connecting_technologies()
5397 unsigned int *always_connected_techs =
5398 connman_setting_get_uint_list("AlwaysConnectedTechnologies");
5400 for (i = 0; always_connected_techs && always_connected_techs[i]; i++)
5401 always_connect[always_connected_techs[i]] = 1;
5404 static bool autoconnect_no_session_active(struct connman_service *service)
5407 * Test active_count to see if there are no sessions set up and
5408 * stop autoconnecting, but continue connecting if the service
5409 * belongs to a technology which should always autoconnect.
5411 if (!active_count && !always_connect[service->type])
5417 static bool autoconnect_already_connecting(struct connman_service *service,
5418 bool autoconnecting)
5421 * If another service is already connecting and this service type has
5422 * not been marked as always connecting, stop the connecting procedure.
5424 if (autoconnecting &&
5425 !active_sessions[service->type] &&
5426 !always_connect[service->type])
5432 static bool auto_connect_service(GList *services,
5433 enum connman_service_connect_reason reason,
5436 struct connman_service *service = NULL;
5437 bool ignore[MAX_CONNMAN_SERVICE_TYPES] = { };
5438 bool autoconnecting = false;
5441 DBG("preferred %d sessions %d reason %s", preferred, active_count,
5442 reason2string(reason));
5444 ignore[CONNMAN_SERVICE_TYPE_VPN] = true;
5446 #if defined TIZEN_EXT_WIFI_MESH
5447 /* Don't auto connect wifi if mesh interface is created */
5448 if (connman_mesh_is_interface_created())
5449 ignore[CONNMAN_SERVICE_TYPE_WIFI] = true;
5452 for (list = services; list; list = list->next) {
5453 service = list->data;
5455 if (ignore[service->type]) {
5456 DBG("service %p type %s ignore", service,
5457 __connman_service_type2string(service->type));
5461 #if defined TIZEN_EXT
5462 DBG("service %p %s %s %s, favorite(%d), ignore(%d), hidden(%d, %d)",
5463 service, service->name,
5464 state2string(service->state),
5465 __connman_service_type2string(service->type),
5466 service->favorite, is_ignore(service),
5467 service->hidden, service->hidden_service);
5469 /* Tizen takes Wi-Fi as the highest priority into consideration. */
5470 if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
5471 if (is_connecting(service->state) == TRUE || is_connected(service->state) == TRUE)
5475 if (service->pending ||
5476 is_connecting(service->state) ||
5477 is_connected(service->state)) {
5478 if (autoconnect_no_session_active(service))
5481 ignore[service->type] = true;
5482 autoconnecting = true;
5484 DBG("service %p type %s busy", service,
5485 __connman_service_type2string(service->type));
5490 if (!service->favorite) {
5494 #if defined TIZEN_EXT
5495 DBG("Service is not favorite, autoconnecting %d",
5498 return autoconnecting;
5501 #if defined TIZEN_EXT
5502 DBG("service %p identifier %s roaming %d ignore %d "
5503 "ipconfig_usable %d autoconnect %d state %d",
5505 service->identifier, service->roaming,
5506 service->ignore, is_ipconfig_usable(service),
5507 service->autoconnect, service->state);
5509 if (is_ignore(service) || service->state !=
5510 CONNMAN_SERVICE_STATE_IDLE)
5513 if (autoconnect_already_connecting(service, autoconnecting)) {
5514 DBG("service %p type %s has no users", service,
5515 __connman_service_type2string(service->type));
5519 DBG("service %p %s %s", service, service->name,
5520 (preferred) ? "preferred" : reason2string(reason));
5522 __connman_service_connect(service, reason);
5524 if (autoconnect_no_session_active(service))
5527 ignore[service->type] = true;
5530 return autoconnecting;
5533 static gboolean run_auto_connect(gpointer data)
5535 enum connman_service_connect_reason reason = GPOINTER_TO_UINT(data);
5536 bool autoconnecting = false;
5537 GList *preferred_tech;
5543 preferred_tech = preferred_tech_list_get();
5544 if (preferred_tech) {
5545 autoconnecting = auto_connect_service(preferred_tech, reason,
5547 g_list_free(preferred_tech);
5550 if (!autoconnecting || active_count)
5551 auto_connect_service(service_list, reason, false);
5556 #if defined TIZEN_EXT
5557 bool __connman_service_get_auto_connect_mode(void)
5559 return auto_connect_mode;
5562 void __connman_service_set_auto_connect_mode(bool enable)
5564 DBG("set auto_connect_mode = %d", enable);
5566 if (auto_connect_mode != enable)
5567 auto_connect_mode = enable;
5571 void __connman_service_auto_connect(enum connman_service_connect_reason reason)
5575 if (autoconnect_id != 0)
5578 #if defined TIZEN_EXT
5579 if (auto_connect_mode == FALSE) {
5580 DBG("Currently, not auto connection mode");
5585 if (!__connman_session_policy_autoconnect(reason))
5588 #if defined TIZEN_EXT
5589 /* Adding Timeout of 500ms before trying to auto connect.
5590 * This is done because of below scenario
5591 * 1. Device is connected to AP1
5592 * 2. WPS Connection request is initiated for AP2
5593 * 3. Immediately WPS Connection is Cancelled
5594 * When WPS Connection Connection is initiated for AP2 then
5595 * sometimes there is a scenario where connman gets in ASSOCIATED
5596 * state with AP1 due to autoconnect and subsequently the connection
5597 * initiated by AP1 fails and connman service for AP1 comes in
5598 * FAILURE state due to this when connection with AP2 is cancelled
5599 * then autoconnect with AP1 doesn't works because its autoconnection
5600 * is ignored as its last state was FAILURE rather than IDLE */
5601 autoconnect_id = g_timeout_add(500, run_auto_connect,
5603 autoconnect_id = g_idle_add(run_auto_connect,
5605 GUINT_TO_POINTER(reason));
5608 static gboolean run_vpn_auto_connect(gpointer data) {
5610 bool need_split = false;
5612 vpn_autoconnect_id = 0;
5614 for (list = service_list; list; list = list->next) {
5615 struct connman_service *service = list->data;
5618 if (service->type != CONNMAN_SERVICE_TYPE_VPN)
5621 if (is_connected(service->state) ||
5622 is_connecting(service->state)) {
5623 if (!service->do_split_routing)
5628 if (is_ignore(service) || !service->favorite)
5631 if (need_split && !service->do_split_routing) {
5632 DBG("service %p no split routing", service);
5636 DBG("service %p %s %s", service, service->name,
5637 service->do_split_routing ?
5638 "split routing" : "");
5640 res = __connman_service_connect(service,
5641 CONNMAN_SERVICE_CONNECT_REASON_AUTO);
5642 if (res < 0 && res != -EINPROGRESS)
5645 if (!service->do_split_routing)
5652 static void vpn_auto_connect(void)
5654 if (vpn_autoconnect_id)
5657 vpn_autoconnect_id =
5658 g_idle_add(run_vpn_auto_connect, NULL);
5662 __connman_service_is_provider_pending(struct connman_service *service)
5667 if (service->provider_pending)
5673 void __connman_service_set_provider_pending(struct connman_service *service,
5676 if (service->provider_pending) {
5677 DBG("service %p provider pending msg %p already exists",
5678 service, service->provider_pending);
5682 service->provider_pending = msg;
5685 static void check_pending_msg(struct connman_service *service)
5687 if (!service->pending)
5690 DBG("service %p pending msg %p already exists", service,
5692 dbus_message_unref(service->pending);
5695 void __connman_service_set_hidden_data(struct connman_service *service,
5698 DBusMessage *pending = user_data;
5700 DBG("service %p pending %p", service, pending);
5705 check_pending_msg(service);
5707 service->pending = pending;
5710 void __connman_service_return_error(struct connman_service *service,
5711 int error, gpointer user_data)
5713 DBG("service %p error %d user_data %p", service, error, user_data);
5715 __connman_service_set_hidden_data(service, user_data);
5717 reply_pending(service, error);
5720 static gboolean connect_timeout(gpointer user_data)
5722 struct connman_service *service = user_data;
5723 bool autoconnect = false;
5725 DBG("service %p", service);
5727 service->timeout = 0;
5729 if (service->network)
5730 __connman_network_disconnect(service->network);
5731 else if (service->provider)
5732 connman_provider_disconnect(service->provider);
5734 __connman_stats_service_unregister(service);
5736 if (service->pending) {
5739 reply = __connman_error_operation_timeout(service->pending);
5741 g_dbus_send_message(connection, reply);
5743 dbus_message_unref(service->pending);
5744 service->pending = NULL;
5748 __connman_service_ipconfig_indicate_state(service,
5749 CONNMAN_SERVICE_STATE_FAILURE,
5750 CONNMAN_IPCONFIG_TYPE_IPV4);
5751 __connman_service_ipconfig_indicate_state(service,
5752 CONNMAN_SERVICE_STATE_FAILURE,
5753 CONNMAN_IPCONFIG_TYPE_IPV6);
5756 service->connect_reason !=
5757 CONNMAN_SERVICE_CONNECT_REASON_USER)
5758 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
5763 static DBusMessage *connect_service(DBusConnection *conn,
5764 DBusMessage *msg, void *user_data)
5766 struct connman_service *service = user_data;
5767 #if defined TIZEN_EXT
5774 DBG("service %p", service);
5776 #if defined TIZEN_EXT
5778 * Description: TIZEN implements system global connection management.
5780 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
5781 connman_service_user_pdn_connection_ref(service);
5783 /*Reset the Disconnect Reason while issue connect request*/
5784 service->disconnect_reason = 0;
5786 /*Reset the association status code while issue connect request*/
5787 service->assoc_status_code = 0;
5789 /* Reset the disconnection_requested while issue connect request*/
5790 connman_service_set_disconnection_requested(service, false);
5793 if (service->pending)
5794 return __connman_error_in_progress(msg);
5796 #if !defined TIZEN_EXT
5797 index = __connman_service_get_index(service);
5799 for (list = service_list; list; list = list->next) {
5800 struct connman_service *temp = list->data;
5802 #if defined TIZEN_EXT
5803 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
5806 if (!is_connecting(temp->state) && !is_connected(temp->state))
5809 if (service == temp)
5812 if (service->type != temp->type)
5815 if (__connman_service_get_index(temp) == index &&
5816 __connman_service_disconnect(temp) == -EINPROGRESS)
5820 if (err == -EINPROGRESS)
5821 return __connman_error_operation_timeout(msg);
5824 service->ignore = false;
5826 service->pending = dbus_message_ref(msg);
5828 err = __connman_service_connect(service,
5829 CONNMAN_SERVICE_CONNECT_REASON_USER);
5831 if (err != -EINPROGRESS)
5832 reply_pending(service, -err);
5837 static DBusMessage *disconnect_service(DBusConnection *conn,
5838 DBusMessage *msg, void *user_data)
5840 struct connman_service *service = user_data;
5843 DBG("service %p", service);
5845 #if defined TIZEN_EXT
5847 * Description: TIZEN implements system global connection management.
5849 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
5850 if (connman_service_user_pdn_connection_unref_and_test(service) != TRUE)
5851 return __connman_error_failed(msg, EISCONN);
5853 if (is_connected(service->state) == TRUE &&
5854 service == connman_service_get_default_connection())
5855 return __connman_error_failed(msg, EISCONN);
5859 service->ignore = true;
5861 err = __connman_service_disconnect(service);
5862 if (err < 0 && err != -EINPROGRESS)
5863 return __connman_error_failed(msg, -err);
5865 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
5868 #if defined TIZEN_EXT
5869 static void __connman_service_cleanup_network_8021x(struct connman_service *service)
5871 if (service == NULL)
5874 DBG("service %p ", service);
5876 connman_network_set_string(service->network, "WiFi.EAP", NULL);
5877 connman_network_set_string(service->network, "WiFi.Identity", NULL);
5878 connman_network_set_string(service->network, "WiFi.CACertFile", NULL);
5879 connman_network_set_string(service->network, "WiFi.ClientCertFile", NULL);
5880 connman_network_set_string(service->network, "WiFi.PrivateKeyFile", NULL);
5881 connman_network_set_string(service->network, "WiFi.PrivateKeyPassphrase", NULL);
5882 connman_network_set_string(service->network, "WiFi.Phase2", NULL);
5883 connman_network_set_string(service->network, "WiFi.AnonymousIdentity", NULL);
5885 static void __connman_service_cleanup_network_dpp(struct connman_service *service)
5887 if (service == NULL)
5890 DBG("service %p ", service);
5892 connman_network_set_string(service->network, "WiFi.Connector", NULL);
5893 connman_network_set_string(service->network, "WiFi.CSignKey", NULL);
5894 connman_network_set_string(service->network, "WiFi.NetAccessKey", NULL);
5898 bool __connman_service_remove(struct connman_service *service)
5900 if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET ||
5901 service->type == CONNMAN_SERVICE_TYPE_GADGET)
5904 if (service->immutable || service->hidden ||
5905 __connman_provider_is_immutable(service->provider))
5908 #if !defined TIZEN_EXT
5909 if (!service->favorite && !is_idle(service->state))
5913 __connman_service_disconnect(service);
5915 g_free(service->passphrase);
5916 service->passphrase = NULL;
5918 g_free(service->identity);
5919 service->identity = NULL;
5921 g_free(service->anonymous_identity);
5922 service->anonymous_identity = NULL;
5924 g_free(service->subject_match);
5925 service->subject_match = NULL;
5927 g_free(service->altsubject_match);
5928 service->altsubject_match = NULL;
5930 g_free(service->domain_suffix_match);
5931 service->domain_suffix_match = NULL;
5933 g_free(service->domain_match);
5934 service->domain_match = NULL;
5936 g_free(service->agent_identity);
5937 service->agent_identity = NULL;
5939 g_free(service->eap);
5940 service->eap = NULL;
5942 #if defined TIZEN_EXT
5943 g_free(service->ca_cert_file);
5944 service->ca_cert_file = NULL;
5946 g_free(service->client_cert_file);
5947 service->client_cert_file = NULL;
5949 g_free(service->private_key_file);
5950 service->private_key_file = NULL;
5952 g_free(service->private_key_passphrase);
5953 service->private_key_passphrase = NULL;
5955 g_free(service->phase2);
5956 service->phase2 = NULL;
5958 __connman_service_cleanup_network_8021x(service);
5960 __connman_ipconfig_set_method(service->ipconfig_ipv4, CONNMAN_IPCONFIG_METHOD_DHCP);
5961 __connman_ipconfig_set_method(service->ipconfig_ipv6, CONNMAN_IPCONFIG_METHOD_AUTO);
5962 connman_service_set_proxy(service, NULL, false);
5964 __connman_service_nameserver_clear(service);
5966 g_strfreev(service->nameservers_config);
5967 service->nameservers_config = NULL;
5969 g_free(service->connector);
5970 service->connector = NULL;
5972 g_free(service->c_sign_key);
5973 service->c_sign_key = NULL;
5975 g_free(service->net_access_key);
5976 service->net_access_key = NULL;
5978 __connman_service_cleanup_network_dpp(service);
5981 service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
5983 __connman_service_set_favorite(service, false);
5985 __connman_ipconfig_ipv6_reset_privacy(service->ipconfig_ipv6);
5987 #if defined TIZEN_EXT
5988 /* Reset IP Method and DNS Method to DHCP */
5989 __connman_ipconfig_set_method(service->ipconfig_ipv4,
5990 CONNMAN_IPCONFIG_METHOD_DHCP);
5991 service->dns_config_method_ipv4 = CONNMAN_DNSCONFIG_METHOD_DHCP;
5992 g_strfreev(service->nameservers_config);
5993 service->nameservers_config = NULL;
5996 #if defined TIZEN_EXT
5997 __connman_storage_remove_service(service->identifier);
5999 service_save(service);
6005 static DBusMessage *remove_service(DBusConnection *conn,
6006 DBusMessage *msg, void *user_data)
6008 struct connman_service *service = user_data;
6010 DBG("service %p", service);
6012 if (!__connman_service_remove(service))
6013 return __connman_error_not_supported(msg);
6015 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
6018 static bool check_suitable_state(enum connman_service_state a,
6019 enum connman_service_state b)
6022 * Special check so that "ready" service can be moved before
6025 if ((a == CONNMAN_SERVICE_STATE_ONLINE &&
6026 b == CONNMAN_SERVICE_STATE_READY) ||
6027 (b == CONNMAN_SERVICE_STATE_ONLINE &&
6028 a == CONNMAN_SERVICE_STATE_READY))
6034 static void downgrade_state(struct connman_service *service)
6039 DBG("service %p state4 %d state6 %d", service, service->state_ipv4,
6040 service->state_ipv6);
6042 if (service->state_ipv4 == CONNMAN_SERVICE_STATE_ONLINE)
6043 __connman_service_ipconfig_indicate_state(service,
6044 CONNMAN_SERVICE_STATE_READY,
6045 CONNMAN_IPCONFIG_TYPE_IPV4);
6047 if (service->state_ipv6 == CONNMAN_SERVICE_STATE_ONLINE)
6048 __connman_service_ipconfig_indicate_state(service,
6049 CONNMAN_SERVICE_STATE_READY,
6050 CONNMAN_IPCONFIG_TYPE_IPV6);
6053 static void apply_relevant_default_downgrade(struct connman_service *service)
6055 struct connman_service *def_service;
6057 def_service = connman_service_get_default();
6061 if (def_service == service &&
6062 def_service->state == CONNMAN_SERVICE_STATE_ONLINE) {
6063 def_service->state = CONNMAN_SERVICE_STATE_READY;
6064 __connman_notifier_leave_online(def_service->type);
6065 state_changed(def_service);
6069 static void switch_default_service(struct connman_service *default_service,
6070 struct connman_service *downgrade_service)
6072 struct connman_service *service;
6075 apply_relevant_default_downgrade(default_service);
6076 src = g_list_find(service_list, downgrade_service);
6077 dst = g_list_find(service_list, default_service);
6080 if (src == dst || src->next == dst)
6083 service = src->data;
6084 service_list = g_list_delete_link(service_list, src);
6085 service_list = g_list_insert_before(service_list, dst, service);
6087 downgrade_state(downgrade_service);
6090 static struct _services_notify {
6097 static void service_append_added_foreach(gpointer data, gpointer user_data)
6099 struct connman_service *service = data;
6100 DBusMessageIter *iter = user_data;
6102 if (!service || !service->path) {
6103 DBG("service %p or path is NULL", service);
6107 if (g_hash_table_lookup(services_notify->add, service->path)) {
6108 DBG("new %s", service->path);
6110 append_struct(service, iter);
6111 g_hash_table_remove(services_notify->add, service->path);
6113 DBG("changed %s", service->path);
6115 append_struct_service(iter, NULL, service);
6119 static void service_append_ordered(DBusMessageIter *iter, void *user_data)
6121 g_list_foreach(service_list, service_append_added_foreach, iter);
6124 static void append_removed(gpointer key, gpointer value, gpointer user_data)
6126 char *objpath = key;
6127 DBusMessageIter *iter = user_data;
6129 DBG("removed %s", objpath);
6130 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &objpath);
6133 static void service_append_removed(DBusMessageIter *iter, void *user_data)
6135 g_hash_table_foreach(services_notify->remove, append_removed, iter);
6138 static gboolean service_send_changed(gpointer data)
6140 DBusMessage *signal;
6144 services_notify->id = 0;
6146 signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
6147 CONNMAN_MANAGER_INTERFACE, "ServicesChanged");
6151 __connman_dbus_append_objpath_dict_array(signal,
6152 service_append_ordered, NULL);
6153 __connman_dbus_append_objpath_array(signal,
6154 service_append_removed, NULL);
6156 dbus_connection_send(connection, signal, NULL);
6157 dbus_message_unref(signal);
6159 g_hash_table_remove_all(services_notify->remove);
6160 g_hash_table_remove_all(services_notify->add);
6165 static void service_schedule_changed(void)
6167 if (services_notify->id != 0)
6170 services_notify->id = g_timeout_add(100, service_send_changed, NULL);
6173 static DBusMessage *move_service(DBusConnection *conn,
6174 DBusMessage *msg, void *user_data,
6177 struct connman_service *service = user_data;
6178 struct connman_service *target;
6180 enum connman_ipconfig_method target4, target6;
6181 enum connman_ipconfig_method service4, service6;
6183 DBG("service %p", service);
6185 dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
6188 if (!service->favorite)
6189 return __connman_error_not_supported(msg);
6191 target = find_service(path);
6192 if (!target || !target->favorite || target == service)
6193 return __connman_error_invalid_service(msg);
6195 if (target->type == CONNMAN_SERVICE_TYPE_VPN) {
6197 * We only allow VPN route splitting if there are
6198 * routes defined for a given VPN.
6200 if (!__connman_provider_check_routes(target->provider)) {
6201 connman_info("Cannot move service. "
6202 "No routes defined for provider %s",
6203 __connman_provider_get_ident(target->provider));
6204 return __connman_error_invalid_service(msg);
6207 set_split_routing(target, true);
6209 set_split_routing(target, false);
6211 set_split_routing(service, false);
6213 target4 = __connman_ipconfig_get_method(target->ipconfig_ipv4);
6214 target6 = __connman_ipconfig_get_method(target->ipconfig_ipv6);
6215 service4 = __connman_ipconfig_get_method(service->ipconfig_ipv4);
6216 service6 = __connman_ipconfig_get_method(service->ipconfig_ipv6);
6218 DBG("target %s method %d/%d state %d/%d split %d", target->identifier,
6219 target4, target6, target->state_ipv4, target->state_ipv6,
6220 target->do_split_routing);
6222 DBG("service %s method %d/%d state %d/%d", service->identifier,
6224 service->state_ipv4, service->state_ipv6);
6227 * If method is OFF, then we do not need to check the corresponding
6230 if (target4 == CONNMAN_IPCONFIG_METHOD_OFF) {
6231 if (service6 != CONNMAN_IPCONFIG_METHOD_OFF) {
6232 if (!check_suitable_state(target->state_ipv6,
6233 service->state_ipv6))
6234 return __connman_error_invalid_service(msg);
6238 if (target6 == CONNMAN_IPCONFIG_METHOD_OFF) {
6239 if (service4 != CONNMAN_IPCONFIG_METHOD_OFF) {
6240 if (!check_suitable_state(target->state_ipv4,
6241 service->state_ipv4))
6242 return __connman_error_invalid_service(msg);
6246 if (service4 == CONNMAN_IPCONFIG_METHOD_OFF) {
6247 if (target6 != CONNMAN_IPCONFIG_METHOD_OFF) {
6248 if (!check_suitable_state(target->state_ipv6,
6249 service->state_ipv6))
6250 return __connman_error_invalid_service(msg);
6254 if (service6 == CONNMAN_IPCONFIG_METHOD_OFF) {
6255 if (target4 != CONNMAN_IPCONFIG_METHOD_OFF) {
6256 if (!check_suitable_state(target->state_ipv4,
6257 service->state_ipv4))
6258 return __connman_error_invalid_service(msg);
6262 g_get_current_time(&service->modified);
6263 service_save(service);
6264 service_save(target);
6267 * If the service which goes down is the default service and is
6268 * online, we downgrade directly its state to ready so:
6269 * the service which goes up, needs to recompute its state which
6270 * is triggered via downgrading it - if relevant - to state ready.
6273 switch_default_service(target, service);
6275 switch_default_service(service, target);
6277 __connman_connection_update_gateway();
6279 service_schedule_changed();
6281 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
6284 static DBusMessage *move_before(DBusConnection *conn,
6285 DBusMessage *msg, void *user_data)
6287 return move_service(conn, msg, user_data, true);
6290 static DBusMessage *move_after(DBusConnection *conn,
6291 DBusMessage *msg, void *user_data)
6293 return move_service(conn, msg, user_data, false);
6296 static DBusMessage *reset_counters(DBusConnection *conn,
6297 DBusMessage *msg, void *user_data)
6299 struct connman_service *service = user_data;
6301 reset_stats(service);
6303 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
6306 #if defined TIZEN_MAINTAIN_ONLINE
6307 static DBusMessage *downgrade_service(DBusConnection *conn,
6308 DBusMessage *msg, void *user_data)
6310 struct connman_service *service = user_data;
6312 downgrade_state(service);
6313 __connman_connection_update_gateway();
6315 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
6319 static void service_schedule_added(struct connman_service *service)
6321 DBG("service %p", service);
6323 g_hash_table_remove(services_notify->remove, service->path);
6324 g_hash_table_replace(services_notify->add, service->path, service);
6326 service_schedule_changed();
6329 static void service_schedule_removed(struct connman_service *service)
6331 if (!service || !service->path) {
6332 DBG("service %p or path is NULL", service);
6336 DBG("service %p %s", service, service->path);
6338 g_hash_table_remove(services_notify->add, service->path);
6339 g_hash_table_replace(services_notify->remove, g_strdup(service->path),
6342 service_schedule_changed();
6345 static bool allow_property_changed(struct connman_service *service)
6347 #if defined TIZEN_EXT
6348 if (service->path == NULL)
6351 if (g_hash_table_lookup_extended(services_notify->add, service->path,
6358 static const GDBusMethodTable service_methods[] = {
6359 { GDBUS_DEPRECATED_METHOD("GetProperties",
6360 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
6362 { GDBUS_METHOD("SetProperty",
6363 GDBUS_ARGS({ "name", "s" }, { "value", "v" }),
6364 NULL, set_property) },
6365 { GDBUS_METHOD("ClearProperty",
6366 GDBUS_ARGS({ "name", "s" }), NULL,
6368 { GDBUS_ASYNC_METHOD("Connect", NULL, NULL,
6370 { GDBUS_METHOD("Disconnect", NULL, NULL,
6371 disconnect_service) },
6372 { GDBUS_METHOD("Remove", NULL, NULL, remove_service) },
6373 { GDBUS_METHOD("MoveBefore",
6374 GDBUS_ARGS({ "service", "o" }), NULL,
6376 { GDBUS_METHOD("MoveAfter",
6377 GDBUS_ARGS({ "service", "o" }), NULL,
6379 { GDBUS_METHOD("ResetCounters", NULL, NULL, reset_counters) },
6380 #if defined TIZEN_MAINTAIN_ONLINE
6381 { GDBUS_METHOD("Downgrade", NULL, NULL, downgrade_service) },
6386 static const GDBusSignalTable service_signals[] = {
6387 { GDBUS_SIGNAL("PropertyChanged",
6388 GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
6392 static void service_free(gpointer user_data)
6394 struct connman_service *service = user_data;
6395 char *path = service->path;
6397 DBG("service %p", service);
6399 reply_pending(service, ENOENT);
6401 if (service->nameservers_timeout) {
6402 g_source_remove(service->nameservers_timeout);
6403 dns_changed(service);
6406 __connman_notifier_service_remove(service);
6407 service_schedule_removed(service);
6409 __connman_wispr_stop(service);
6410 stats_stop(service);
6412 service->path = NULL;
6415 __connman_connection_update_gateway();
6417 g_dbus_unregister_interface(connection, path,
6418 CONNMAN_SERVICE_INTERFACE);
6422 g_hash_table_destroy(service->counter_table);
6424 if (service->network) {
6425 __connman_network_disconnect(service->network);
6426 connman_network_unref(service->network);
6427 service->network = NULL;
6430 if (service->provider)
6431 connman_provider_unref(service->provider);
6433 if (service->ipconfig_ipv4) {
6434 __connman_ipconfig_set_ops(service->ipconfig_ipv4, NULL);
6435 __connman_ipconfig_set_data(service->ipconfig_ipv4, NULL);
6436 __connman_ipconfig_unref(service->ipconfig_ipv4);
6437 service->ipconfig_ipv4 = NULL;
6440 if (service->ipconfig_ipv6) {
6441 __connman_ipconfig_set_ops(service->ipconfig_ipv6, NULL);
6442 __connman_ipconfig_set_data(service->ipconfig_ipv6, NULL);
6443 __connman_ipconfig_unref(service->ipconfig_ipv6);
6444 service->ipconfig_ipv6 = NULL;
6447 g_strfreev(service->timeservers);
6448 g_strfreev(service->timeservers_config);
6449 g_strfreev(service->nameservers);
6450 g_strfreev(service->nameservers_config);
6451 g_strfreev(service->nameservers_auto);
6452 g_strfreev(service->domains);
6453 g_strfreev(service->proxies);
6454 g_strfreev(service->excludes);
6456 g_free(service->hostname);
6457 g_free(service->domainname);
6458 g_free(service->pac);
6459 g_free(service->name);
6460 g_free(service->passphrase);
6461 g_free(service->identifier);
6462 g_free(service->eap);
6463 g_free(service->identity);
6464 g_free(service->anonymous_identity);
6465 g_free(service->agent_identity);
6466 g_free(service->ca_cert_file);
6467 g_free(service->subject_match);
6468 g_free(service->altsubject_match);
6469 g_free(service->domain_suffix_match);
6470 g_free(service->domain_match);
6471 g_free(service->client_cert_file);
6472 g_free(service->private_key_file);
6473 g_free(service->private_key_passphrase);
6474 g_free(service->phase2);
6475 g_free(service->config_file);
6476 g_free(service->config_entry);
6477 #if defined TIZEN_EXT
6478 g_free(service->connector);
6479 g_free(service->c_sign_key);
6480 g_free(service->net_access_key);
6483 if (service->stats.timer)
6484 g_timer_destroy(service->stats.timer);
6485 if (service->stats_roaming.timer)
6486 g_timer_destroy(service->stats_roaming.timer);
6488 if (current_default == service)
6489 current_default = NULL;
6494 static void stats_init(struct connman_service *service)
6497 service->stats.valid = false;
6498 service->stats.enabled = false;
6499 service->stats.timer = g_timer_new();
6502 service->stats_roaming.valid = false;
6503 service->stats_roaming.enabled = false;
6504 service->stats_roaming.timer = g_timer_new();
6507 static void service_initialize(struct connman_service *service)
6509 DBG("service %p", service);
6511 service->refcount = 1;
6513 service->error = CONNMAN_SERVICE_ERROR_UNKNOWN;
6515 service->type = CONNMAN_SERVICE_TYPE_UNKNOWN;
6516 service->security = CONNMAN_SERVICE_SECURITY_UNKNOWN;
6518 service->state = CONNMAN_SERVICE_STATE_UNKNOWN;
6519 service->state_ipv4 = CONNMAN_SERVICE_STATE_UNKNOWN;
6520 service->state_ipv6 = CONNMAN_SERVICE_STATE_UNKNOWN;
6522 service->favorite = false;
6523 service->immutable = false;
6524 service->hidden = false;
6526 service->ignore = false;
6528 service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
6532 stats_init(service);
6534 service->provider = NULL;
6536 service->wps = false;
6537 service->wps_advertizing = false;
6538 #if defined TIZEN_EXT
6539 service->disconnection_requested = false;
6540 service->storage_reload = false;
6542 * Description: TIZEN implements system global connection management.
6544 service->user_pdn_connection_refcount = 0;
6545 __sync_synchronize();
6550 * connman_service_create:
6552 * Allocate a new service.
6554 * Returns: a newly-allocated #connman_service structure
6556 struct connman_service *connman_service_create(void)
6559 struct connman_stats_counter *counters;
6560 const char *counter;
6562 struct connman_service *service;
6564 service = g_try_new0(struct connman_service, 1);
6568 DBG("service %p", service);
6570 service->counter_table = g_hash_table_new_full(g_str_hash,
6571 g_str_equal, NULL, g_free);
6573 for (list = counter_list; list; list = list->next) {
6574 counter = list->data;
6576 counters = g_try_new0(struct connman_stats_counter, 1);
6578 g_hash_table_destroy(service->counter_table);
6583 counters->append_all = true;
6585 g_hash_table_replace(service->counter_table, (gpointer)counter,
6589 service_initialize(service);
6595 * connman_service_ref:
6596 * @service: service structure
6598 * Increase reference counter of service
6600 struct connman_service *
6601 connman_service_ref_debug(struct connman_service *service,
6602 const char *file, int line, const char *caller)
6604 DBG("%p ref %d by %s:%d:%s()", service, service->refcount + 1,
6605 file, line, caller);
6607 __sync_fetch_and_add(&service->refcount, 1);
6613 * connman_service_unref:
6614 * @service: service structure
6616 * Decrease reference counter of service and release service if no
6619 void connman_service_unref_debug(struct connman_service *service,
6620 const char *file, int line, const char *caller)
6622 DBG("%p ref %d by %s:%d:%s()", service, service->refcount - 1,
6623 file, line, caller);
6625 if (__sync_fetch_and_sub(&service->refcount, 1) != 1)
6628 service_list = g_list_remove(service_list, service);
6630 __connman_service_disconnect(service);
6632 g_hash_table_remove(service_hash, service->identifier);
6635 static gint service_compare(gconstpointer a, gconstpointer b)
6637 struct connman_service *service_a = (void *) a;
6638 struct connman_service *service_b = (void *) b;
6639 enum connman_service_state state_a, state_b;
6640 bool a_connected, b_connected;
6643 state_a = service_a->state;
6644 state_b = service_b->state;
6645 a_connected = is_connected(state_a);
6646 b_connected = is_connected(state_b);
6648 if (a_connected && b_connected) {
6649 if (service_a->order > service_b->order)
6652 if (service_a->order < service_b->order)
6656 if (state_a != state_b) {
6657 if (a_connected && b_connected) {
6658 /* We prefer online over ready state */
6659 if (state_a == CONNMAN_SERVICE_STATE_ONLINE)
6662 if (state_b == CONNMAN_SERVICE_STATE_ONLINE)
6671 if (is_connecting(state_a))
6673 if (is_connecting(state_b))
6677 if (service_a->favorite && !service_b->favorite)
6680 if (!service_a->favorite && service_b->favorite)
6683 if (service_a->type != service_b->type) {
6684 unsigned int *tech_array;
6687 tech_array = connman_setting_get_uint_list(
6688 "PreferredTechnologies");
6690 for (i = 0; tech_array[i]; i++) {
6691 if (tech_array[i] == service_a->type)
6694 if (tech_array[i] == service_b->type)
6699 if (service_a->type == CONNMAN_SERVICE_TYPE_ETHERNET)
6701 if (service_b->type == CONNMAN_SERVICE_TYPE_ETHERNET)
6704 if (service_a->type == CONNMAN_SERVICE_TYPE_WIFI)
6706 if (service_b->type == CONNMAN_SERVICE_TYPE_WIFI)
6709 if (service_a->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6711 if (service_b->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6714 if (service_a->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
6716 if (service_b->type == CONNMAN_SERVICE_TYPE_BLUETOOTH)
6719 if (service_a->type == CONNMAN_SERVICE_TYPE_VPN)
6721 if (service_b->type == CONNMAN_SERVICE_TYPE_VPN)
6724 if (service_a->type == CONNMAN_SERVICE_TYPE_GADGET)
6726 if (service_b->type == CONNMAN_SERVICE_TYPE_GADGET)
6730 strength = (gint) service_b->strength - (gint) service_a->strength;
6734 return g_strcmp0(service_a->name, service_b->name);
6737 static void service_list_sort(void)
6739 if (service_list && service_list->next) {
6740 service_list = g_list_sort(service_list, service_compare);
6741 service_schedule_changed();
6745 int __connman_service_compare(const struct connman_service *a,
6746 const struct connman_service *b)
6748 return service_compare(a, b);
6752 * connman_service_get_type:
6753 * @service: service structure
6755 * Get the type of service
6757 enum connman_service_type connman_service_get_type(struct connman_service *service)
6760 return CONNMAN_SERVICE_TYPE_UNKNOWN;
6762 return service->type;
6766 * connman_service_get_interface:
6767 * @service: service structure
6769 * Get network interface of service
6771 char *connman_service_get_interface(struct connman_service *service)
6778 index = __connman_service_get_index(service);
6780 return connman_inet_ifname(index);
6784 * connman_service_get_network:
6785 * @service: service structure
6787 * Get the service network
6789 struct connman_network *
6790 __connman_service_get_network(struct connman_service *service)
6795 return service->network;
6798 struct connman_ipconfig *
6799 __connman_service_get_ip4config(struct connman_service *service)
6804 return service->ipconfig_ipv4;
6807 struct connman_ipconfig *
6808 __connman_service_get_ip6config(struct connman_service *service)
6813 return service->ipconfig_ipv6;
6816 struct connman_ipconfig *
6817 __connman_service_get_ipconfig(struct connman_service *service, int family)
6819 if (family == AF_INET)
6820 return __connman_service_get_ip4config(service);
6821 else if (family == AF_INET6)
6822 return __connman_service_get_ip6config(service);
6828 bool __connman_service_is_connected_state(struct connman_service *service,
6829 enum connman_ipconfig_type type)
6835 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
6837 case CONNMAN_IPCONFIG_TYPE_IPV4:
6838 return is_connected(service->state_ipv4);
6839 case CONNMAN_IPCONFIG_TYPE_IPV6:
6840 return is_connected(service->state_ipv6);
6841 case CONNMAN_IPCONFIG_TYPE_ALL:
6842 return is_connected(service->state_ipv4) &&
6843 is_connected(service->state_ipv6);
6848 enum connman_service_security __connman_service_get_security(
6849 struct connman_service *service)
6852 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
6854 return service->security;
6857 const char *__connman_service_get_phase2(struct connman_service *service)
6862 return service->phase2;
6865 bool __connman_service_wps_enabled(struct connman_service *service)
6870 return service->wps;
6873 void __connman_service_mark_dirty(void)
6875 services_dirty = true;
6878 #if defined TIZEN_EXT
6880 * Returns profile count if there is any connected profiles
6881 * that use same interface
6883 int __connman_service_get_connected_count_of_iface(
6884 struct connman_service *service)
6893 index1 = __connman_service_get_index(service);
6898 for (list = service_list; list; list = list->next) {
6899 struct connman_service *service2 = list->data;
6901 if (service == service2)
6904 index2 = __connman_service_get_index(service2);
6906 if (is_connected(service2->state) && index2 > 0 && index1 == index2)
6912 DBG("Interface index %d, count %d", index1, count);
6917 void __connman_service_set_storage_reload(struct connman_service *service,
6918 bool storage_reload)
6920 if (service != NULL)
6921 service->storage_reload = storage_reload;
6926 * __connman_service_set_favorite_delayed:
6927 * @service: service structure
6928 * @favorite: favorite value
6929 * @delay_ordering: do not order service sequence
6931 * Change the favorite setting of service
6933 int __connman_service_set_favorite_delayed(struct connman_service *service,
6935 bool delay_ordering)
6937 #if defined TIZEN_EXT
6938 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
6941 if (service->hidden)
6944 if (service->favorite == favorite)
6947 service->favorite = favorite;
6949 favorite_changed(service);
6951 if (!delay_ordering) {
6953 service_list_sort();
6955 __connman_connection_update_gateway();
6962 * __connman_service_set_favorite:
6963 * @service: service structure
6964 * @favorite: favorite value
6966 * Change the favorite setting of service
6968 int __connman_service_set_favorite(struct connman_service *service,
6971 return __connman_service_set_favorite_delayed(service, favorite,
6975 bool connman_service_get_favorite(struct connman_service *service)
6977 return service->favorite;
6980 bool connman_service_get_autoconnect(struct connman_service *service)
6982 return service->autoconnect;
6985 int __connman_service_set_immutable(struct connman_service *service,
6988 if (service->hidden)
6991 if (service->immutable == immutable)
6994 service->immutable = immutable;
6996 immutable_changed(service);
7001 int __connman_service_set_ignore(struct connman_service *service,
7007 service->ignore = ignore;
7012 void __connman_service_set_string(struct connman_service *service,
7013 const char *key, const char *value)
7015 if (service->hidden)
7017 if (g_str_equal(key, "EAP")) {
7018 g_free(service->eap);
7019 service->eap = g_strdup(value);
7020 } else if (g_str_equal(key, "Identity")) {
7021 g_free(service->identity);
7022 service->identity = g_strdup(value);
7023 } else if (g_str_equal(key, "AnonymousIdentity")) {
7024 g_free(service->anonymous_identity);
7025 service->anonymous_identity = g_strdup(value);
7026 } else if (g_str_equal(key, "CACertFile")) {
7027 g_free(service->ca_cert_file);
7028 service->ca_cert_file = g_strdup(value);
7029 } else if (g_str_equal(key, "SubjectMatch")) {
7030 g_free(service->subject_match);
7031 service->subject_match = g_strdup(value);
7032 } else if (g_str_equal(key, "AltSubjectMatch")) {
7033 g_free(service->altsubject_match);
7034 service->altsubject_match = g_strdup(value);
7035 } else if (g_str_equal(key, "DomainSuffixMatch")) {
7036 g_free(service->domain_suffix_match);
7037 service->domain_suffix_match = g_strdup(value);
7038 } else if (g_str_equal(key, "DomainMatch")) {
7039 g_free(service->domain_match);
7040 service->domain_match = g_strdup(value);
7041 } else if (g_str_equal(key, "ClientCertFile")) {
7042 g_free(service->client_cert_file);
7043 service->client_cert_file = g_strdup(value);
7044 } else if (g_str_equal(key, "PrivateKeyFile")) {
7045 g_free(service->private_key_file);
7046 service->private_key_file = g_strdup(value);
7047 } else if (g_str_equal(key, "PrivateKeyPassphrase")) {
7048 g_free(service->private_key_passphrase);
7049 service->private_key_passphrase = g_strdup(value);
7050 } else if (g_str_equal(key, "Phase2")) {
7051 g_free(service->phase2);
7052 service->phase2 = g_strdup(value);
7053 } else if (g_str_equal(key, "Passphrase"))
7054 __connman_service_set_passphrase(service, value);
7055 #if defined TIZEN_EXT
7056 else if (g_str_equal(key, "Connector")) {
7057 g_free(service->connector);
7058 service->connector = g_strdup(value);
7059 } else if (g_str_equal(key, "CSignKey")) {
7060 g_free(service->c_sign_key);
7061 service->c_sign_key = g_strdup(value);
7062 } else if (g_str_equal(key, "NetAccessKey")) {
7063 g_free(service->net_access_key);
7064 service->net_access_key = g_strdup(value);
7066 DBG("Unknown key: %s", key);
7070 void __connman_service_set_search_domains(struct connman_service *service,
7073 searchdomain_remove_all(service);
7075 if (service->domains)
7076 g_strfreev(service->domains);
7078 service->domains = g_strdupv(domains);
7080 searchdomain_add_all(service);
7083 int __connman_service_set_mdns(struct connman_service *service,
7086 service->mdns_config = enabled;
7088 return set_mdns(service, enabled);
7091 static void report_error_cb(void *user_context, bool retry,
7094 struct connman_service *service = user_context;
7097 __connman_service_connect(service,
7098 CONNMAN_SERVICE_CONNECT_REASON_USER);
7100 /* It is not relevant to stay on Failure state
7101 * when failing is due to wrong user input */
7102 __connman_service_clear_error(service);
7103 #if defined TIZEN_EXT
7104 /* Reseting the state back in case of failure state */
7105 service->state_ipv4 = service->state_ipv6 =
7106 CONNMAN_SERVICE_STATE_IDLE;
7108 if (service->error != CONNMAN_SERVICE_ERROR_AUTH_FAILED)
7109 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
7111 service_complete(service);
7112 __connman_connection_update_gateway();
7116 static int check_wpspin(struct connman_service *service, const char *wpspin)
7124 length = strlen(wpspin);
7126 /* If 0, it will mean user wants to use PBC method */
7128 connman_network_set_string(service->network,
7129 "WiFi.PinWPS", NULL);
7133 /* A WPS PIN is always 8 chars length,
7134 * its content is in digit representation.
7139 for (i = 0; i < 8; i++)
7140 if (!isdigit((unsigned char) wpspin[i]))
7143 connman_network_set_string(service->network, "WiFi.PinWPS", wpspin);
7148 static void request_input_cb(struct connman_service *service,
7149 bool values_received,
7150 const char *name, int name_len,
7151 const char *identity, const char *passphrase,
7152 bool wps, const char *wpspin,
7153 const char *error, void *user_data)
7155 struct connman_device *device;
7156 const char *security;
7159 DBG("RequestInput return, %p", service);
7162 DBG("error: %s", error);
7164 if (g_strcmp0(error,
7165 "net.connman.Agent.Error.Canceled") == 0) {
7166 err = -ECONNABORTED;
7168 if (service->hidden)
7169 __connman_service_return_error(service,
7174 if (service->hidden)
7175 __connman_service_return_error(service,
7176 ETIMEDOUT, user_data);
7180 if (service->hidden && name_len > 0 && name_len <= 32) {
7181 device = connman_network_get_device(service->network);
7182 security = connman_network_get_string(service->network,
7184 err = __connman_device_request_hidden_scan(device,
7186 identity, passphrase,
7187 security, user_data);
7189 __connman_service_return_error(service, -err,
7193 if (!values_received || service->hidden) {
7198 if (wps && service->network) {
7199 err = check_wpspin(service, wpspin);
7203 connman_network_set_bool(service->network, "WiFi.UseWPS", wps);
7207 __connman_service_set_agent_identity(service, identity);
7210 err = __connman_service_set_passphrase(service, passphrase);
7214 /* We forget any previous error. */
7215 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
7217 __connman_service_connect(service,
7218 CONNMAN_SERVICE_CONNECT_REASON_USER);
7220 } else if (err == -ENOKEY) {
7221 __connman_service_indicate_error(service,
7222 CONNMAN_SERVICE_ERROR_INVALID_KEY);
7224 /* It is not relevant to stay on Failure state
7225 * when failing is due to wrong user input */
7226 service->state = CONNMAN_SERVICE_STATE_IDLE;
7228 if (!service->hidden) {
7230 * If there was a real error when requesting
7231 * hidden scan, then that error is returned already
7232 * to the user somewhere above so do not try to
7235 __connman_service_return_error(service, -err,
7239 service_complete(service);
7240 __connman_connection_update_gateway();
7244 static void downgrade_connected_services(void)
7246 struct connman_service *up_service;
7249 for (list = service_list; list; list = list->next) {
7250 up_service = list->data;
7252 if (!is_connected(up_service->state))
7255 if (up_service->state == CONNMAN_SERVICE_STATE_ONLINE)
7258 downgrade_state(up_service);
7262 static int service_update_preferred_order(struct connman_service *default_service,
7263 struct connman_service *new_service,
7264 enum connman_service_state new_state)
7266 unsigned int *tech_array;
7269 if (!default_service || default_service == new_service ||
7270 default_service->state != new_state)
7273 tech_array = connman_setting_get_uint_list("PreferredTechnologies");
7276 for (i = 0; tech_array[i] != 0; i += 1) {
7277 if (default_service->type == tech_array[i])
7280 if (new_service->type == tech_array[i]) {
7281 switch_default_service(default_service,
7283 __connman_connection_update_gateway();
7292 #if defined TIZEN_EXT
7293 static gboolean __connman_service_can_drop(struct connman_service *service)
7295 if (is_connected(service->state) == TRUE || is_connecting(service->state) == TRUE) {
7296 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR)
7298 else if (connman_service_is_no_ref_user_pdn_connection(service) == TRUE)
7304 static struct connman_device *default_connecting_device = NULL;
7306 static void __connman_service_disconnect_default(struct connman_service *service)
7308 struct connman_device *default_device = NULL;
7310 if (default_connecting_device == NULL)
7313 default_device = connman_network_get_device(
7314 __connman_service_get_network(service));
7316 DBG("Disconnecting service %p %s", service, service->path);
7317 DBG("Disconnecting device %p %p %s",
7318 default_connecting_device,
7320 connman_device_get_string(default_device, "Name"));
7322 if (default_connecting_device == default_device)
7323 default_connecting_device = NULL;
7326 #if defined TIZEN_MAINTAIN_ONLINE
7327 static void __connman_service_connect_default(struct connman_service *current,
7328 enum connman_service_state old_state)
7330 static void __connman_service_connect_default(struct connman_service *current)
7335 bool default_internet;
7336 struct connman_service *service;
7337 struct connman_service *default_service = NULL;
7338 struct connman_device *default_device = NULL;
7340 if (current->type == CONNMAN_SERVICE_TYPE_CELLULAR) {
7341 switch (current->state) {
7342 case CONNMAN_SERVICE_STATE_UNKNOWN:
7343 case CONNMAN_SERVICE_STATE_ASSOCIATION:
7344 case CONNMAN_SERVICE_STATE_CONFIGURATION:
7350 if (default_connecting_device &&
7351 __connman_service_is_internet_profile(current) == TRUE) {
7352 if (current->network == NULL)
7355 default_device = connman_network_get_device(current->network);
7356 if (default_connecting_device == default_device) {
7357 DBG("Cellular service[%s] %p %s",
7358 state2string(current->state), current, current->path);
7359 DBG("Cellular device %p %p %s",
7360 default_connecting_device, default_device,
7361 connman_device_get_string(default_device, "Name"));
7363 default_connecting_device = NULL;
7368 #if defined TIZEN_MAINTAIN_ONLINE
7369 } else if (current->state == CONNMAN_SERVICE_STATE_READY &&
7370 old_state == CONNMAN_SERVICE_STATE_ONLINE) {
7371 DBG("Device is downgraded: online --> ready");
7373 } else if (is_connected(current->state) == TRUE || is_connecting(current->state) == TRUE)
7376 /* Always-on: keep default cellular connection as possible */
7377 for (list = service_list; list; list = list->next) {
7378 service = list->data;
7380 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
7381 __connman_service_is_internet_profile(service) != TRUE ||
7382 service->network == NULL) {
7387 connman_network_get_bool(service->network, "DefaultInternet");
7389 DBG("service: %p %s %s %s (default: %d)", service, service->name,
7390 __connman_service_type2string(service->type),
7391 state2string(service->state), default_internet);
7393 if (default_internet) {
7394 default_service = service;
7395 if (is_connected(default_service->state) == TRUE ||
7396 is_connecting(default_service->state) == TRUE)
7399 default_device = connman_network_get_device(default_service->network);
7400 if (default_connecting_device == default_device) {
7401 DBG("Device is connecting (%p)", default_connecting_device);
7405 default_connecting_device = default_device;
7406 default_service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_USER;
7408 err = __connman_network_connect(default_service->network);
7409 DBG("Connecting default service %p %s [%d]",
7410 default_service, default_service->path, err);
7411 DBG("Connecting device %p %s", default_connecting_device,
7412 connman_device_get_string(default_connecting_device, "Name"));
7413 if (err < 0 && err != -EINPROGRESS) {
7414 default_connecting_device = NULL;
7422 static void single_connected_tech(struct connman_service *allowed)
7424 struct connman_service *service;
7425 GSList *services = NULL, *list;
7428 DBG("keeping %p %s", allowed, allowed->path);
7430 #if defined TIZEN_EXT
7431 if (!allowed || allowed->type == CONNMAN_SERVICE_TYPE_CELLULAR)
7435 for (iter = service_list; iter; iter = iter->next) {
7436 service = iter->data;
7438 #if defined TIZEN_EXT
7439 if (service != allowed && service->type != allowed->type &&
7440 __connman_service_can_drop(service) == TRUE)
7442 if (!is_connected(service->state))
7445 if (service == allowed)
7449 services = g_slist_prepend(services, service);
7452 for (list = services; list; list = list->next) {
7453 service = list->data;
7455 DBG("disconnecting %p %s", service, service->path);
7456 #if defined TIZEN_EXT
7457 __connman_service_disconnect_default(service);
7459 __connman_service_disconnect(service);
7462 g_slist_free(services);
7465 #if defined TIZEN_EXT
7466 static void set_priority_connected_service(void)
7468 struct connman_service *service;
7471 for (list = service_list; list; list = list->next) {
7472 service = list->data;
7474 if (is_connected(service->state) == FALSE)
7477 #if defined TIZEN_MAINTAIN_ONLINE
7479 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
7480 service->state == CONNMAN_SERVICE_STATE_ONLINE)
7482 else if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
7494 static const char *get_dbus_sender(struct connman_service *service)
7496 if (!service->pending)
7499 return dbus_message_get_sender(service->pending);
7502 static int service_indicate_state(struct connman_service *service)
7504 enum connman_service_state old_state, new_state;
7505 struct connman_service *def_service;
7506 enum connman_ipconfig_method method;
7512 old_state = service->state;
7513 new_state = combine_state(service->state_ipv4, service->state_ipv6);
7515 DBG("service %p old %s - new %s/%s => %s",
7517 state2string(old_state),
7518 state2string(service->state_ipv4),
7519 state2string(service->state_ipv6),
7520 state2string(new_state));
7522 if (old_state == new_state)
7525 def_service = connman_service_get_default();
7527 if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
7528 result = service_update_preferred_order(def_service,
7529 service, new_state);
7530 if (result == -EALREADY)
7534 if (old_state == CONNMAN_SERVICE_STATE_ONLINE)
7535 __connman_notifier_leave_online(service->type);
7537 if (is_connected(old_state) && !is_connected(new_state))
7538 searchdomain_remove_all(service);
7540 service->state = new_state;
7541 state_changed(service);
7543 if (!is_connected(old_state) && is_connected(new_state))
7544 searchdomain_add_all(service);
7547 case CONNMAN_SERVICE_STATE_UNKNOWN:
7551 case CONNMAN_SERVICE_STATE_IDLE:
7552 if (old_state != CONNMAN_SERVICE_STATE_DISCONNECT)
7553 __connman_service_disconnect(service);
7557 case CONNMAN_SERVICE_STATE_ASSOCIATION:
7561 case CONNMAN_SERVICE_STATE_CONFIGURATION:
7562 if (!service->new_service &&
7563 __connman_stats_service_register(service) == 0) {
7565 * For new services the statistics are updated after
7566 * we have successfully connected.
7568 __connman_stats_get(service, false,
7569 &service->stats.data);
7570 __connman_stats_get(service, true,
7571 &service->stats_roaming.data);
7576 case CONNMAN_SERVICE_STATE_READY:
7577 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
7579 if (service->new_service &&
7580 __connman_stats_service_register(service) == 0) {
7582 * This is normally done after configuring state
7583 * but for new service do this after we have connected
7586 __connman_stats_get(service, false,
7587 &service->stats.data);
7588 __connman_stats_get(service, true,
7589 &service->stats_roaming.data);
7592 service->new_service = false;
7596 def_service = connman_service_get_default();
7598 service_update_preferred_order(def_service, service, new_state);
7600 __connman_service_set_favorite(service, true);
7602 reply_pending(service, 0);
7604 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
7605 connman_network_get_bool(service->network,
7609 pass = connman_network_get_string(service->network,
7612 __connman_service_set_passphrase(service, pass);
7614 connman_network_set_bool(service->network,
7615 "WiFi.UseWPS", false);
7618 g_get_current_time(&service->modified);
7619 service_save(service);
7621 domain_changed(service);
7622 proxy_changed(service);
7624 if (old_state != CONNMAN_SERVICE_STATE_ONLINE)
7625 __connman_notifier_connect(service->type);
7627 method = __connman_ipconfig_get_method(service->ipconfig_ipv6);
7628 if (method == CONNMAN_IPCONFIG_METHOD_OFF)
7629 __connman_ipconfig_disable_ipv6(
7630 service->ipconfig_ipv6);
7632 #if !defined TIZEN_MAINTAIN_ONLINE
7633 if (connman_setting_get_bool("SingleConnectedTechnology"))
7634 single_connected_tech(service);
7635 else if (service->type != CONNMAN_SERVICE_TYPE_VPN)
7638 if (service->type != CONNMAN_SERVICE_TYPE_VPN)
7642 #if defined TIZEN_EXT
7643 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
7644 set_priority_connected_service();
7649 case CONNMAN_SERVICE_STATE_ONLINE:
7650 #if defined TIZEN_MAINTAIN_ONLINE
7651 #if defined TIZEN_EXT
7652 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
7653 set_priority_connected_service();
7656 if (connman_setting_get_bool("SingleConnectedTechnology"))
7657 single_connected_tech(service);
7662 case CONNMAN_SERVICE_STATE_DISCONNECT:
7663 set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
7665 reply_pending(service, ECONNABORTED);
7669 __connman_wispr_stop(service);
7671 __connman_wpad_stop(service);
7673 #if defined TIZEN_EXT
7675 * Skip the functions if there is any connected profiles
7676 * that use same interface
7678 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
7679 __connman_service_get_connected_count_of_iface(
7682 domain_changed(service);
7683 proxy_changed(service);
7684 #if defined TIZEN_EXT
7689 * Previous services which are connected and which states
7690 * are set to online should reset relevantly ipconfig_state
7691 * to ready so wispr/portal will be rerun on those
7693 downgrade_connected_services();
7695 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
7698 case CONNMAN_SERVICE_STATE_FAILURE:
7699 #if defined TIZEN_EXT
7700 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
7702 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
7704 if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
7705 connman_agent_report_error(service, service->path,
7706 error2string(service->error),
7708 get_dbus_sender(service),
7711 service_complete(service);
7715 service_list_sort();
7717 #if defined TIZEN_EXT
7718 #if defined TIZEN_MAINTAIN_ONLINE
7719 __connman_service_connect_default(service, old_state);
7721 __connman_service_connect_default(service);
7725 __connman_connection_update_gateway();
7727 if ((old_state == CONNMAN_SERVICE_STATE_ONLINE &&
7728 new_state != CONNMAN_SERVICE_STATE_READY) ||
7729 (old_state == CONNMAN_SERVICE_STATE_READY &&
7730 new_state != CONNMAN_SERVICE_STATE_ONLINE)) {
7731 __connman_notifier_disconnect(service->type);
7734 if (new_state == CONNMAN_SERVICE_STATE_ONLINE) {
7735 __connman_notifier_enter_online(service->type);
7742 int __connman_service_indicate_error(struct connman_service *service,
7743 enum connman_service_error error)
7745 DBG("service %p error %d", service, error);
7750 if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
7753 set_error(service, error);
7755 /* default internet service: fix not cleared if pdp activation*/
7756 #if defined TIZEN_EXT
7758 * If connection failed for default service(DefaultInternet),
7759 * default_connecting_device should be cleared.
7761 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
7762 service->error == CONNMAN_SERVICE_ERROR_CONNECT_FAILED)
7763 __connman_service_disconnect_default(service);
7765 if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
7766 service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY) {
7767 g_free(service->passphrase);
7768 service->passphrase = NULL;
7772 __connman_service_ipconfig_indicate_state(service,
7773 CONNMAN_SERVICE_STATE_FAILURE,
7774 CONNMAN_IPCONFIG_TYPE_IPV4);
7775 __connman_service_ipconfig_indicate_state(service,
7776 CONNMAN_SERVICE_STATE_FAILURE,
7777 CONNMAN_IPCONFIG_TYPE_IPV6);
7781 int __connman_service_clear_error(struct connman_service *service)
7783 DBusMessage *pending, *provider_pending;
7785 DBG("service %p", service);
7790 if (service->state != CONNMAN_SERVICE_STATE_FAILURE)
7793 pending = service->pending;
7794 service->pending = NULL;
7795 provider_pending = service->provider_pending;
7796 service->provider_pending = NULL;
7798 __connman_service_ipconfig_indicate_state(service,
7799 CONNMAN_SERVICE_STATE_IDLE,
7800 CONNMAN_IPCONFIG_TYPE_IPV6);
7802 __connman_service_ipconfig_indicate_state(service,
7803 CONNMAN_SERVICE_STATE_IDLE,
7804 CONNMAN_IPCONFIG_TYPE_IPV4);
7806 service->pending = pending;
7807 service->provider_pending = provider_pending;
7812 int __connman_service_indicate_default(struct connman_service *service)
7814 DBG("service %p state %s", service, state2string(service->state));
7816 if (!is_connected(service->state)) {
7818 * If service is not yet fully connected, then we must not
7819 * change the default yet. The default gw will be changed
7820 * after the service state is in ready.
7822 return -EINPROGRESS;
7830 enum connman_service_state __connman_service_ipconfig_get_state(
7831 struct connman_service *service,
7832 enum connman_ipconfig_type type)
7835 return CONNMAN_SERVICE_STATE_UNKNOWN;
7837 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
7838 return service->state_ipv4;
7840 if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
7841 return service->state_ipv6;
7843 return CONNMAN_SERVICE_STATE_UNKNOWN;
7846 static void check_proxy_setup(struct connman_service *service)
7849 * We start WPAD if we haven't got a PAC URL from DHCP and
7850 * if our proxy manual configuration is either empty or set
7851 * to AUTO with an empty URL.
7854 if (service->proxy != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN)
7857 if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN &&
7858 (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_AUTO ||
7862 if (__connman_wpad_start(service) < 0) {
7863 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
7864 __connman_notifier_proxy_changed(service);
7871 __connman_service_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
7874 #if defined TIZEN_EXT
7875 void connman_check_proxy_setup_and_wispr_start(struct connman_service *service){
7877 DBG("check the proxy and start wispr");
7878 check_proxy_setup(service);
7884 * How many networks are connected at the same time. If more than 1,
7885 * then set the rp_filter setting properly (loose mode routing) so that network
7886 * connectivity works ok. This is only done for IPv4 networks as IPv6
7887 * does not have rp_filter knob.
7889 static int connected_networks_count;
7890 static int original_rp_filter;
7892 static void service_rp_filter(struct connman_service *service,
7895 enum connman_ipconfig_method method;
7897 method = __connman_ipconfig_get_method(service->ipconfig_ipv4);
7900 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
7901 case CONNMAN_IPCONFIG_METHOD_OFF:
7902 case CONNMAN_IPCONFIG_METHOD_AUTO:
7904 case CONNMAN_IPCONFIG_METHOD_FIXED:
7905 case CONNMAN_IPCONFIG_METHOD_MANUAL:
7906 case CONNMAN_IPCONFIG_METHOD_DHCP:
7911 if (connected_networks_count == 1) {
7913 filter_value = __connman_ipconfig_set_rp_filter();
7914 if (filter_value < 0)
7917 original_rp_filter = filter_value;
7919 connected_networks_count++;
7922 if (connected_networks_count == 2)
7923 __connman_ipconfig_unset_rp_filter(original_rp_filter);
7925 connected_networks_count--;
7926 if (connected_networks_count < 0)
7927 connected_networks_count = 0;
7930 DBG("%s %s ipconfig %p method %d count %d filter %d",
7931 connected ? "connected" : "disconnected", service->identifier,
7932 service->ipconfig_ipv4, method,
7933 connected_networks_count, original_rp_filter);
7936 static void redo_wispr(struct connman_service *service,
7937 enum connman_ipconfig_type type)
7939 service->online_timeout = 0;
7940 connman_service_unref(service);
7942 DBG("Retrying %s WISPr for %p %s",
7943 __connman_ipconfig_type2string(type),
7944 service, service->name);
7946 __connman_wispr_start(service, type);
7949 static gboolean redo_wispr_ipv4(gpointer user_data)
7951 struct connman_service *service = user_data;
7953 redo_wispr(service, CONNMAN_IPCONFIG_TYPE_IPV4);
7958 static gboolean redo_wispr_ipv6(gpointer user_data)
7960 struct connman_service *service = user_data;
7962 redo_wispr(service, CONNMAN_IPCONFIG_TYPE_IPV6);
7967 #if defined TIZEN_MAINTAIN_ONLINE
7968 static gboolean redo_wispr_ipv4(gpointer user_data)
7970 struct connman_service *service = user_data;
7974 __connman_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
7980 int __connman_service_online_check_failed(struct connman_service *service,
7981 enum connman_ipconfig_type type)
7983 GSourceFunc redo_func;
7986 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
7987 interval = &service->online_check_interval_ipv4;
7988 redo_func = redo_wispr_ipv4;
7990 interval = &service->online_check_interval_ipv6;
7991 redo_func = redo_wispr_ipv6;
7994 DBG("service %p type %s interval %d", service,
7995 __connman_ipconfig_type2string(type), *interval);
7997 service->online_timeout = g_timeout_add_seconds(*interval * *interval,
7998 redo_func, connman_service_ref(service));
8000 /* Increment the interval for the next time, set a maximum timeout of
8001 * ONLINE_CHECK_MAX_INTERVAL * ONLINE_CHECK_MAX_INTERVAL seconds.
8003 if (*interval < ONLINE_CHECK_MAX_INTERVAL)
8009 static void cancel_online_check(struct connman_service *service)
8011 if (service->online_timeout == 0)
8014 g_source_remove(service->online_timeout);
8015 service->online_timeout = 0;
8016 connman_service_unref(service);
8019 int __connman_service_ipconfig_indicate_state(struct connman_service *service,
8020 enum connman_service_state new_state,
8021 enum connman_ipconfig_type type)
8023 struct connman_ipconfig *ipconfig = NULL;
8024 enum connman_service_state old_state;
8025 enum connman_ipconfig_method method;
8031 case CONNMAN_IPCONFIG_TYPE_UNKNOWN:
8032 case CONNMAN_IPCONFIG_TYPE_ALL:
8035 case CONNMAN_IPCONFIG_TYPE_IPV4:
8036 old_state = service->state_ipv4;
8037 ipconfig = service->ipconfig_ipv4;
8041 case CONNMAN_IPCONFIG_TYPE_IPV6:
8042 old_state = service->state_ipv6;
8043 ipconfig = service->ipconfig_ipv6;
8051 method = __connman_ipconfig_get_method(ipconfig);
8054 case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
8055 case CONNMAN_IPCONFIG_METHOD_OFF:
8056 if (new_state != CONNMAN_SERVICE_STATE_IDLE)
8057 connman_warn("ipconfig state %d ipconfig method %d",
8060 #if defined TIZEN_EXT
8061 if (old_state != CONNMAN_SERVICE_STATE_READY &&
8062 old_state != CONNMAN_SERVICE_STATE_ONLINE)
8064 new_state = CONNMAN_SERVICE_STATE_IDLE;
8067 case CONNMAN_IPCONFIG_METHOD_FIXED:
8068 case CONNMAN_IPCONFIG_METHOD_MANUAL:
8069 case CONNMAN_IPCONFIG_METHOD_DHCP:
8070 case CONNMAN_IPCONFIG_METHOD_AUTO:
8076 if (old_state == new_state)
8079 #if defined TIZEN_EXT
8080 __sync_synchronize();
8081 if (service->user_pdn_connection_refcount > 0 &&
8082 service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
8083 if (new_state == CONNMAN_SERVICE_STATE_FAILURE ||
8084 new_state == CONNMAN_SERVICE_STATE_DISCONNECT ||
8085 new_state == CONNMAN_SERVICE_STATE_IDLE) {
8086 service->user_pdn_connection_refcount = 0;
8087 __sync_synchronize();
8091 DBG("service %p (%s) old state %d (%s) new state %d (%s) type %d (%s)",
8092 service, service ? service->identifier : NULL,
8093 old_state, state2string(old_state),
8094 new_state, state2string(new_state),
8095 type, __connman_ipconfig_type2string(type));
8097 switch (new_state) {
8098 case CONNMAN_SERVICE_STATE_UNKNOWN:
8099 case CONNMAN_SERVICE_STATE_ASSOCIATION:
8101 case CONNMAN_SERVICE_STATE_CONFIGURATION:
8103 case CONNMAN_SERVICE_STATE_READY:
8104 #if defined TIZEN_EXT
8105 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR &&
8106 __connman_service_is_internet_profile(service) != TRUE) {
8107 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
8108 service_rp_filter(service, TRUE);
8113 if (connman_setting_get_bool("EnableOnlineCheck"))
8114 if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
8115 #if !defined TIZEN_EXT
8116 check_proxy_setup(service);
8118 #if defined TIZEN_MAINTAIN_ONLINE
8119 /* if (old_state == CONNMAN_SERVICE_STATE_ONLINE) */
8120 check_proxy_setup(service);
8123 __connman_service_wispr_start(service, type);
8126 connman_info("Online check disabled. "
8127 "Default service remains in READY state.");
8128 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
8129 service_rp_filter(service, true);
8130 set_mdns(service, service->mdns_config);
8132 case CONNMAN_SERVICE_STATE_ONLINE:
8134 case CONNMAN_SERVICE_STATE_DISCONNECT:
8135 if (service->state == CONNMAN_SERVICE_STATE_IDLE)
8138 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
8139 service_rp_filter(service, false);
8143 case CONNMAN_SERVICE_STATE_IDLE:
8144 case CONNMAN_SERVICE_STATE_FAILURE:
8145 __connman_ipconfig_disable(ipconfig);
8150 if (is_connected(old_state) && !is_connected(new_state)) {
8151 nameserver_remove_all(service, type);
8152 cancel_online_check(service);
8155 if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
8156 service->state_ipv4 = new_state;
8158 service->state_ipv6 = new_state;
8160 if (!is_connected(old_state) && is_connected(new_state))
8161 nameserver_add_all(service, type);
8163 __connman_timeserver_sync(service);
8165 #if defined TIZEN_EXT
8166 int ret = service_indicate_state(service);
8167 /*Sent the Ready changed signal again in case IPv4 IP set
8170 if(ret == -EALREADY && type == CONNMAN_IPCONFIG_TYPE_IPV4
8171 && new_state == CONNMAN_SERVICE_STATE_READY) {
8172 DBG("Notify IPv4 state new/old %d/%d", new_state,old_state);
8173 state_changed(service);
8178 return service_indicate_state(service);
8181 static bool prepare_network(struct connman_service *service)
8183 enum connman_network_type type;
8184 unsigned int ssid_len;
8186 type = connman_network_get_type(service->network);
8189 case CONNMAN_NETWORK_TYPE_UNKNOWN:
8190 case CONNMAN_NETWORK_TYPE_VENDOR:
8192 case CONNMAN_NETWORK_TYPE_WIFI:
8193 if (!connman_network_get_blob(service->network, "WiFi.SSID",
8197 if (service->passphrase)
8198 connman_network_set_string(service->network,
8199 "WiFi.Passphrase", service->passphrase);
8201 case CONNMAN_NETWORK_TYPE_ETHERNET:
8202 case CONNMAN_NETWORK_TYPE_GADGET:
8203 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
8204 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
8205 case CONNMAN_NETWORK_TYPE_CELLULAR:
8212 static void prepare_8021x(struct connman_service *service)
8215 connman_network_set_string(service->network, "WiFi.EAP",
8218 if (service->identity)
8219 connman_network_set_string(service->network, "WiFi.Identity",
8222 if (service->anonymous_identity)
8223 connman_network_set_string(service->network,
8224 "WiFi.AnonymousIdentity",
8225 service->anonymous_identity);
8227 if (service->ca_cert_file)
8228 connman_network_set_string(service->network, "WiFi.CACertFile",
8229 service->ca_cert_file);
8231 if (service->subject_match)
8232 connman_network_set_string(service->network, "WiFi.SubjectMatch",
8233 service->subject_match);
8235 if (service->altsubject_match)
8236 connman_network_set_string(service->network, "WiFi.AltSubjectMatch",
8237 service->altsubject_match);
8239 if (service->domain_suffix_match)
8240 connman_network_set_string(service->network, "WiFi.DomainSuffixMatch",
8241 service->domain_suffix_match);
8243 if (service->domain_match)
8244 connman_network_set_string(service->network, "WiFi.DomainMatch",
8245 service->domain_match);
8247 if (service->client_cert_file)
8248 connman_network_set_string(service->network,
8249 "WiFi.ClientCertFile",
8250 service->client_cert_file);
8252 if (service->private_key_file)
8253 connman_network_set_string(service->network,
8254 "WiFi.PrivateKeyFile",
8255 service->private_key_file);
8257 if (service->private_key_passphrase)
8258 connman_network_set_string(service->network,
8259 "WiFi.PrivateKeyPassphrase",
8260 service->private_key_passphrase);
8262 if (service->phase2)
8263 connman_network_set_string(service->network, "WiFi.Phase2",
8266 #if defined TIZEN_EXT
8267 if (service->keymgmt_type)
8268 connman_network_set_string(service->network, "WiFi.KeymgmtType",
8269 service->keymgmt_type);
8271 DBG("service->phase1 : %s", service->phase1);
8272 if (service->phase1)
8273 connman_network_set_string(service->network, "WiFi.Phase1",
8277 #if defined TIZEN_EXT
8279 static bool has_valid_configuration_object(struct connman_service *service)
8281 return service->connector && service->c_sign_key && service->net_access_key;
8284 static void prepare_dpp(struct connman_service *service)
8287 if (service->connector)
8288 connman_network_set_string(service->network, "WiFi.Connector",
8289 service->connector);
8291 if (service->c_sign_key)
8292 connman_network_set_string(service->network, "WiFi.CSignKey",
8293 service->c_sign_key);
8295 if (service->net_access_key)
8296 connman_network_set_string(service->network, "WiFi.NetAccessKey",
8297 service->net_access_key);
8301 static int service_connect(struct connman_service *service)
8305 if (service->hidden)
8308 #if defined TIZEN_EXT
8312 index = __connman_service_get_index(service);
8314 for (list = service_list; list; list = list->next) {
8315 struct connman_service *temp = list->data;
8317 if (service->type == CONNMAN_SERVICE_TYPE_CELLULAR)
8320 if (!is_connecting(temp->state) && !is_connected(temp->state))
8323 if (service == temp)
8326 if (service->type != temp->type)
8329 if (__connman_service_get_index(temp) == index &&
8330 __connman_service_disconnect(temp) == -EINPROGRESS)
8331 return -EINPROGRESS;
8335 switch (service->type) {
8336 case CONNMAN_SERVICE_TYPE_UNKNOWN:
8337 case CONNMAN_SERVICE_TYPE_SYSTEM:
8338 case CONNMAN_SERVICE_TYPE_GPS:
8339 case CONNMAN_SERVICE_TYPE_P2P:
8340 #if defined TIZEN_EXT_WIFI_MESH
8341 case CONNMAN_SERVICE_TYPE_MESH:
8344 case CONNMAN_SERVICE_TYPE_ETHERNET:
8345 case CONNMAN_SERVICE_TYPE_GADGET:
8346 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
8347 case CONNMAN_SERVICE_TYPE_CELLULAR:
8348 case CONNMAN_SERVICE_TYPE_VPN:
8350 case CONNMAN_SERVICE_TYPE_WIFI:
8351 switch (service->security) {
8352 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
8353 case CONNMAN_SERVICE_SECURITY_NONE:
8354 #if defined TIZEN_EXT
8355 case CONNMAN_SERVICE_SECURITY_OWE:
8358 case CONNMAN_SERVICE_SECURITY_WEP:
8359 case CONNMAN_SERVICE_SECURITY_PSK:
8360 case CONNMAN_SERVICE_SECURITY_WPA:
8361 case CONNMAN_SERVICE_SECURITY_RSN:
8362 #if defined TIZEN_EXT
8363 case CONNMAN_SERVICE_SECURITY_SAE:
8365 if (service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
8368 if (!service->passphrase) {
8369 if (!service->network)
8372 if (!service->wps ||
8373 !connman_network_get_bool(service->network, "WiFi.UseWPS"))
8378 #if defined TIZEN_EXT
8379 case CONNMAN_SERVICE_SECURITY_DPP:
8380 if (has_valid_configuration_object(service) &&
8385 case CONNMAN_SERVICE_SECURITY_8021X:
8386 if (!service->eap) {
8387 connman_warn("EAP type has not been found. "
8388 "Most likely ConnMan is not able to "
8389 "find a configuration for given "
8391 "Check SSID or Name match with the "
8396 #if defined TIZEN_EXT
8398 * never request credentials if using EAP-TLS, EAP-SIM
8399 * or EAP-AKA (EAP-TLS, EAP-SIM and EAP-AKA networks
8400 * need to be fully provisioned)
8402 DBG("service eap: %s", service->eap);
8403 if (g_str_equal(service->eap, "tls") ||
8404 g_str_equal(service->eap, "sim") ||
8405 g_str_equal(service->eap, "aka") ||
8406 g_str_equal(service->eap, "aka'") ||
8407 g_str_equal(service->eap, "pwd") ||
8408 g_str_equal(service->eap, "fast"))
8412 * never request credentials if using EAP-TLS
8413 * (EAP-TLS networks need to be fully provisioned)
8415 if (g_str_equal(service->eap, "tls"))
8420 * Return -ENOKEY if either identity or passphrase is
8421 * missing. Agent provided credentials can be used as
8422 * fallback if needed.
8424 if (((!service->identity &&
8425 !service->agent_identity) ||
8426 !service->passphrase) ||
8427 service->error == CONNMAN_SERVICE_ERROR_INVALID_KEY)
8435 if (service->network) {
8436 if (!prepare_network(service))
8439 switch (service->security) {
8440 case CONNMAN_SERVICE_SECURITY_UNKNOWN:
8441 case CONNMAN_SERVICE_SECURITY_NONE:
8442 case CONNMAN_SERVICE_SECURITY_WEP:
8443 case CONNMAN_SERVICE_SECURITY_PSK:
8444 case CONNMAN_SERVICE_SECURITY_WPA:
8445 case CONNMAN_SERVICE_SECURITY_RSN:
8446 #if defined TIZEN_EXT
8447 case CONNMAN_SERVICE_SECURITY_SAE:
8448 case CONNMAN_SERVICE_SECURITY_OWE:
8450 case CONNMAN_SERVICE_SECURITY_DPP:
8451 prepare_dpp(service);
8454 case CONNMAN_SERVICE_SECURITY_8021X:
8455 prepare_8021x(service);
8459 if (__connman_stats_service_register(service) == 0) {
8460 __connman_stats_get(service, false,
8461 &service->stats.data);
8462 __connman_stats_get(service, true,
8463 &service->stats_roaming.data);
8466 err = __connman_network_connect(service->network);
8467 } else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
8469 err = __connman_provider_connect(service->provider,
8470 get_dbus_sender(service));
8475 if (err != -EINPROGRESS) {
8476 __connman_service_ipconfig_indicate_state(service,
8477 CONNMAN_SERVICE_STATE_FAILURE,
8478 CONNMAN_IPCONFIG_TYPE_IPV4);
8479 __connman_service_ipconfig_indicate_state(service,
8480 CONNMAN_SERVICE_STATE_FAILURE,
8481 CONNMAN_IPCONFIG_TYPE_IPV6);
8482 __connman_stats_service_unregister(service);
8489 int __connman_service_connect(struct connman_service *service,
8490 enum connman_service_connect_reason reason)
8494 DBG("service %p state %s connect reason %s -> %s",
8495 service, state2string(service->state),
8496 reason2string(service->connect_reason),
8497 reason2string(reason));
8499 if (is_connected(service->state))
8502 if (is_connecting(service->state))
8505 switch (service->type) {
8506 case CONNMAN_SERVICE_TYPE_UNKNOWN:
8507 case CONNMAN_SERVICE_TYPE_SYSTEM:
8508 case CONNMAN_SERVICE_TYPE_GPS:
8509 case CONNMAN_SERVICE_TYPE_P2P:
8510 #if defined TIZEN_EXT_WIFI_MESH
8511 case CONNMAN_SERVICE_TYPE_MESH:
8515 case CONNMAN_SERVICE_TYPE_ETHERNET:
8516 case CONNMAN_SERVICE_TYPE_GADGET:
8517 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
8518 case CONNMAN_SERVICE_TYPE_CELLULAR:
8519 case CONNMAN_SERVICE_TYPE_VPN:
8520 case CONNMAN_SERVICE_TYPE_WIFI:
8524 if (!is_ipconfig_usable(service))
8527 __connman_service_clear_error(service);
8529 err = service_connect(service);
8531 DBG("service %p err %d", service, err);
8533 service->connect_reason = reason;
8534 #if defined TIZEN_EXT
8535 connect_reason_changed(service);
8541 if (err == -EINPROGRESS) {
8542 if (service->timeout == 0)
8543 service->timeout = g_timeout_add_seconds(
8544 CONNECT_TIMEOUT, connect_timeout, service);
8546 return -EINPROGRESS;
8549 if (service->network)
8550 __connman_network_disconnect(service->network);
8551 else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
8553 connman_provider_disconnect(service->provider);
8555 if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
8556 if (err == -ENOKEY || err == -EPERM) {
8557 DBusMessage *pending = NULL;
8558 const char *dbus_sender = get_dbus_sender(service);
8561 * We steal the reply here. The idea is that the
8562 * connecting client will see the connection status
8563 * after the real hidden network is connected or
8564 * connection failed.
8566 if (service->hidden) {
8567 pending = service->pending;
8568 service->pending = NULL;
8571 err = __connman_agent_request_passphrase_input(service,
8575 if (service->hidden && err != -EINPROGRESS)
8576 service->pending = pending;
8585 int __connman_service_disconnect(struct connman_service *service)
8589 DBG("service %p", service);
8591 service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_NONE;
8592 service->proxy = CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN;
8594 connman_agent_cancel(service);
8596 __connman_stats_service_unregister(service);
8598 if (service->network) {
8599 err = __connman_network_disconnect(service->network);
8600 } else if (service->type == CONNMAN_SERVICE_TYPE_VPN &&
8602 err = connman_provider_disconnect(service->provider);
8606 if (err < 0 && err != -EINPROGRESS)
8609 __connman_6to4_remove(service->ipconfig_ipv4);
8611 if (service->ipconfig_ipv4)
8612 __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv4,
8615 __connman_ipconfig_set_proxy_autoconfig(service->ipconfig_ipv6,
8618 #if defined TIZEN_EXT
8620 * Skip the functions If there is any connected profiles
8621 * that use same interface
8623 if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR ||
8624 __connman_service_get_connected_count_of_iface(service) <= 0) {
8626 __connman_ipconfig_address_remove(service->ipconfig_ipv4);
8627 settings_changed(service, service->ipconfig_ipv4);
8629 __connman_ipconfig_address_remove(service->ipconfig_ipv6);
8630 settings_changed(service, service->ipconfig_ipv6);
8632 __connman_ipconfig_disable(service->ipconfig_ipv4);
8633 __connman_ipconfig_disable(service->ipconfig_ipv6);
8634 #if defined TIZEN_EXT
8641 int __connman_service_disconnect_all(void)
8643 struct connman_service *service;
8644 GSList *services = NULL, *list;
8649 for (iter = service_list; iter; iter = iter->next) {
8650 service = iter->data;
8652 if (!is_connected(service->state))
8655 services = g_slist_prepend(services, service);
8658 for (list = services; list; list = list->next) {
8659 struct connman_service *service = list->data;
8661 service->ignore = true;
8663 __connman_service_disconnect(service);
8666 g_slist_free(services);
8672 * lookup_by_identifier:
8673 * @identifier: service identifier
8675 * Look up a service by identifier (reference count will not be increased)
8677 static struct connman_service *lookup_by_identifier(const char *identifier)
8679 return g_hash_table_lookup(service_hash, identifier);
8682 struct connman_service *connman_service_lookup_from_identifier(const char* identifier)
8684 return identifier ? lookup_by_identifier(identifier) : NULL;
8687 struct provision_user_data {
8692 static void provision_changed(gpointer value, gpointer user_data)
8694 struct connman_service *service = value;
8695 struct provision_user_data *data = user_data;
8696 const char *path = data->ident;
8699 ret = __connman_config_provision_service_ident(service, path,
8700 service->config_file, service->config_entry);
8705 int __connman_service_provision_changed(const char *ident)
8707 struct provision_user_data data = {
8712 g_list_foreach(service_list, provision_changed, (void *)&data);
8715 * Because the provision_changed() might have set some services
8716 * as favorite, we must sort the sequence now.
8718 if (services_dirty) {
8719 services_dirty = false;
8721 service_list_sort();
8723 __connman_connection_update_gateway();
8729 void __connman_service_set_config(struct connman_service *service,
8730 const char *file_id, const char *entry)
8735 g_free(service->config_file);
8736 service->config_file = g_strdup(file_id);
8738 g_free(service->config_entry);
8739 service->config_entry = g_strdup(entry);
8743 * __connman_service_get:
8744 * @identifier: service identifier
8746 * Look up a service by identifier or create a new one if not found
8748 static struct connman_service *service_get(const char *identifier)
8750 struct connman_service *service;
8752 service = g_hash_table_lookup(service_hash, identifier);
8754 connman_service_ref(service);
8758 service = connman_service_create();
8762 DBG("service %p", service);
8764 service->identifier = g_strdup(identifier);
8766 service_list = g_list_insert_sorted(service_list, service,
8769 g_hash_table_insert(service_hash, service->identifier, service);
8774 static int service_register(struct connman_service *service)
8776 DBG("service %p", service);
8781 service->path = g_strdup_printf("%s/service/%s", CONNMAN_PATH,
8782 service->identifier);
8784 DBG("path %s", service->path);
8786 #if defined TIZEN_EXT
8787 service_load(service);
8788 int ret = __connman_config_provision_service(service);
8790 DBG("Failed to provision service");
8792 if (__connman_config_provision_service(service) < 0)
8793 service_load(service);
8796 g_dbus_register_interface(connection, service->path,
8797 CONNMAN_SERVICE_INTERFACE,
8798 service_methods, service_signals,
8799 NULL, service, NULL);
8801 service_list_sort();
8803 __connman_connection_update_gateway();
8808 static void service_up(struct connman_ipconfig *ipconfig,
8811 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8813 DBG("%s up", ifname);
8815 link_changed(service);
8817 service->stats.valid = false;
8818 service->stats_roaming.valid = false;
8821 static void service_down(struct connman_ipconfig *ipconfig,
8824 DBG("%s down", ifname);
8827 static void service_lower_up(struct connman_ipconfig *ipconfig,
8830 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8832 DBG("%s lower up", ifname);
8834 stats_start(service);
8837 static void service_lower_down(struct connman_ipconfig *ipconfig,
8840 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8842 DBG("%s lower down", ifname);
8844 stats_stop(service);
8845 service_save(service);
8848 static void service_ip_bound(struct connman_ipconfig *ipconfig,
8851 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8852 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
8853 enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
8854 #if defined TIZEN_EXT
8858 DBG("%s ip bound", ifname);
8860 type = __connman_ipconfig_get_config_type(ipconfig);
8861 method = __connman_ipconfig_get_method(ipconfig);
8863 DBG("service %p ipconfig %p type %d method %d", service, ipconfig,
8866 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
8867 method == CONNMAN_IPCONFIG_METHOD_AUTO)
8868 #if defined TIZEN_EXT
8870 err = __connman_ipconfig_gateway_add(ipconfig, service);
8873 DBG("Failed to add gateway");
8876 __connman_service_ipconfig_indicate_state(service,
8877 CONNMAN_SERVICE_STATE_READY,
8878 CONNMAN_IPCONFIG_TYPE_IPV6);
8881 settings_changed(service, ipconfig);
8882 address_updated(service, type);
8885 static void service_ip_release(struct connman_ipconfig *ipconfig,
8888 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8889 enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
8890 enum connman_ipconfig_type type = CONNMAN_IPCONFIG_TYPE_UNKNOWN;
8892 DBG("%s ip release", ifname);
8894 type = __connman_ipconfig_get_config_type(ipconfig);
8895 method = __connman_ipconfig_get_method(ipconfig);
8897 DBG("service %p ipconfig %p type %d method %d", service, ipconfig,
8900 if (type == CONNMAN_IPCONFIG_TYPE_IPV6 &&
8901 method == CONNMAN_IPCONFIG_METHOD_OFF)
8902 __connman_service_ipconfig_indicate_state(service,
8903 CONNMAN_SERVICE_STATE_DISCONNECT,
8904 CONNMAN_IPCONFIG_TYPE_IPV6);
8906 if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
8907 method == CONNMAN_IPCONFIG_METHOD_OFF)
8908 __connman_service_ipconfig_indicate_state(service,
8909 CONNMAN_SERVICE_STATE_DISCONNECT,
8910 CONNMAN_IPCONFIG_TYPE_IPV4);
8912 settings_changed(service, ipconfig);
8915 static void service_route_changed(struct connman_ipconfig *ipconfig,
8918 struct connman_service *service = __connman_ipconfig_get_data(ipconfig);
8920 DBG("%s route changed", ifname);
8922 settings_changed(service, ipconfig);
8925 static const struct connman_ipconfig_ops service_ops = {
8927 .down = service_down,
8928 .lower_up = service_lower_up,
8929 .lower_down = service_lower_down,
8930 .ip_bound = service_ip_bound,
8931 .ip_release = service_ip_release,
8932 .route_set = service_route_changed,
8933 .route_unset = service_route_changed,
8936 static struct connman_ipconfig *create_ip4config(struct connman_service *service,
8937 int index, enum connman_ipconfig_method method)
8939 struct connman_ipconfig *ipconfig_ipv4;
8941 ipconfig_ipv4 = __connman_ipconfig_create(index,
8942 CONNMAN_IPCONFIG_TYPE_IPV4);
8946 __connman_ipconfig_set_method(ipconfig_ipv4, method);
8948 __connman_ipconfig_set_data(ipconfig_ipv4, service);
8950 __connman_ipconfig_set_ops(ipconfig_ipv4, &service_ops);
8952 return ipconfig_ipv4;
8955 static struct connman_ipconfig *create_ip6config(struct connman_service *service,
8958 struct connman_ipconfig *ipconfig_ipv6;
8960 ipconfig_ipv6 = __connman_ipconfig_create(index,
8961 CONNMAN_IPCONFIG_TYPE_IPV6);
8965 __connman_ipconfig_set_data(ipconfig_ipv6, service);
8967 __connman_ipconfig_set_ops(ipconfig_ipv6, &service_ops);
8969 return ipconfig_ipv6;
8972 void __connman_service_read_ip4config(struct connman_service *service)
8976 if (!service->ipconfig_ipv4)
8979 keyfile = connman_storage_load_service(service->identifier);
8983 __connman_ipconfig_load(service->ipconfig_ipv4, keyfile,
8984 service->identifier, "IPv4.");
8986 g_key_file_free(keyfile);
8989 void connman_service_create_ip4config(struct connman_service *service,
8992 DBG("ipv4 %p", service->ipconfig_ipv4);
8994 if (service->ipconfig_ipv4)
8997 service->ipconfig_ipv4 = create_ip4config(service, index,
8998 CONNMAN_IPCONFIG_METHOD_DHCP);
8999 __connman_service_read_ip4config(service);
9002 void __connman_service_read_ip6config(struct connman_service *service)
9006 if (!service->ipconfig_ipv6)
9009 keyfile = connman_storage_load_service(service->identifier);
9013 __connman_ipconfig_load(service->ipconfig_ipv6, keyfile,
9014 service->identifier, "IPv6.");
9016 g_key_file_free(keyfile);
9019 void connman_service_create_ip6config(struct connman_service *service,
9022 DBG("ipv6 %p", service->ipconfig_ipv6);
9024 if (service->ipconfig_ipv6)
9027 service->ipconfig_ipv6 = create_ip6config(service, index);
9029 __connman_service_read_ip6config(service);
9033 * connman_service_lookup_from_network:
9034 * @network: network structure
9036 * Look up a service by network (reference count will not be increased)
9038 struct connman_service *connman_service_lookup_from_network(struct connman_network *network)
9040 struct connman_service *service;
9041 const char *ident, *group;
9047 ident = __connman_network_get_ident(network);
9051 group = connman_network_get_group(network);
9055 name = g_strdup_printf("%s_%s_%s",
9056 __connman_network_get_type(network), ident, group);
9057 service = lookup_by_identifier(name);
9063 struct connman_service *__connman_service_lookup_from_index(int index)
9065 struct connman_service *service;
9068 for (list = service_list; list; list = list->next) {
9069 service = list->data;
9071 if (__connman_ipconfig_get_index(service->ipconfig_ipv4)
9075 if (__connman_ipconfig_get_index(service->ipconfig_ipv6)
9083 const char *connman_service_get_identifier(struct connman_service *service)
9085 return service ? service->identifier : NULL;
9088 const char *__connman_service_get_path(struct connman_service *service)
9090 return service->path;
9093 const char *__connman_service_get_name(struct connman_service *service)
9095 return service->name;
9098 enum connman_service_state connman_service_get_state(struct connman_service *service)
9100 return service ? service->state : CONNMAN_SERVICE_STATE_UNKNOWN;
9103 static enum connman_service_type convert_network_type(struct connman_network *network)
9105 enum connman_network_type type = connman_network_get_type(network);
9108 case CONNMAN_NETWORK_TYPE_UNKNOWN:
9109 case CONNMAN_NETWORK_TYPE_VENDOR:
9111 case CONNMAN_NETWORK_TYPE_ETHERNET:
9112 return CONNMAN_SERVICE_TYPE_ETHERNET;
9113 case CONNMAN_NETWORK_TYPE_WIFI:
9114 return CONNMAN_SERVICE_TYPE_WIFI;
9115 case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
9116 case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
9117 return CONNMAN_SERVICE_TYPE_BLUETOOTH;
9118 case CONNMAN_NETWORK_TYPE_CELLULAR:
9119 return CONNMAN_SERVICE_TYPE_CELLULAR;
9120 case CONNMAN_NETWORK_TYPE_GADGET:
9121 return CONNMAN_SERVICE_TYPE_GADGET;
9124 return CONNMAN_SERVICE_TYPE_UNKNOWN;
9127 static enum connman_service_security convert_wifi_security(const char *security)
9130 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
9131 else if (g_str_equal(security, "none"))
9132 return CONNMAN_SERVICE_SECURITY_NONE;
9133 else if (g_str_equal(security, "wep"))
9134 return CONNMAN_SERVICE_SECURITY_WEP;
9135 else if (g_str_equal(security, "psk"))
9136 return CONNMAN_SERVICE_SECURITY_PSK;
9137 else if (g_str_equal(security, "ieee8021x"))
9138 return CONNMAN_SERVICE_SECURITY_8021X;
9139 else if (g_str_equal(security, "wpa"))
9140 return CONNMAN_SERVICE_SECURITY_WPA;
9141 else if (g_str_equal(security, "rsn"))
9142 return CONNMAN_SERVICE_SECURITY_RSN;
9143 #if defined TIZEN_EXT
9144 else if (g_str_equal(security, "sae"))
9145 return CONNMAN_SERVICE_SECURITY_SAE;
9146 else if (g_str_equal(security, "owe"))
9147 return CONNMAN_SERVICE_SECURITY_OWE;
9148 else if (g_str_equal(security, "dpp"))
9149 return CONNMAN_SERVICE_SECURITY_DPP;
9150 else if (g_str_equal(security, "ft_psk") == TRUE)
9151 return CONNMAN_SERVICE_SECURITY_PSK;
9152 else if (g_str_equal(security, "ft_ieee8021x") == TRUE)
9153 return CONNMAN_SERVICE_SECURITY_8021X;
9156 return CONNMAN_SERVICE_SECURITY_UNKNOWN;
9159 #if defined TIZEN_EXT
9160 int check_passphrase_ext(struct connman_network *network,
9161 const char *passphrase)
9164 enum connman_service_security security;
9166 str = connman_network_get_string(network, "WiFi.Security");
9167 security = convert_wifi_security(str);
9169 return __connman_service_check_passphrase(security, passphrase);
9173 static void update_wps_values(struct connman_service *service,
9174 struct connman_network *network)
9176 bool wps = connman_network_get_bool(network, "WiFi.WPS");
9177 bool wps_advertising = connman_network_get_bool(network,
9178 "WiFi.WPSAdvertising");
9180 if (service->wps != wps ||
9181 service->wps_advertizing != wps_advertising) {
9183 service->wps_advertizing = wps_advertising;
9184 security_changed(service);
9188 static void update_from_network(struct connman_service *service,
9189 struct connman_network *network)
9191 uint8_t strength = service->strength;
9194 DBG("service %p network %p", service, network);
9196 if (is_connected(service->state))
9199 if (is_connecting(service->state))
9202 str = connman_network_get_string(network, "Name");
9204 g_free(service->name);
9205 service->name = g_strdup(str);
9206 service->hidden = false;
9208 g_free(service->name);
9209 service->name = NULL;
9210 service->hidden = true;
9213 service->strength = connman_network_get_strength(network);
9214 service->roaming = connman_network_get_bool(network, "Roaming");
9216 if (service->strength == 0) {
9218 * Filter out 0-values; it's unclear what they mean
9219 * and they cause anomalous sorting of the priority list.
9221 service->strength = strength;
9224 str = connman_network_get_string(network, "WiFi.Security");
9225 service->security = convert_wifi_security(str);
9227 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
9228 update_wps_values(service, network);
9230 if (service->strength > strength && service->network) {
9231 connman_network_unref(service->network);
9232 service->network = connman_network_ref(network);
9234 strength_changed(service);
9237 if (!service->network)
9238 service->network = connman_network_ref(network);
9240 service_list_sort();
9244 * __connman_service_create_from_network:
9245 * @network: network structure
9247 * Look up service by network and if not found, create one
9249 struct connman_service * __connman_service_create_from_network(struct connman_network *network)
9251 struct connman_service *service;
9252 struct connman_device *device;
9253 const char *ident, *group;
9255 unsigned int *auto_connect_types, *favorite_types;
9258 DBG("network %p", network);
9263 ident = __connman_network_get_ident(network);
9267 group = connman_network_get_group(network);
9271 name = g_strdup_printf("%s_%s_%s",
9272 __connman_network_get_type(network), ident, group);
9273 service = service_get(name);
9279 if (__connman_network_get_weakness(network))
9282 if (service->path) {
9283 update_from_network(service, network);
9284 __connman_connection_update_gateway();
9288 service->type = convert_network_type(network);
9290 auto_connect_types = connman_setting_get_uint_list("DefaultAutoConnectTechnologies");
9291 service->autoconnect = false;
9292 for (i = 0; auto_connect_types &&
9293 auto_connect_types[i] != 0; i++) {
9294 if (service->type == auto_connect_types[i]) {
9295 service->autoconnect = true;
9300 favorite_types = connman_setting_get_uint_list("DefaultFavoriteTechnologies");
9301 service->favorite = false;
9302 for (i = 0; favorite_types && favorite_types[i] != 0; i++) {
9303 if (service->type == favorite_types[i]) {
9304 service->favorite = true;
9309 service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
9310 service->state = combine_state(service->state_ipv4, service->state_ipv6);
9312 update_from_network(service, network);
9314 index = connman_network_get_index(network);
9316 if (!service->ipconfig_ipv4)
9317 service->ipconfig_ipv4 = create_ip4config(service, index,
9318 CONNMAN_IPCONFIG_METHOD_DHCP);
9320 if (!service->ipconfig_ipv6)
9321 service->ipconfig_ipv6 = create_ip6config(service, index);
9323 service_register(service);
9324 service_schedule_added(service);
9326 if (service->favorite) {
9327 device = connman_network_get_device(service->network);
9328 if (device && !connman_device_get_scanning(device,
9329 CONNMAN_SERVICE_TYPE_UNKNOWN)) {
9331 switch (service->type) {
9332 case CONNMAN_SERVICE_TYPE_UNKNOWN:
9333 case CONNMAN_SERVICE_TYPE_SYSTEM:
9334 case CONNMAN_SERVICE_TYPE_P2P:
9335 #if defined TIZEN_EXT_WIFI_MESH
9336 case CONNMAN_SERVICE_TYPE_MESH:
9340 case CONNMAN_SERVICE_TYPE_GADGET:
9341 case CONNMAN_SERVICE_TYPE_ETHERNET:
9342 if (service->autoconnect) {
9343 __connman_service_connect(service,
9344 CONNMAN_SERVICE_CONNECT_REASON_AUTO);
9349 case CONNMAN_SERVICE_TYPE_BLUETOOTH:
9350 case CONNMAN_SERVICE_TYPE_GPS:
9351 case CONNMAN_SERVICE_TYPE_VPN:
9352 case CONNMAN_SERVICE_TYPE_WIFI:
9353 case CONNMAN_SERVICE_TYPE_CELLULAR:
9354 __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
9359 #if defined TIZEN_EXT
9360 /* TIZEN synchronizes below information when the service creates */
9361 if (service->eap != NULL)
9362 connman_network_set_string(service->network, "WiFi.EAP",
9364 if (service->identity != NULL)
9365 connman_network_set_string(service->network, "WiFi.Identity",
9367 if (service->phase2 != NULL)
9368 connman_network_set_string(service->network, "WiFi.Phase2",
9370 if (service->eap != NULL)
9371 connman_network_set_string(service->network, "WiFi.Connector",
9372 service->connector);
9373 if (service->identity != NULL)
9374 connman_network_set_string(service->network, "WiFi.CSignKey",
9375 service->c_sign_key);
9376 if (service->phase2 != NULL)
9377 connman_network_set_string(service->network, "WiFi.NetAccessKey",
9378 service->net_access_key);
9382 __connman_notifier_service_add(service, service->name);
9387 #if defined TIZEN_EXT
9388 void __connman_service_notify_strength_changed(struct connman_network *network)
9390 struct connman_service *service;
9391 uint8_t strength = 0;
9393 service = connman_service_lookup_from_network(network);
9397 if (!service->network)
9400 strength = connman_network_get_strength(service->network);
9401 if (strength == service->strength)
9404 service->strength = strength;
9405 DBG("Strength %d", strength);
9406 strength_changed(service);
9407 service_list_sort();
9411 void __connman_service_update_from_network(struct connman_network *network)
9413 bool need_sort = false;
9414 struct connman_service *service;
9420 service = connman_service_lookup_from_network(network);
9424 if (!service->network)
9427 #if defined TIZEN_EXT
9428 if (service->storage_reload) {
9429 service_load(service);
9430 __connman_service_set_storage_reload(service, false);
9434 name = connman_network_get_string(service->network, "Name");
9435 if (g_strcmp0(service->name, name) != 0) {
9436 g_free(service->name);
9437 service->name = g_strdup(name);
9439 if (allow_property_changed(service))
9440 connman_dbus_property_changed_basic(service->path,
9441 CONNMAN_SERVICE_INTERFACE, "Name",
9442 DBUS_TYPE_STRING, &service->name);
9445 if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
9446 update_wps_values(service, network);
9448 strength = connman_network_get_strength(service->network);
9449 if (strength == service->strength)
9452 service->strength = strength;
9455 strength_changed(service);
9458 roaming = connman_network_get_bool(service->network, "Roaming");
9459 if (roaming == service->roaming)
9462 stats_enable = stats_enabled(service);
9464 stats_stop(service);
9466 service->roaming = roaming;
9470 stats_start(service);
9472 roaming_changed(service);
9476 service_list_sort();
9480 void __connman_service_remove_from_network(struct connman_network *network)
9482 struct connman_service *service;
9484 service = connman_service_lookup_from_network(network);
9486 DBG("network %p service %p", network, service);
9491 service->ignore = true;
9493 __connman_connection_gateway_remove(service,
9494 CONNMAN_IPCONFIG_TYPE_ALL);
9496 connman_service_unref(service);
9500 * __connman_service_create_from_provider:
9501 * @provider: provider structure
9503 * Look up service by provider and if not found, create one
9505 struct connman_service *
9506 __connman_service_create_from_provider(struct connman_provider *provider)
9508 struct connman_service *service;
9509 const char *ident, *str;
9511 int index = connman_provider_get_index(provider);
9513 DBG("provider %p", provider);
9515 ident = __connman_provider_get_ident(provider);
9519 name = g_strdup_printf("vpn_%s", ident);
9520 service = service_get(name);
9526 service->type = CONNMAN_SERVICE_TYPE_VPN;
9527 service->order = service->do_split_routing ? 0 : 10;
9528 service->provider = connman_provider_ref(provider);
9529 service->autoconnect = false;
9530 service->favorite = true;
9532 service->state_ipv4 = service->state_ipv6 = CONNMAN_SERVICE_STATE_IDLE;
9533 service->state = combine_state(service->state_ipv4, service->state_ipv6);
9535 str = connman_provider_get_string(provider, "Name");
9537 g_free(service->name);
9538 service->name = g_strdup(str);
9539 service->hidden = false;
9541 g_free(service->name);
9542 service->name = NULL;
9543 service->hidden = true;
9546 service->strength = 0;
9548 if (!service->ipconfig_ipv4)
9549 service->ipconfig_ipv4 = create_ip4config(service, index,
9550 CONNMAN_IPCONFIG_METHOD_MANUAL);
9552 if (!service->ipconfig_ipv6)
9553 service->ipconfig_ipv6 = create_ip6config(service, index);
9555 service_register(service);
9557 __connman_notifier_service_add(service, service->name);
9558 service_schedule_added(service);
9563 static void remove_unprovisioned_services(void)
9566 GKeyFile *keyfile, *configkeyfile;
9567 char *file, *section;
9570 services = connman_storage_get_services();
9574 for (; services[i]; i++) {
9575 file = section = NULL;
9576 keyfile = configkeyfile = NULL;
9578 keyfile = connman_storage_load_service(services[i]);
9582 file = g_key_file_get_string(keyfile, services[i],
9583 "Config.file", NULL);
9587 section = g_key_file_get_string(keyfile, services[i],
9588 "Config.ident", NULL);
9592 configkeyfile = __connman_storage_load_config(file);
9593 if (!configkeyfile) {
9595 * Config file is missing, remove the provisioned
9598 __connman_storage_remove_service(services[i]);
9602 if (!g_key_file_has_group(configkeyfile, section))
9604 * Config section is missing, remove the provisioned
9607 __connman_storage_remove_service(services[i]);
9611 g_key_file_free(keyfile);
9614 g_key_file_free(configkeyfile);
9620 g_strfreev(services);
9623 static int agent_probe(struct connman_agent *agent)
9625 DBG("agent %p", agent);
9629 static void agent_remove(struct connman_agent *agent)
9631 DBG("agent %p", agent);
9634 static void *agent_context_ref(void *context)
9636 struct connman_service *service = context;
9638 return (void *)connman_service_ref(service);
9641 static void agent_context_unref(void *context)
9643 struct connman_service *service = context;
9645 connman_service_unref(service);
9648 static struct connman_agent_driver agent_driver = {
9650 .interface = CONNMAN_AGENT_INTERFACE,
9651 .probe = agent_probe,
9652 .remove = agent_remove,
9653 .context_ref = agent_context_ref,
9654 .context_unref = agent_context_unref,
9657 int __connman_service_init(void)
9663 err = connman_agent_driver_register(&agent_driver);
9665 connman_error("Cannot register agent driver for %s",
9670 set_always_connecting_technologies();
9672 connection = connman_dbus_get_connection();
9674 service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
9675 NULL, service_free);
9677 services_notify = g_new0(struct _services_notify, 1);
9678 services_notify->remove = g_hash_table_new_full(g_str_hash,
9679 g_str_equal, g_free, NULL);
9680 services_notify->add = g_hash_table_new(g_str_hash, g_str_equal);
9682 remove_unprovisioned_services();
9687 void __connman_service_cleanup(void)
9691 if (vpn_autoconnect_id) {
9692 g_source_remove(vpn_autoconnect_id);
9693 vpn_autoconnect_id = 0;
9696 if (autoconnect_id != 0) {
9697 g_source_remove(autoconnect_id);
9701 connman_agent_driver_unregister(&agent_driver);
9703 g_list_free(service_list);
9704 service_list = NULL;
9706 g_hash_table_destroy(service_hash);
9707 service_hash = NULL;
9709 g_slist_free(counter_list);
9710 counter_list = NULL;
9712 if (services_notify->id != 0) {
9713 g_source_remove(services_notify->id);
9714 service_send_changed(NULL);
9717 g_hash_table_destroy(services_notify->remove);
9718 g_hash_table_destroy(services_notify->add);
9719 g_free(services_notify);
9721 dbus_connection_unref(connection);