#include <connman/setting.h>
#include <connman/agent.h>
+#include "src/shared/util.h"
+
#include "connman.h"
#define CONNECT_TIMEOUT 120
#if defined TIZEN_EXT
#define WIFI_BSSID_STR_LEN 18
#define MAX_WIFI_PROFILES 200
-#endif
-#if defined TIZEN_EXT
#define FREQ_RANGE_24GHZ_CHANNEL_1 2412
#define FREQ_RANGE_24GHZ_CHANNEL_14 2484
#define FREQ_RANGE_5GHZ_CHANNEL_32 5160
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
#endif
+#define VPN_AUTOCONNECT_TIMEOUT_DEFAULT 1
+#define VPN_AUTOCONNECT_TIMEOUT_STEP 30
+#define VPN_AUTOCONNECT_TIMEOUT_ATTEMPTS_THRESHOLD 270
static DBusConnection *connection = NULL;
gchar *profile_name;
};
-#endif
-
-#if defined TIZEN_EXT
enum connman_ins_preferred_freq {
CONNMAN_INS_PREFERRED_FREQ_UNKNOWN,
CONNMAN_INS_PREFERRED_FREQ_24GHZ,
bool hidden;
bool ignore;
bool autoconnect;
- GTimeVal modified;
+ struct timeval modified;
unsigned int order;
char *name;
char *passphrase;
int disconnect_reason;
int assoc_status_code;
/*
- * Only for EAP-FAST
+ * Only for EAP-FAST and EAP-PEAP in EAPoL.
*/
char *phase1;
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+ /*
+ * Only for EAP-FAST
+ */
+ char *pac_file;
+#endif
/*
* Description: To indicate that disconnection triggered by user.
*/
char *connector;
char *c_sign_key;
char *net_access_key;
-#endif
-#if defined TIZEN_EXT
unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
bool is_internet_connection;
int assoc_reject_count;
static struct connman_ipconfig *create_ip6config(struct connman_service *service,
int index);
static void dns_changed(struct connman_service *service);
+static void vpn_auto_connect(void);
struct find_data {
const char *path;
char *bssid;
GSList *reject_time_list;
};
-#endif
-#if defined TIZEN_EXT
/*
* Public APIs to use user_pdn_connection_refcount
*/
str = g_key_file_get_string(keyfile,
service->identifier, "Modified", NULL);
if (str) {
- g_time_val_from_iso8601(str, &service->modified);
+ util_iso8601_to_timeval(str, &service->modified);
g_free(str);
}
return 0;
}
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+static void __connman_service_cleanup_8021x(struct connman_service *service)
+{
+ if (service == NULL)
+ return;
+
+ DBG("service %p ", service);
+
+ __connman_service_set_string(service, "EAP", NULL);
+ __connman_service_set_string(service, "Identity", NULL);
+ __connman_service_set_string(service, "Passphrase", NULL);
+ __connman_service_set_string(service, "AnonymousIdentity", NULL);
+ __connman_service_set_string(service, "CACertFile", NULL);
+ __connman_service_set_string(service, "ClientCertFile", NULL);
+ __connman_service_set_string(service, "PrivateKeyFile", NULL);
+ __connman_service_set_string(service, "PrivateKeyPassphrase", NULL);
+ __connman_service_set_string(service, "Phase1", NULL);
+ __connman_service_set_string(service, "Phase2", NULL);
+ __connman_service_set_string(service, "PacFile", NULL);
+}
+
+static int connman_service_set_eapol_property(struct connman_service *service,
+ DBusMessageIter *array)
+{
+ DBusMessageIter dict;
+ char *str = NULL;
+
+ __connman_service_cleanup_8021x(service);
+
+ if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
+ return -EINVAL;
+
+ dbus_message_iter_recurse(array, &dict);
+
+ while(dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry, value;
+ const char *key;
+ int type;
+
+ dbus_message_iter_recurse(&dict, &entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&entry, &key);
+ dbus_message_iter_next(&entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+ return -EINVAL;
+
+ dbus_message_iter_recurse(&entry, &value);
+
+ type = dbus_message_iter_get_arg_type(&value);
+
+ if (g_str_equal(key, "UseEapol")) {
+ dbus_bool_t use_eapol;
+
+ if (type != DBUS_TYPE_BOOLEAN)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &use_eapol);
+ service->use_eapol = use_eapol;
+
+ } else if (g_str_equal(key, "EAP")) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &str);
+ __connman_service_set_string(service, "EAP", str);
+
+ } else if (g_str_equal(key, "Identity")) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &str);
+ __connman_service_set_string(service, "Identity", str);
+
+ } else if (g_str_equal(key, "AnonymousIdentity")) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &str);
+ __connman_service_set_string(service, "AnonymousIdentity", str);
+
+ } else if (g_str_equal(key, "CACertFile")) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &str);
+ __connman_service_set_string(service, "CACertFile", str);
+ } else if (g_str_equal(key, "ClientCertFile")) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &str);
+ __connman_service_set_string(service, "ClientCertFile", str);
+ } else if (g_str_equal(key, "PrivateKeyFile")) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &str);
+ __connman_service_set_string(service, "PrivateKeyFile", str);
+ } else if (g_str_equal(key, "PrivateKeyPassphrase")) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &str);
+ __connman_service_set_string(service, "PrivateKeyPassphrase", str);
+ } else if (g_str_equal(key, "Phase2")) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &str);
+ __connman_service_set_string(service, "Phase2", str);
+ } else if (g_str_equal(key, "Phase1")) {
+ int val;
+ char phase1[5] = {0,};
+
+ if (type != DBUS_TYPE_INT32)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &val);
+ sprintf(phase1, "%d", val);
+ __connman_service_set_string(service, "Phase1", phase1);
+ } else if (g_str_equal(key, "PacFile")) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&value, &str);
+ __connman_service_set_string(service, "PacFile", str);
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ return 0;
+}
+#endif
+
#if defined TIZEN_EXT
static void save_assoc_reject(gpointer key, gpointer value, gpointer user_data)
{
int i;
int err = 0;
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
DBG("service %p", service);
if (!service->network)
if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
return -EINVAL;
- keyfile = __connman_storage_open_service(service->identifier);
+ keyfile = g_key_file_new();
if (!keyfile)
return -EIO;
#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
bool use_eapol;
#endif
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
DBG("service %p", service);
keyfile = connman_storage_load_service(service->identifier);
str = g_key_file_get_string(keyfile,
service->identifier, "Modified", NULL);
if (str) {
- g_time_val_from_iso8601(str, &service->modified);
+ util_iso8601_to_timeval(str, &service->modified);
g_free(str);
}
service->identifier, "Hidden", NULL);
#if defined TIZEN_EXT
- if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
- service->security == CONNMAN_SERVICE_SECURITY_8021X) {
+ if ((service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ service->security == CONNMAN_SERVICE_SECURITY_8021X)
+#if defined TIZEN_EXT_EAP_ON_ETHERNET
+ || (service->type == CONNMAN_SERVICE_TYPE_ETHERNET && service->use_eapol)
+#endif
+ ) {
str = g_key_file_get_string(keyfile,
service->identifier, "EAP", NULL);
if (str != NULL) {
service->identity = str;
}
+#if defined TIZEN_EXT_EAP_ON_ETHERNET
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "AnonymousIdentity", NULL);
+ if (str != NULL) {
+ g_free(service->anonymous_identity);
+ service->anonymous_identity = str;
+ }
+#endif
str = g_key_file_get_string(keyfile,
service->identifier, "CACertFile", NULL);
if (str != NULL) {
g_free(service->private_key_passphrase);
service->private_key_passphrase = str;
}
+
+#if defined TIZEN_EXT_EAP_ON_ETHERNET
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "Phase1", NULL);
+ if (str != NULL) {
+ g_free(service->phase1);
+ service->phase1 = str;
+ }
+
+ str = g_key_file_get_string(keyfile,
+ service->identifier, "PacFile", NULL);
+ if (str != NULL) {
+ g_free(service->pac_file);
+ service->pac_file = str;
+ }
+#endif
}
#endif
#if defined TIZEN_EXT
if (service->new_service)
return -ESRCH;
- keyfile = __connman_storage_open_service(service->identifier);
+ keyfile = g_key_file_new();
if (!keyfile)
return -EIO;
g_key_file_set_boolean(keyfile, service->identifier,
"Favorite", service->favorite);
- g_key_file_remove_key(keyfile, service->identifier,
- "Failure", NULL);
-
/* fall through */
case CONNMAN_SERVICE_TYPE_ETHERNET:
break;
}
- str = g_time_val_to_iso8601(&service->modified);
+ str = util_timeval_to_iso8601(&service->modified);
if (str) {
g_key_file_set_string(keyfile, service->identifier,
- "Modified", str);
+ "Modified", str);
g_free(str);
}
if (service->passphrase && strlen(service->passphrase) > 0)
g_key_file_set_string(keyfile, service->identifier,
- "Passphrase", service->passphrase);
- else
- g_key_file_remove_key(keyfile, service->identifier,
- "Passphrase", NULL);
+ "Passphrase", service->passphrase);
if (service->ipconfig_ipv4)
__connman_ipconfig_save(service->ipconfig_ipv4, keyfile,
- service->identifier, "IPv4.");
+ service->identifier, "IPv4.");
if (service->ipconfig_ipv6)
__connman_ipconfig_save(service->ipconfig_ipv6, keyfile,
- service->identifier, "IPv6.");
+ service->identifier, "IPv6.");
if (service->nameservers_config) {
guint len = g_strv_length(service->nameservers_config);
g_key_file_set_string_list(keyfile, service->identifier,
- "Nameservers",
+ "Nameservers",
(const gchar **) service->nameservers_config, len);
- } else
- g_key_file_remove_key(keyfile, service->identifier,
- "Nameservers", NULL);
+ }
#if defined TIZEN_EXT
if(service->dns_config_method_ipv4 != 0) {
guint len = g_strv_length(service->timeservers_config);
g_key_file_set_string_list(keyfile, service->identifier,
- "Timeservers",
+ "Timeservers",
(const gchar **) service->timeservers_config, len);
- } else
- g_key_file_remove_key(keyfile, service->identifier,
- "Timeservers", NULL);
+ }
if (service->domains) {
guint len = g_strv_length(service->domains);
g_key_file_set_string_list(keyfile, service->identifier,
- "Domains",
+ "Domains",
(const gchar **) service->domains, len);
- } else
- g_key_file_remove_key(keyfile, service->identifier,
- "Domains", NULL);
+ }
cst_str = proxymethod2string(service->proxy_config);
if (cst_str)
g_key_file_set_string_list(keyfile, service->identifier,
"Proxy.Servers",
(const gchar **) service->proxies, len);
- } else
- g_key_file_remove_key(keyfile, service->identifier,
- "Proxy.Servers", NULL);
+ }
if (service->excludes) {
guint len = g_strv_length(service->excludes);
g_key_file_set_string_list(keyfile, service->identifier,
"Proxy.Excludes",
(const gchar **) service->excludes, len);
- } else
- g_key_file_remove_key(keyfile, service->identifier,
- "Proxy.Excludes", NULL);
+ }
if (service->pac && strlen(service->pac) > 0)
g_key_file_set_string(keyfile, service->identifier,
- "Proxy.URL", service->pac);
- else
- g_key_file_remove_key(keyfile, service->identifier,
- "Proxy.URL", NULL);
+ "Proxy.URL", service->pac);
if (service->mdns_config)
g_key_file_set_boolean(keyfile, service->identifier,
- "mDNS", TRUE);
- else
- g_key_file_remove_key(keyfile, service->identifier,
- "mDNS", NULL);
+ "mDNS", TRUE);
if (service->hidden_service)
g_key_file_set_boolean(keyfile, service->identifier, "Hidden",
"Config.ident", service->config_entry);
#if defined TIZEN_EXT
- if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
- service->security == CONNMAN_SERVICE_SECURITY_8021X) {
+ if ((service->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ service->security == CONNMAN_SERVICE_SECURITY_8021X)
+#if defined TIZEN_EXT_EAP_ON_ETHERNET
+ || (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
+#endif
+ ) {
if (service->eap != NULL && strlen(service->eap) > 0)
g_key_file_set_string(keyfile, service->identifier,
"EAP", service->eap);
else
g_key_file_remove_key(keyfile, service->identifier,
"Identity", NULL);
+#if defined TIZEN_EXT_EAP_ON_ETHERNET
+ if (service->anonymous_identity != NULL && strlen(service->anonymous_identity) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "AnonymousIdentity", service->anonymous_identity);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "AnonymousIdentity", NULL);
+#endif
if (service->ca_cert_file != NULL && strlen(service->ca_cert_file) > 0)
g_key_file_set_string(keyfile, service->identifier,
else
g_key_file_remove_key(keyfile, service->identifier,
"PrivateKeyPassphrase", NULL);
+#if defined TIZEN_EXT_EAP_ON_ETHERNET
+ if (service->phase1 != NULL && strlen(service->phase1) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "Phase1", service->phase1);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "Phase1", NULL);
+ if (service->pac_file != NULL && strlen(service->pac_file) > 0)
+ g_key_file_set_string(keyfile, service->identifier,
+ "PacFile", service->pac_file);
+ else
+ g_key_file_remove_key(keyfile, service->identifier,
+ "PacFile", NULL);
+#endif
}
+
if (service->type == CONNMAN_SERVICE_TYPE_WIFI &&
service->security == CONNMAN_SERVICE_SECURITY_DPP) {
if (service->connector != NULL && strlen(service->connector) > 0)
else
nameservers = service->nameservers;
- for (i = 0; nameservers && nameservers[i]; i++)
-#if defined TIZEN_EXT
- {
- DBG("nameservers[%d] %s, nameserver %s", i, nameservers[i], nameserver);
-#endif
- if (g_strcmp0(nameservers[i], nameserver) == 0)
- return -EEXIST;
+ if (nameservers) {
+ for (i = 0; nameservers[i]; i++) {
#if defined TIZEN_EXT
- }
+ DBG("nameservers[%d] %s, nameserver %s", i, nameservers[i], nameserver);
#endif
+ if (g_strcmp0(nameservers[i], nameserver) == 0)
+ return -EEXIST;
+ }
- if (nameservers) {
len = g_strv_length(nameservers);
nameservers = g_try_renew(char *, nameservers, len + 2);
} else {
nameserver_del_routes(index, service->nameservers, type);
}
+static bool check_proxy_setup(struct connman_service *service)
+{
+ /*
+ * We start WPAD if we haven't got a PAC URL from DHCP and
+ * if our proxy manual configuration is either empty or set
+ * to AUTO with an empty URL.
+ */
+
+ if (service->proxy != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN)
+ return true;
+
+ if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN &&
+ (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_AUTO ||
+ service->pac))
+ return true;
+
+ if (__connman_wpad_start(service) < 0) {
+ service->proxy = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
+ __connman_notifier_proxy_changed(service);
+ return true;
+ }
+
+ return false;
+}
+
+static void cancel_online_check(struct connman_service *service)
+{
+ if (service->online_timeout == 0)
+ return;
+
+ g_source_remove(service->online_timeout);
+ service->online_timeout = 0;
+ connman_service_unref(service);
+}
+
+static void start_online_check(struct connman_service *service,
+ enum connman_ipconfig_type type)
+{
+ if (!connman_setting_get_bool("EnableOnlineCheck")) {
+ connman_info("Online check disabled. "
+ "Default service remains in READY state.");
+ return;
+ }
+
+ if (type != CONNMAN_IPCONFIG_TYPE_IPV4 || check_proxy_setup(service)) {
+ cancel_online_check(service);
+ __connman_service_wispr_start(service, type);
+ }
+}
+
static void address_updated(struct connman_service *service,
enum connman_ipconfig_type type)
{
service == connman_service_get_default()) {
nameserver_remove_all(service, type);
nameserver_add_all(service, type);
+ start_online_check(service, type);
__connman_timeserver_sync(service);
}
static void default_changed(void)
{
+#if defined TIZEN_EXT
+ struct connman_service *service = connman_service_get_default_connection();
+#else
struct connman_service *service = connman_service_get_default();
+#endif
if (service == current_default)
return;
if (service->domainname &&
connman_setting_get_bool("AllowDomainnameUpdates"))
__connman_utsname_set_domainname(service->domainname);
+
+ /*
+ * Connect VPN automatically when new default service
+ * is set and connected, unless new default is VPN
+ */
+ if (is_connected(service->state) &&
+ service->type != CONNMAN_SERVICE_TYPE_VPN) {
+ DBG("running vpn_auto_connect");
+ vpn_auto_connect();
+ }
}
__connman_notifier_default_changed(service);
}
+#if defined TIZEN_EXT
+static void append_struct(gpointer value, gpointer user_data);
+
+static void emit_state_changed_with_properties(struct connman_service *service)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter;
+
+ if (!service)
+ return;
+
+ signal = dbus_message_new_signal(service->path, CONNMAN_SERVICE_INTERFACE,
+ "StateChangedProperties");
+ if (!signal)
+ return;
+
+ dbus_message_iter_init_append(signal, &iter);
+ append_struct(service, &iter);
+
+ g_dbus_send_message(connection, signal);
+
+ return;
+}
+#endif
+
static void state_changed(struct connman_service *service)
{
const char *str;
#if !defined TIZEN_EXT
if (!allow_property_changed(service))
return;
-
-#endif
-#if defined TIZEN_EXT
+#else
DBG(" %s, %s", str, service->path);
#endif
+
connman_dbus_property_changed_basic(service->path,
CONNMAN_SERVICE_INTERFACE, "State",
DBUS_TYPE_STRING, &str);
+
+#if defined TIZEN_EXT
+ emit_state_changed_with_properties(service);
+#endif
}
#if defined TIZEN_EXT
}
#endif
-#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
-static void use_eapol_changed(struct connman_service *service)
-{
- dbus_bool_t use_eapol;
-
- if (!service->path)
- return;
-
- if (!allow_property_changed(service))
- return;
-
- use_eapol = service->use_eapol;
- connman_dbus_property_changed_basic(service->path,
- CONNMAN_SERVICE_INTERFACE,
- "UseEapol",
- DBUS_TYPE_BOOLEAN,
- &use_eapol);
-}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
-
static void strength_changed(struct connman_service *service)
{
if (service->strength == 0)
DBUS_TYPE_BOOLEAN, &autoconnect);
}
+bool connman_service_set_autoconnect(struct connman_service *service,
+ bool autoconnect)
+{
+ if (service->autoconnect == autoconnect)
+ return false;
+
+ service->autoconnect = autoconnect;
+ autoconnect_changed(service);
+
+ return true;
+}
+
static void append_security(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
iter);
}
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+static void append_eap_over_ethernet(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_service *service = user_data;
+ dbus_bool_t val;
+
+ val = service->use_eapol;
+ connman_dbus_dict_append_basic(iter, "UseEapol",
+ DBUS_TYPE_BOOLEAN, &val);
+ if (service->use_eapol) {
+ if (service->eap)
+ connman_dbus_dict_append_basic(iter, "EAP",
+ DBUS_TYPE_STRING, &service->eap);
+
+ if (service->identity)
+ connman_dbus_dict_append_basic(iter, "Identity",
+ DBUS_TYPE_STRING, &service->identity);
+
+ if (service->anonymous_identity)
+ connman_dbus_dict_append_basic(iter, "AnonymousIdentity",
+ DBUS_TYPE_STRING, &service->anonymous_identity);
+
+ if (service->ca_cert_file)
+ connman_dbus_dict_append_basic(iter, "CACertFile",
+ DBUS_TYPE_STRING, &service->ca_cert_file);
+
+ if (service->client_cert_file)
+ connman_dbus_dict_append_basic(iter, "ClientCertFile",
+ DBUS_TYPE_STRING, &service->client_cert_file);
+
+ if (service->private_key_file)
+ connman_dbus_dict_append_basic(iter, "PrivateKeyFile",
+ DBUS_TYPE_STRING, &service->private_key_file);
+
+ if (service->phase2)
+ connman_dbus_dict_append_basic(iter, "Phase2",
+ DBUS_TYPE_STRING, &service->phase2);
+
+ if (service->phase1)
+ connman_dbus_dict_append_basic(iter, "Phase1",
+ DBUS_TYPE_STRING, &service->phase1);
+
+ if (service->pac_file)
+ connman_dbus_dict_append_basic(iter, "PacFile",
+ DBUS_TYPE_STRING, &service->pac_file);
+
+ /* Should we include passphrase? */
+ }
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
static void append_ipv4(DBusMessageIter *iter, void *user_data)
{
struct connman_service *service = user_data;
connman_dbus_dict_append_basic(dict, "AssocStatusCode",
DBUS_TYPE_INT32, &service->assoc_status_code);
+ val = service->hidden_service;
connman_dbus_dict_append_basic(dict, "Hidden",
- DBUS_TYPE_BOOLEAN, &service->hidden_service);
+ DBUS_TYPE_BOOLEAN, &val);
break;
#endif
case CONNMAN_SERVICE_TYPE_ETHERNET:
#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
- val = service->use_eapol;
- connman_dbus_dict_append_basic(dict, "UseEapol",
- DBUS_TYPE_BOOLEAN, &val);
+ connman_dbus_dict_append_dict(dict, "EapOverEthernet",
+ append_eap_over_ethernet, service);
+ /* fall through */
#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
case CONNMAN_SERVICE_TYPE_BLUETOOTH:
case CONNMAN_SERVICE_TYPE_GADGET:
return service->is_internet_connection;
}
+
+DBusMessage *connman_service_get_defaut_info(DBusMessage *msg,
+ struct connman_service *service)
+{
+ DBusMessage *reply;
+ DBusMessageIter array, dict;
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &array);
+
+ if (service)
+ dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH,
+ &service->path);
+
+ connman_dbus_dict_open(&array, &dict);
+ if (service)
+ append_properties(&dict, FALSE, service);
+ connman_dbus_dict_close(&array, &dict);
+
+ return reply;
+}
#endif
void __connman_service_set_proxy_autoconfig(struct connman_service *service,
return service->use_eapol;
}
+
+int __connman_service_get_connect_reason(struct connman_service *service)
+{
+ if (!service) {
+ DBG("Service is NULL");
+ return -1;
+ }
+
+ return service->connect_reason;
+}
#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
static DBusMessage *get_properties(DBusConnection *conn,
return -EINVAL;
}
+static void do_auto_connect(struct connman_service *service,
+ enum connman_service_connect_reason reason)
+{
+ /*
+ * CONNMAN_SERVICE_CONNECT_REASON_NONE must be ignored for VPNs. VPNs
+ * always have reason CONNMAN_SERVICE_CONNECT_REASON_USER/AUTO.
+ */
+ if (!service || (service->type == CONNMAN_SERVICE_TYPE_VPN &&
+ reason == CONNMAN_SERVICE_CONNECT_REASON_NONE))
+ return;
+
+ /*
+ * Run service auto connect for other than VPN services. Afterwards
+ * start also VPN auto connect process.
+ */
+ if (service->type != CONNMAN_SERVICE_TYPE_VPN)
+ __connman_service_auto_connect(reason);
+ /* Only user interaction should get VPN connected in failure state. */
+ else if (service->state == CONNMAN_SERVICE_STATE_FAILURE &&
+ reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
+ return;
+
+ vpn_auto_connect();
+}
+
int __connman_service_reset_ipconfig(struct connman_service *service,
enum connman_ipconfig_type type, DBusMessageIter *array,
enum connman_service_state *new_state)
settings_changed(service, new_ipconfig);
address_updated(service, type);
- __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+ do_auto_connect(service, CONNMAN_SERVICE_CONNECT_REASON_AUTO);
}
DBG("err %d ipconfig %p type %d method %d state %s", err,
__connman_wispr_start(service, type);
}
+static void set_error(struct connman_service *service,
+ enum connman_service_error error);
+
static DBusMessage *set_property(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
dbus_message_iter_get_basic(&value, &autoconnect);
- if (service->autoconnect == autoconnect)
- return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-
- service->autoconnect = autoconnect;
-
- autoconnect_changed(service);
+ if (autoconnect && service->type == CONNMAN_SERVICE_TYPE_VPN) {
+ /*
+ * Changing the autoconnect flag on VPN to "on" should
+ * have the same effect as user connecting the VPN =
+ * clear previous error and change state to idle.
+ */
+ set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
- if (autoconnect)
- __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+ if (service->state == CONNMAN_SERVICE_STATE_FAILURE) {
+ service->state = CONNMAN_SERVICE_STATE_IDLE;
+ state_changed(service);
+ }
+ }
- service_save(service);
+ if (connman_service_set_autoconnect(service, autoconnect)) {
+ service_save(service);
+ if (autoconnect)
+ do_auto_connect(service,
+ CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+ }
} else if (g_str_equal(name, "Nameservers.Configuration")) {
DBusMessageIter entry;
GString *str;
__connman_service_set_passphrase(service, passphrase);
#endif
#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
- } else if (g_str_equal(name, "UseEapol")) {
- dbus_bool_t use_eapol;
-
- if (type != DBUS_TYPE_BOOLEAN)
- return __connman_error_invalid_arguments(msg);
-
- dbus_message_iter_get_basic(&value, &use_eapol);
+ } else if (g_str_equal(name, "EapOverEthernet")) {
+ int err = connman_service_set_eapol_property(service, &value);
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
- service->use_eapol = use_eapol;
+ service->connect_reason = CONNMAN_SERVICE_CONNECT_REASON_USER;
service_save(service);
#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
} else
reply_pending(service, EIO);
if (service->connect_reason != CONNMAN_SERVICE_CONNECT_REASON_USER)
- __connman_service_auto_connect(service->connect_reason);
+ do_auto_connect(service, service->connect_reason);
- g_get_current_time(&service->modified);
+ gettimeofday(&service->modified, NULL);
service_save(service);
}
tech_data->preferred_list =
g_list_append(tech_data->preferred_list, service);
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
DBG("type %d service %p %s", tech_data->type, service,
service->name);
}
return false;
}
+static int service_indicate_state(struct connman_service *service);
+
static bool auto_connect_service(GList *services,
enum connman_service_connect_reason reason,
bool preferred)
bool ignore[MAX_CONNMAN_SERVICE_TYPES] = { };
bool autoconnecting = false;
GList *list;
+#if defined TIZEN_EXT
+ GSList *wifi_ignore = NULL;
+#endif
DBG("preferred %d sessions %d reason %s", preferred, active_count,
reason2string(reason));
for (list = services; list; list = list->next) {
service = list->data;
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
+ int index = connman_network_get_index(service->network);
+ if (g_slist_find(wifi_ignore, GINT_TO_POINTER(index)) != NULL)
+ continue;
+ } else
+#endif
if (ignore[service->type]) {
DBG("service %p type %s ignore", service,
__connman_service_type2string(service->type));
if (service->pending ||
is_connecting(service->state) ||
is_connected(service->state)) {
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
+ int index = connman_network_get_index(service->network);
+ wifi_ignore = g_slist_prepend(wifi_ignore, GINT_TO_POINTER(index));
+
+ autoconnecting = true;
+ continue;
+ }
+#else
if (autoconnect_no_session_active(service))
return true;
-
+#endif
ignore[service->type] = true;
autoconnecting = true;
#if defined TIZEN_EXT
DBG("Service is not favorite, autoconnecting %d",
autoconnecting);
+ g_slist_free(wifi_ignore);
#endif
return autoconnecting;
}
if (is_ignore(service) || service->state !=
CONNMAN_SERVICE_STATE_IDLE)
continue;
-
+#if defined TIZEN_EXT
+ if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
+#endif
if (autoconnect_already_connecting(service, autoconnecting)) {
DBG("service %p type %s has no users", service,
__connman_service_type2string(service->type));
DBG("service %p %s %s", service, service->name,
(preferred) ? "preferred" : reason2string(reason));
+#if defined TIZEN_EXT
__connman_service_connect(service, reason);
+#else
+ if (__connman_service_connect(service, reason) == 0)
+ service_indicate_state(service);
if (autoconnect_no_session_active(service))
return true;
-
+#endif
+#if defined TIZEN_EXT
+ if (service->type == CONNMAN_SERVICE_TYPE_WIFI) {
+ int index = connman_network_get_index(service->network);
+ wifi_ignore = g_slist_prepend(wifi_ignore, GINT_TO_POINTER(index));
+ autoconnecting = true;
+ }
+#endif
ignore[service->type] = true;
}
-
+#if defined TIZEN_EXT
+ g_slist_free(wifi_ignore);
+#endif
return autoconnecting;
}
static gboolean run_vpn_auto_connect(gpointer data) {
GList *list;
bool need_split = false;
+ bool autoconnectable_vpns = false;
+ int attempts = 0;
+ int timeout = VPN_AUTOCONNECT_TIMEOUT_DEFAULT;
+ struct connman_service *def_service;
- vpn_autoconnect_id = 0;
+ attempts = GPOINTER_TO_INT(data);
+ def_service = connman_service_get_default();
+
+ /*
+ * Stop auto connecting VPN if there is no transport service or the
+ * transport service is not connected or if the current default service
+ * is a connected VPN (in ready state).
+ */
+ if (!def_service || !is_connected(def_service->state) ||
+ (def_service->type == CONNMAN_SERVICE_TYPE_VPN &&
+ is_connected(def_service->state))) {
+
+ DBG("stopped, default service %s connected %d",
+ def_service ? def_service->identifier : "NULL",
+ def_service ? is_connected(def_service->state) : -1);
+ goto out;
+ }
for (list = service_list; list; list = list->next) {
struct connman_service *service = list->data;
continue;
if (is_connected(service->state) ||
- is_connecting(service->state)) {
+ is_connecting(service->state)) {
if (!service->do_split_routing)
need_split = true;
+
+ /*
+ * If the service is connecting it must be accounted
+ * for to keep the autoconnection in main loop.
+ */
+ if (is_connecting(service->state))
+ autoconnectable_vpns = true;
+
continue;
}
res = __connman_service_connect(service,
CONNMAN_SERVICE_CONNECT_REASON_AUTO);
- if (res < 0 && res != -EINPROGRESS)
+
+ switch (res) {
+ case 0:
+ service_indicate_state(service);
+ /* fall through */
+ case -EINPROGRESS:
+ autoconnectable_vpns = true;
+ break;
+ default:
continue;
+ }
if (!service->do_split_routing)
need_split = true;
}
- return FALSE;
+ /* Stop if there is no VPN to automatically connect.*/
+ if (!autoconnectable_vpns) {
+ DBG("stopping, no autoconnectable VPNs found");
+ goto out;
+ }
+
+ /* Increase the attempt count up to the threshold.*/
+ if (attempts < VPN_AUTOCONNECT_TIMEOUT_ATTEMPTS_THRESHOLD)
+ attempts++;
+
+ /*
+ * Timeout increases with 1s after VPN_AUTOCONNECT_TIMEOUT_STEP amount
+ * of attempts made. After VPN_AUTOCONNECT_TIMEOUT_ATTEMPTS_THRESHOLD is
+ * reached the delay does not increase.
+ */
+ timeout = timeout + (int)(attempts / VPN_AUTOCONNECT_TIMEOUT_STEP);
+
+ /* Re add this to main loop */
+ vpn_autoconnect_id =
+ g_timeout_add_seconds(timeout, run_vpn_auto_connect,
+ GINT_TO_POINTER(attempts));
+
+ DBG("re-added to main loop, next VPN autoconnect in %d seconds (#%d)",
+ timeout, attempts);
+
+ return G_SOURCE_REMOVE;
+
+out:
+ vpn_autoconnect_id = 0;
+ return G_SOURCE_REMOVE;
}
static void vpn_auto_connect(void)
{
- if (vpn_autoconnect_id)
- return;
+ /*
+ * Remove existing autoconnect from main loop to reset the attempt
+ * counter in order to get VPN connected when there is a network change.
+ */
+ if (vpn_autoconnect_id) {
+ if (!g_source_remove(vpn_autoconnect_id))
+ return;
+ }
vpn_autoconnect_id =
g_idle_add(run_vpn_auto_connect, NULL);
if (autoconnect &&
service->connect_reason !=
CONNMAN_SERVICE_CONNECT_REASON_USER)
- __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+ do_auto_connect(service, CONNMAN_SERVICE_CONNECT_REASON_AUTO);
return FALSE;
}
append_struct(service, iter);
g_hash_table_remove(services_notify->add, service->path);
} else {
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
DBG("changed %s", service->path);
append_struct_service(iter, NULL, service);
}
}
- g_get_current_time(&service->modified);
+ gettimeofday(&service->modified, NULL);
service_save(service);
service_save(target);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+static DBusMessage *is_eapol_enabled(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ struct connman_service *service = user_data;
+ DBG("service: %p path: %s UseEapol: %d", service, service->path, service->use_eapol);
+
+ dbus_bool_t eapol_status = service->use_eapol;
+
+ DBusMessage *reply = dbus_message_new_method_return(msg);
+ if (!reply) {
+ DBG("Failed to initialize reply");
+ return NULL;
+ }
+
+ dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &eapol_status, DBUS_TYPE_INVALID);
+ return reply;
+}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+
#if defined TIZEN_MAINTAIN_ONLINE
static DBusMessage *downgrade_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
static void service_schedule_added(struct connman_service *service)
{
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
DBG("service %p", service);
g_hash_table_remove(services_notify->remove, service->path);
GDBUS_ARGS({ "service", "o" }), NULL,
move_after) },
{ GDBUS_METHOD("ResetCounters", NULL, NULL, reset_counters) },
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+ { GDBUS_METHOD("IsEapolEnabled", NULL, GDBUS_ARGS({ "eapol", "b" }), is_eapol_enabled) },
+#endif
#if defined TIZEN_MAINTAIN_ONLINE
{ GDBUS_METHOD("Downgrade", NULL, NULL, downgrade_service) },
#endif
static const GDBusSignalTable service_signals[] = {
{ GDBUS_SIGNAL("PropertyChanged",
GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
+#if defined TIZEN_EXT
+ { GDBUS_SIGNAL("StateChangedProperties",
+ GDBUS_ARGS({ "properties", "a{sv}" })) },
+#endif
{ },
};
g_free(service->phase2);
g_free(service->config_file);
g_free(service->config_entry);
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+ g_free(service->pac_file);
+ g_free(service->phase1);
+#endif
+
#if defined TIZEN_EXT
g_free(service->connector);
g_free(service->c_sign_key);
static void service_initialize(struct connman_service *service)
{
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
DBG("service %p", service);
service->refcount = 1;
struct tm* ref_timeinfo;
device = connman_network_get_device(service->network);
+ if (!device)
+ return 0;
+
last_user_selection_time = connman_device_get_last_user_selection_time(device);
last_user_selection_ident = connman_device_get_last_user_selection_ident(device);
frequency = connman_network_get_frequency(service->network);
a_connected = is_connected(state_a);
b_connected = is_connected(state_b);
+#if defined TIZEN_EXT
+ if ((a_connected && b_connected) &&
+ state_a == state_b &&
+ service_a->type == CONNMAN_SERVICE_TYPE_WIFI &&
+ service_b->type == CONNMAN_SERVICE_TYPE_WIFI) {
+ const char *default_interface =
+ connman_option_get_string("DefaultWifiInterface");
+ const char *ifname_a = connman_device_get_string(
+ connman_network_get_device(service_a->network), "Interface");
+ const char *ifname_b = connman_device_get_string(
+ connman_network_get_device(service_b->network), "Interface");
+
+ if (g_strcmp0(default_interface, ifname_a) == 0)
+ return -1;
+ else if (g_strcmp0(default_interface, ifname_b) == 0)
+ return 1;
+ }
+#endif
+
if (a_connected && b_connected) {
if (service_a->order > service_b->order)
return -1;
service->phase2 = g_strdup(value);
} else if (g_str_equal(key, "Passphrase"))
__connman_service_set_passphrase(service, value);
+#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
+ else if (g_str_equal(key, "Phase1")) {
+ g_free(service->phase1);
+ service->phase1 = g_strdup(value);
+ } else if (g_str_equal(key, "PacFile")) {
+ g_free(service->pac_file);
+ service->pac_file = g_strdup(value);
+ }
+#endif
#if defined TIZEN_EXT
else if (g_str_equal(key, "Connector")) {
g_free(service->connector);
__connman_service_return_error(service,
ECONNABORTED,
user_data);
- goto done;
} else {
+ err = -ETIMEDOUT;
+
if (service->hidden)
__connman_service_return_error(service,
ETIMEDOUT, user_data);
}
+
+ goto done;
}
if (service->hidden && name_len > 0 && name_len <= 32) {
static void __connman_service_disconnect_default(struct connman_service *service)
{
struct connman_device *default_device = NULL;
+ struct connman_network *network = __connman_service_get_network(service);
+
+ if (!network)
+ return;
if (default_connecting_device == NULL)
return;
- default_device = connman_network_get_device(
- __connman_service_get_network(service));
+ default_device = connman_network_get_device(network);
DBG("Disconnecting service %p %s", service, service->path);
DBG("Disconnecting device %p %p %s",
searchdomain_remove_all(service);
service->state = new_state;
+#if defined TIZEN_EXT
+ if (!is_connected(old_state) && is_connected(new_state))
+ connman_device_send_connected_signal(
+ connman_network_get_device(service->network), true);
+ else if (is_connected(old_state) && !is_connected(new_state))
+ connman_device_send_connected_signal(
+ connman_network_get_device(service->network), false);
+#endif
state_changed(service);
if (!is_connected(old_state) && is_connected(new_state))
"WiFi.UseWPS", false);
}
- g_get_current_time(&service->modified);
+ gettimeofday(&service->modified, NULL);
service_save(service);
domain_changed(service);
*/
downgrade_connected_services();
- __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+ do_auto_connect(service, CONNMAN_SERVICE_CONNECT_REASON_AUTO);
break;
case CONNMAN_SERVICE_STATE_FAILURE:
return CONNMAN_SERVICE_STATE_UNKNOWN;
}
-static void check_proxy_setup(struct connman_service *service)
-{
- /*
- * We start WPAD if we haven't got a PAC URL from DHCP and
- * if our proxy manual configuration is either empty or set
- * to AUTO with an empty URL.
- */
-
- if (service->proxy != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN)
- goto done;
-
- if (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_UNKNOWN &&
- (service->proxy_config != CONNMAN_SERVICE_PROXY_METHOD_AUTO ||
- service->pac))
- goto done;
-
- if (__connman_wpad_start(service) < 0) {
- service->proxy = CONNMAN_SERVICE_PROXY_METHOD_DIRECT;
- __connman_notifier_proxy_changed(service);
- goto done;
- }
-
- return;
-
-done:
- __connman_service_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
-}
-
#if defined TIZEN_EXT
void connman_check_proxy_setup_and_wispr_start(struct connman_service *service){
return EAGAIN;
}
-static void cancel_online_check(struct connman_service *service)
-{
- if (service->online_timeout == 0)
- return;
-
- g_source_remove(service->online_timeout);
- service->online_timeout = 0;
- connman_service_unref(service);
-}
-
int __connman_service_ipconfig_indicate_state(struct connman_service *service,
enum connman_service_state new_state,
enum connman_ipconfig_type type)
service = connman_service_create();
if (!service)
return NULL;
-
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
DBG("service %p", service);
service->identifier = g_strdup(identifier);
static int service_register(struct connman_service *service)
{
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
DBG("service %p", service);
if (service->path)
if (ret == -ERANGE)
service_ext_save(service);
ret = __connman_config_provision_service(service);
- if (ret < 0)
+ if (ret < 0 && !simplified_log)
DBG("Failed to provision service");
#else
if (__connman_config_provision_service(service) < 0)
case CONNMAN_SERVICE_TYPE_VPN:
case CONNMAN_SERVICE_TYPE_WIFI:
case CONNMAN_SERVICE_TYPE_CELLULAR:
- __connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+ do_auto_connect(service,
+ CONNMAN_SERVICE_CONNECT_REASON_AUTO);
break;
}
}
return;
service->strength = strength;
- DBG("Strength %d", strength);
+ if (!simplified_log)
+ DBG("Strength %d", strength);
strength_changed(service);
service_list_sort();
}