static unsigned int vpn_autoconnect_id = 0;
static struct connman_service *current_default = NULL;
static bool services_dirty = false;
+static bool enable_online_to_ready_transition = false;
+static unsigned int online_check_initial_interval = 0;
+static unsigned int online_check_max_interval = 0;
#if defined TIZEN_EXT
static bool auto_connect_mode = TRUE;
gchar *profile_name;
};
+static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+#endif
+
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
enum connman_ins_preferred_freq {
CONNMAN_INS_PREFERRED_FREQ_UNKNOWN,
CONNMAN_INS_PREFERRED_FREQ_24GHZ,
};
static struct connman_ins_settings ins_settings;
-
-static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
struct connman_stats {
bool valid;
bool wps;
bool wps_advertizing;
guint online_timeout;
- int online_check_interval_ipv4;
- int online_check_interval_ipv6;
+ unsigned int online_check_interval_ipv4;
+ unsigned int online_check_interval_ipv6;
bool do_split_routing;
bool new_service;
bool hidden_service;
return "auto";
case CONNMAN_SERVICE_CONNECT_REASON_SESSION:
return "session";
+ case CONNMAN_SERVICE_CONNECT_REASON_NATIVE:
+ return "native";
}
return "unknown";
return "login-failed";
case CONNMAN_SERVICE_ERROR_AUTH_FAILED:
return "auth-failed";
+#ifdef TIZEN_EXT
+ case CONNMAN_SERVICE_ERROR_ASSOC_FAILED:
+ return "assoc-failed";
+#endif
case CONNMAN_SERVICE_ERROR_INVALID_KEY:
return "invalid-key";
case CONNMAN_SERVICE_ERROR_BLOCKED:
}
#endif
-static void set_split_routing(struct connman_service *service, bool value)
+void __connman_service_split_routing_changed(struct connman_service *service)
+{
+ dbus_bool_t split_routing;
+
+ if (!service->path)
+ return;
+
+ if (!allow_property_changed(service))
+ return;
+
+ split_routing = service->do_split_routing;
+ if (!connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "SplitRouting",
+ DBUS_TYPE_BOOLEAN, &split_routing))
+ connman_warn("cannot send SplitRouting property change on %s",
+ service->identifier);
+}
+
+void __connman_service_set_split_routing(struct connman_service *service,
+ bool value)
{
if (service->type != CONNMAN_SERVICE_TYPE_VPN)
return;
service->order = 0;
else
service->order = 10;
+
+ /*
+ * In order to make sure the value is propagated also when loading the
+ * VPN service signal the value regardless of the value change.
+ */
+ __connman_service_split_routing_changed(service);
}
int __connman_service_load_modifiable(struct connman_service *service)
#endif
break;
case CONNMAN_SERVICE_TYPE_VPN:
- set_split_routing(service, g_key_file_get_boolean(keyfile,
- service->identifier,
- "SplitRouting", NULL));
+ __connman_service_set_split_routing(service,
+ g_key_file_get_boolean(keyfile,
+ service->identifier,
+ "SplitRouting", NULL));
/* fall through */
case CONNMAN_SERVICE_TYPE_WIFI:
int i;
int err = 0;
-#if defined TIZEN_EXT
if (!simplified_log)
-#endif
- DBG("service %p", service);
+ DBG("service %p", service);
if (!service->network)
return -EINVAL;
#endif
break;
case CONNMAN_SERVICE_TYPE_VPN:
- set_split_routing(service, g_key_file_get_boolean(keyfile,
- service->identifier,
- "SplitRouting", NULL));
+ __connman_service_set_split_routing(service,
+ g_key_file_get_boolean(keyfile,
+ service->identifier,
+ "SplitRouting", NULL));
autoconnect = g_key_file_get_boolean(keyfile,
service->identifier, "AutoConnect", &error);
str = g_key_file_get_string(keyfile,
service->identifier, "Passphrase", NULL);
if (str) {
+ char *dec = g_strcompress(str);
+ g_free(str);
g_free(service->passphrase);
- service->passphrase = str;
+ service->passphrase = dec;
}
if (service->ipconfig_ipv4)
g_free(str);
}
- if (service->passphrase && strlen(service->passphrase) > 0)
+ if (service->passphrase && strlen(service->passphrase) > 0) {
+ char *enc = g_strescape(service->passphrase, NULL);
g_key_file_set_string(keyfile, service->identifier,
- "Passphrase", service->passphrase);
+ "Passphrase", enc);
+ g_free(enc);
+ }
if (service->ipconfig_ipv4)
__connman_ipconfig_save(service->ipconfig_ipv4, keyfile,
"mDNS", TRUE);
if (service->hidden_service)
- g_key_file_set_boolean(keyfile, service->identifier, "Hidden",
- TRUE);
+ g_key_file_set_boolean(keyfile, service->identifier,
+ "Hidden", TRUE);
if (service->config_file && strlen(service->config_file) > 0)
g_key_file_set_string(keyfile, service->identifier,
"Config.file", service->config_file);
- if (service->config_entry &&
- strlen(service->config_entry) > 0)
+ if (service->config_entry && strlen(service->config_entry) > 0)
g_key_file_set_string(keyfile, service->identifier,
"Config.ident", service->config_entry);
__connman_resolver_append_fallback_nameservers();
#if defined TIZEN_EXT
- const char *global_dns = connman_option_get_string("GlobalNameserver");
+ const char *global_dns = connman_setting_get_string("GlobalNameserver");
if (global_dns)
nameserver_add(service, type, global_dns);
#endif
}
#if defined TIZEN_EXT
- const char *global_dns = connman_option_get_string("GlobalNameserver");
+ const char *global_dns = connman_setting_get_string("GlobalNameserver");
if (global_dns)
nameserver_remove(service, type, global_dns);
#endif
"Default service remains in READY state.");
return;
}
+ enable_online_to_ready_transition =
+ connman_setting_get_bool("EnableOnlineToReadyTransition");
+ online_check_initial_interval =
+ connman_setting_get_uint("OnlineCheckInitialInterval");
+ online_check_max_interval =
+ connman_setting_get_uint("OnlineCheckMaxInterval");
if (type != CONNMAN_IPCONFIG_TYPE_IPV4 || check_proxy_setup(service)) {
cancel_online_check(service);
connman_setting_get_bool("AllowDomainnameUpdates"))
__connman_utsname_set_domainname(service->domainname);
+ if (__connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4))
+ __connman_service_wispr_start(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+
+ if (__connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6))
+ __connman_service_wispr_start(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+
/*
* Connect VPN automatically when new default service
* is set and connected, unless new default is VPN
#if defined TIZEN_EXT
static void connect_reason_changed(struct connman_service *service)
{
+#if defined TIZEN_EXT_INS
struct connman_device *device;
-
+#endif
if (!service->path)
return;
if (!allow_property_changed(service))
return;
+#if defined TIZEN_EXT_INS
if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
device = connman_network_get_device(service->network);
if (device) {
connman_device_save_last_user_selection(device);
}
}
+#endif
connman_dbus_property_changed_basic(service->path,
- CONNMAN_SERVICE_INTERFACE,
- "ConnectReason",
- DBUS_TYPE_INT32,
- &service->connect_reason);
+ CONNMAN_SERVICE_INTERFACE,
+ "ConnectReason",
+ DBUS_TYPE_INT32,
+ &service->connect_reason);
}
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#if defined TIZEN_EXT
static void disconnection_requested_changed(struct connman_service *service)
{
dbus_bool_t disconnection_requested;
}
void connman_service_set_disconnection_requested(struct connman_service *service,
- bool disconnection_requested)
+ bool disconnection_requested)
{
if (service == NULL)
return;
service->disconnection_requested = disconnection_requested;
disconnection_requested_changed(service);
}
+
+static void connman_service_emit_state(struct connman_service *service,
+ enum connman_service_state state)
+{
+ const char *str;
+ enum connman_service_state cur_state = service->state;
+
+ if (service->state != state)
+ service->state = state;
+
+ str = state2string(service->state);
+ if (!str) {
+ service->state = cur_state;
+ return;
+ }
+
+ DBG(" %s, %s", str, service->path);
+
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "State",
+ DBUS_TYPE_STRING, &str);
+
+ emit_state_changed_with_properties(service);
+ service->state = cur_state;
+}
+
+void connman_service_notify_reconnection(struct connman_service *service)
+{
+ if (!service)
+ return;
+
+ if (service->state != CONNMAN_SERVICE_STATE_READY &&
+ service->state != CONNMAN_SERVICE_STATE_ONLINE)
+ return;
+
+ connman_service_emit_state(service, CONNMAN_SERVICE_STATE_CONFIGURATION);
+ connman_service_emit_state(service, CONNMAN_SERVICE_STATE_READY);
+
+ if (service->state == CONNMAN_SERVICE_STATE_ONLINE)
+ connman_service_emit_state(service, CONNMAN_SERVICE_STATE_ONLINE);
+}
#endif
static void strength_changed(struct connman_service *service)
service->autoconnect = autoconnect;
autoconnect_changed(service);
+ connman_network_set_autoconnect(service->network, autoconnect);
+
return true;
}
}
#if defined TIZEN_EXT
+static void append_security_list(DBusMessageIter *iter, void *user_data)
+{
+ GSList *sec_list = (GSList *)user_data;
+ const char *sec_str;
+
+ if (sec_list) {
+ GSList *list;
+ for (list = sec_list; list; list = list->next) {
+ sec_str = (const char *)list->data;
+
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &sec_str);
+ }
+ }
+}
+
static void append_wifi_ext_info(DBusMessageIter *dict,
struct connman_network *network)
{
const char *enc_mode;
const char *str;
gboolean passpoint;
+ gboolean pmf_required;
char country_code_buff[WIFI_COUNTRY_CODE_LEN + 1] = {0,};
char *country_code_str = country_code_buff;
unsigned char *country_code;
uint16_t connection_mode;
+ GSList *sec_list = NULL;
ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len);
bssid = connman_network_get_bssid(network);
enc_mode = connman_network_get_enc_mode(network);
passpoint = connman_network_get_bool(network, "WiFi.HS20AP");
keymgmt = connman_network_get_keymgmt(network);
+ pmf_required = connman_network_get_bool(network, "WiFi.PMFRequired");
country_code = connman_network_get_countrycode(network);
connection_mode = connman_network_get_connection_mode(network);
+ sec_list = (GSList *)connman_network_get_sec_list(network);
snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
snprintf(country_code_str, (WIFI_COUNTRY_CODE_LEN + 1), "%c%c",
country_code[0], country_code[1]);
+ connman_dbus_dict_append_array(dict, "SecurityList",
+ DBUS_TYPE_STRING,
+ append_security_list, sec_list);
connman_dbus_dict_append_fixed_array(dict, "SSID",
DBUS_TYPE_BYTE, &ssid, ssid_len);
DBUS_TYPE_BOOLEAN, &passpoint);
connman_dbus_dict_append_basic(dict, "Keymgmt",
DBUS_TYPE_UINT32, &keymgmt);
+ connman_dbus_dict_append_basic(dict, "PmfReq",
+ DBUS_TYPE_BOOLEAN, &pmf_required);
connman_dbus_dict_append_basic(dict, "Country", DBUS_TYPE_STRING,
&country_code_str);
connman_dbus_dict_append_basic(dict, "ConnMode",
connman_network_append_acddbus(dict, service->network);
}
-#if defined TIZEN_EXT_INS
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
static void append_ins_bssid_info(DBusMessageIter *iter, void *user_data)
{
GSList *bssid_list = NULL;
append_ins_bssid_info, service->network);
}
}
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
static void append_struct_service(DBusMessageIter *iter,
connman_dbus_append_cb_t function,
append_struct_service(iter, append_dict_properties, service);
}
-void __connman_service_list_struct(DBusMessageIter *iter)
-{
- g_list_foreach(service_list, append_struct, iter);
-}
-
-#if defined TIZEN_EXT_INS
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
static void append_dict_ins_properties(DBusMessageIter *dict, void *user_data)
{
struct connman_service *service = user_data;
{
g_list_foreach(service_list, append_ins_struct, iter);
}
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+
+void __connman_service_list_struct(DBusMessageIter *iter)
+{
+ g_list_foreach(service_list, append_struct, iter);
+}
bool __connman_service_is_hidden(struct connman_service *service)
{
return;
/*
+ * Only user interaction should get VPN or WIFI connected in failure
+ * state.
+ */
+ if (service->state == CONNMAN_SERVICE_STATE_FAILURE &&
+ reason != CONNMAN_SERVICE_CONNECT_REASON_USER &&
+ (service->type == CONNMAN_SERVICE_TYPE_VPN ||
+ service->type == CONNMAN_SERVICE_TYPE_WIFI))
+ return;
+
+ /*
+ * Do not use the builtin auto connect, instead rely on the
+ * native auto connect feature of the service.
+ */
+ if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_NATIVE)
+ 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();
}
return err;
}
-/*
- * We set the timeout to 1 sec so that we have a chance to get
- * necessary IPv6 router advertisement messages that might have
- * DNS data etc.
- */
-#define ONLINE_CHECK_INITIAL_INTERVAL 1
-#define ONLINE_CHECK_MAX_INTERVAL 12
-
void __connman_service_wispr_start(struct connman_service *service,
enum connman_ipconfig_type type)
{
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
service->online_check_interval_ipv4 =
- ONLINE_CHECK_INITIAL_INTERVAL;
+ online_check_initial_interval;
else
service->online_check_interval_ipv6 =
- ONLINE_CHECK_INITIAL_INTERVAL;
+ online_check_initial_interval;
__connman_wispr_start(service, type);
}
service_save(service);
timeservers_configuration_changed(service);
-
- if (service == connman_service_get_default())
- __connman_timeserver_sync(service);
+ __connman_timeserver_conf_update(service);
} else if (g_str_equal(name, "Domains.Configuration")) {
DBusMessageIter entry;
always_connect[always_connected_techs[i]] = 1;
}
+#if !defined TIZEN_EXT
static bool autoconnect_no_session_active(struct connman_service *service)
{
/*
return false;
}
+#endif
static bool autoconnect_already_connecting(struct connman_service *service,
bool autoconnecting)
continue;
#endif
+ if (service->connect_reason ==
+ CONNMAN_SERVICE_CONNECT_REASON_NATIVE) {
+ DBG("service %p uses native autonnect, skip", service);
+ continue;
+ }
+
if (service->pending ||
is_connecting(service->state) ||
is_connected(service->state)) {
break;
#endif
if (!is_connecting(temp->state) && !is_connected(temp->state))
- break;
+ continue;
if (service == temp)
continue;
services_notify->id = g_timeout_add(100, service_send_changed, NULL);
}
-static DBusMessage *move_service(DBusConnection *conn,
- DBusMessage *msg, void *user_data,
- bool before)
+int __connman_service_move(struct connman_service *service,
+ struct connman_service *target, bool before)
{
- struct connman_service *service = user_data;
- struct connman_service *target;
- const char *path;
enum connman_ipconfig_method target4, target6;
enum connman_ipconfig_method service4, service6;
DBG("service %p", service);
- dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
+ if (!service)
+ return -EINVAL;
if (!service->favorite)
- return __connman_error_not_supported(msg);
+ return -EOPNOTSUPP;
- target = find_service(path);
if (!target || !target->favorite || target == service)
- return __connman_error_invalid_service(msg);
+ return -EINVAL;
if (target->type == CONNMAN_SERVICE_TYPE_VPN) {
/*
connman_info("Cannot move service. "
"No routes defined for provider %s",
__connman_provider_get_ident(target->provider));
- return __connman_error_invalid_service(msg);
+ return -EINVAL;
}
- set_split_routing(target, true);
+ __connman_service_set_split_routing(target, true);
} else
- set_split_routing(target, false);
+ __connman_service_set_split_routing(target, false);
- set_split_routing(service, false);
+ __connman_service_set_split_routing(service, false);
target4 = __connman_ipconfig_get_method(target->ipconfig_ipv4);
target6 = __connman_ipconfig_get_method(target->ipconfig_ipv6);
if (service6 != CONNMAN_IPCONFIG_METHOD_OFF) {
if (!check_suitable_state(target->state_ipv6,
service->state_ipv6))
- return __connman_error_invalid_service(msg);
+ return -EINVAL;
}
}
if (service4 != CONNMAN_IPCONFIG_METHOD_OFF) {
if (!check_suitable_state(target->state_ipv4,
service->state_ipv4))
- return __connman_error_invalid_service(msg);
+ return -EINVAL;
}
}
if (target6 != CONNMAN_IPCONFIG_METHOD_OFF) {
if (!check_suitable_state(target->state_ipv6,
service->state_ipv6))
- return __connman_error_invalid_service(msg);
+ return -EINVAL;
}
}
if (target4 != CONNMAN_IPCONFIG_METHOD_OFF) {
if (!check_suitable_state(target->state_ipv4,
service->state_ipv4))
- return __connman_error_invalid_service(msg);
+ return -EINVAL;
}
}
service_schedule_changed();
+ return 0;
+}
+
+static DBusMessage *move_service(DBusConnection *conn,
+ DBusMessage *msg, void *user_data,
+ bool before)
+{
+ struct connman_service *service = user_data;
+ struct connman_service *target;
+ const char *path;
+ int err;
+
+ DBG("service %p", service);
+
+ dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID);
+
+ target = find_service(path);
+
+ err = __connman_service_move(service, target, before);
+ switch (err) {
+ case 0:
+ break;
+ case -EINVAL:
+ return __connman_error_invalid_service(msg);
+ case -EOPNOTSUPP:
+ return __connman_error_not_supported(msg);
+ default:
+ connman_warn("unsupported error code %d in move_service()",
+ err);
+ break;
+ }
+
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
}
#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
-#if defined TIZEN_MAINTAIN_ONLINE
+#if defined TIZEN_EXT
static DBusMessage *downgrade_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
downgrade_state(service);
__connman_connection_update_gateway();
+ start_online_check(service, CONNMAN_IPCONFIG_TYPE_IPV4);
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
#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
+#if defined TIZEN_EXT
{ GDBUS_METHOD("Downgrade", NULL, NULL, downgrade_service) },
#endif
{ },
memset(service->last_connected_bssid, 0, WIFI_BSSID_LEN_MAX);
service->is_internet_connection = false;
service->assoc_reject_count = 0;
-#endif
-#if defined TIZEN_EXT
+
service->disconnection_requested = false;
service->storage_reload = false;
/*
g_hash_table_remove(service_hash, service->identifier);
}
-#if defined TIZEN_EXT
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
static int calculate_score_last_user_selection(struct connman_service *service)
{
int score = 0;
last_connected_ident = connman_device_get_last_connected_ident(device);
frequency = connman_network_get_frequency(service->network);
- if (g_strcmp0(last_connected_ident, service->identifier) == 0 &&
- (((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 &&
- frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) &&
- service->strength >= ins_settings.signal_level3_24ghz) ||
- ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 &&
- frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) &&
- service->strength >= ins_settings.signal_level3_5ghz))) {
- score += ins_settings.last_connected_score;
+ if (ins_settings.last_connected) {
+ if (g_strcmp0(last_connected_ident, service->identifier) == 0 &&
+ (((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 &&
+ frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) &&
+ service->strength >= ins_settings.signal_level3_24ghz) ||
+ ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 &&
+ frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) &&
+ service->strength >= ins_settings.signal_level3_5ghz))) {
+ score += ins_settings.last_connected_score;
+ }
}
return score;
switch (ins_settings.preferred_freq) {
case CONNMAN_INS_PREFERRED_FREQ_24GHZ:
- if ((frequency >= FREQ_RANGE_24GHZ_CHANNEL_14 &&
+ if ((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 &&
frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) &&
(service->strength >= ins_settings.signal_level3_24ghz))
score += ins_settings.preferred_freq_score;
score_frequency + score_security_priority +
score_internet_connection + score_strength;
-#if defined TIZEN_EXT_INS
service->score_last_user_selection = score_last_user_selection;
service->score_last_connected = score_last_connected;
service->score_frequency = score_frequency;
service->score_security_priority = score_security_priority;
service->score_internet_connection = score_internet_connection;
service->score_strength = score_strength;
-#endif
service->ins_score = score;
return score;
}
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+
+static gint service_compare(gconstpointer a, gconstpointer b);
+
+static gint service_compare_vpn(struct connman_service *a,
+ struct connman_service *b)
+{
+ struct connman_provider *provider;
+ struct connman_service *service;
+ struct connman_service *transport;
+ const char *ident;
+ bool reverse;
+
+ if (a->provider) {
+ provider = a->provider;
+ service = b;
+ reverse = false;
+ } else if (b->provider) {
+ provider = b->provider;
+ service = a;
+ reverse = true;
+ } else {
+ return 0;
+ }
+
+ ident = __connman_provider_get_transport_ident(provider);
+ transport = connman_service_lookup_from_identifier(ident);
+ if (!transport)
+ return 0;
+
+ if (reverse)
+ return service_compare(service, transport);
+
+ return service_compare(transport, service);
+}
static gint service_compare(gconstpointer a, gconstpointer b)
{
struct connman_service *service_b = (void *) b;
enum connman_service_state state_a, state_b;
bool a_connected, b_connected;
-#if defined TIZEN_EXT
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
int score_a;
int score_b;
-#else
+#else /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
gint strength;
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
state_a = service_a->state;
state_b = service_b->state;
service_a->type == CONNMAN_SERVICE_TYPE_WIFI &&
service_b->type == CONNMAN_SERVICE_TYPE_WIFI) {
const char *default_interface =
- connman_option_get_string("DefaultWifiInterface");
+ connman_setting_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(
#endif
if (a_connected && b_connected) {
+ int rval;
+
+ /* Compare the VPN transport and the service */
+ if ((service_a->type == CONNMAN_SERVICE_TYPE_VPN ||
+ service_b->type == CONNMAN_SERVICE_TYPE_VPN) &&
+ service_b->type != service_a->type) {
+ rval = service_compare_vpn(service_a, service_b);
+ if (rval)
+ return rval;
+ }
+
if (service_a->order > service_b->order)
return -1;
return 1;
}
-#if defined TIZEN_EXT
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
score_a = calculate_score(service_a);
score_b = calculate_score(service_b);
if (score_b != score_a)
return score_b - score_a;
-#else
+#else /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
strength = (gint) service_b->strength - (gint) service_a->strength;
if (strength)
return strength;
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
return g_strcmp0(service_a->name, service_b->name);
}
-#if defined TIZEN_EXT_INS
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
static void print_service_sort(gpointer data, gpointer user_data)
{
struct connman_service *service = data;
service->score_security_priority, service->score_internet_connection,
service->score_strength);
}
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
static void service_list_sort(void)
{
if (service_list && service_list->next) {
service_list = g_list_sort(service_list, service_compare);
-#if defined TIZEN_EXT_INS
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
g_list_foreach(service_list, print_service_sort, NULL);
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
service_schedule_changed();
}
}
service->state_ipv4 = service->state_ipv6 =
CONNMAN_SERVICE_STATE_IDLE;
- if (service->error != CONNMAN_SERVICE_ERROR_AUTH_FAILED)
+ if (service->error != CONNMAN_SERVICE_ERROR_AUTH_FAILED &&
+ service->error != CONNMAN_SERVICE_ERROR_ASSOC_FAILED)
set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
#endif
service_complete(service);
+ service_list_sort();
__connman_connection_update_gateway();
}
}
goto done;
}
- if (service->hidden && name_len > 0 && name_len <= 32) {
- device = connman_network_get_device(service->network);
- security = connman_network_get_string(service->network,
- "WiFi.Security");
- err = __connman_device_request_hidden_scan(device,
- name, name_len,
- identity, passphrase,
- security, user_data);
+ if (service->hidden) {
+ if (name_len > 0 && name_len <= 32) {
+ device = connman_network_get_device(service->network);
+ security = connman_network_get_string(service->network,
+ "WiFi.Security");
+ err = __connman_device_request_hidden_scan(device,
+ name, name_len,
+ identity, passphrase,
+ security, user_data);
+ } else {
+ err = -EINVAL;
+ }
if (err < 0)
__connman_service_return_error(service, -err,
user_data);
#endif
}
}
+
+static void emit_wifi_roaming_failure(struct connman_service *service,
+ enum connman_service_state new_state)
+{
+ if (connman_setting_get_bool("WifiRoaming") &&
+ connman_network_get_bool(service->network, "WiFi.Roaming")) {
+ const char *cur_bssid;
+ const char *dst_bssid;
+ const char *ifname;
+ struct connman_device *device;
+
+ device = connman_network_get_device(service->network);
+ if (device) {
+ ifname = connman_device_get_string(device, "Interface");
+ cur_bssid = connman_network_get_string(service->network,
+ "WiFi.RoamingCurBSSID");
+ dst_bssid = connman_network_get_string(service->network,
+ "WiFi.RoamingDstBSSID");
+ }
+
+ if (device && ifname && cur_bssid && dst_bssid) {
+ switch(new_state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ case CONNMAN_SERVICE_STATE_READY:
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ break;
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ __connman_technology_notify_roaming_state(ifname,
+ "failure", cur_bssid, dst_bssid);
+ connman_network_set_bool(service->network,
+ "WiFi.Roaming", false);
+ connman_network_set_string(service->network,
+ "WiFi.RoamingCurBSSID", NULL);
+ connman_network_set_string(service->network,
+ "WiFi.RoamingDstBSSID", NULL);
+ break;
+ }
+ }
+ }
+}
#endif
static const char *get_dbus_sender(struct connman_service *service)
proxy_changed(service);
#if defined TIZEN_EXT
}
+
+ emit_wifi_roaming_failure(service, new_state);
#endif
/*
report_error_cb,
get_dbus_sender(service),
NULL);
+#if !defined TIZEN_EXT
+ goto notifier;
+#endif
}
service_complete(service);
break;
#else
__connman_service_connect_default(service);
#endif
+ emit_wifi_roaming_failure(service, new_state);
#endif
__connman_connection_update_gateway();
+#if !defined TIZEN_EXT
+notifier:
+#endif
if ((old_state == CONNMAN_SERVICE_STATE_ONLINE &&
new_state != CONNMAN_SERVICE_STATE_READY) ||
(old_state == CONNMAN_SERVICE_STATE_READY &&
return FALSE;
}
-int __connman_service_online_check_failed(struct connman_service *service,
- enum connman_ipconfig_type type)
+void __connman_service_online_check(struct connman_service *service,
+ enum connman_ipconfig_type type,
+ bool success)
{
GSourceFunc redo_func;
- int *interval;
+ unsigned int *interval;
+ enum connman_service_state current_state;
if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
interval = &service->online_check_interval_ipv4;
redo_func = redo_wispr_ipv6;
}
+ if(!enable_online_to_ready_transition)
+ goto redo_func;
+
+ if (success) {
+ *interval = online_check_max_interval;
+ } else {
+ current_state = service->state;
+ downgrade_state(service);
+ if (current_state != service->state)
+ *interval = online_check_initial_interval;
+ if (service != connman_service_get_default()) {
+ return;
+ }
+ }
+
+redo_func:
DBG("service %p type %s interval %d", service,
__connman_ipconfig_type2string(type), *interval);
redo_func, connman_service_ref(service));
/* Increment the interval for the next time, set a maximum timeout of
- * ONLINE_CHECK_MAX_INTERVAL * ONLINE_CHECK_MAX_INTERVAL seconds.
+ * online_check_max_interval seconds * online_check_max_interval seconds.
*/
- if (*interval < ONLINE_CHECK_MAX_INTERVAL)
+ if (*interval < online_check_max_interval)
(*interval)++;
-
- return EAGAIN;
}
int __connman_service_ipconfig_indicate_state(struct connman_service *service,
service->phase1);
#endif
}
-#if defined TIZEN_EXT
+#if defined TIZEN_EXT
static bool has_valid_configuration_object(struct connman_service *service)
{
return service->connector && service->c_sign_key && service->net_access_key;
__connman_service_clear_error(service);
+ if (service->network && service->autoconnect &&
+ __connman_network_native_autoconnect(service->network)) {
+ DBG("service %p switch connecting reason to native", service);
+ reason = CONNMAN_SERVICE_CONNECT_REASON_NATIVE;
+ }
+
err = service_connect(service);
DBG("service %p err %d", service, err);
service_methods, service_signals,
NULL, service, NULL);
+ if (__connman_config_provision_service(service) < 0)
+ service_load(service);
+
service_list_sort();
__connman_connection_update_gateway();
service_list_sort();
}
+static void trigger_autoconnect(struct connman_service *service)
+{
+ struct connman_device *device;
+ bool native;
+
+ if (!service->favorite)
+ return;
+
+ native = __connman_network_native_autoconnect(service->network);
+ if (native && service->autoconnect) {
+ DBG("trigger native autoconnect");
+ connman_network_set_autoconnect(service->network, true);
+ return;
+ }
+
+ device = connman_network_get_device(service->network);
+ if (device && connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_UNKNOWN))
+ return;
+
+ switch (service->type) {
+ case CONNMAN_SERVICE_TYPE_UNKNOWN:
+ case CONNMAN_SERVICE_TYPE_SYSTEM:
+ case CONNMAN_SERVICE_TYPE_P2P:
+#if defined TIZEN_EXT_WIFI_MESH
+ case CONNMAN_SERVICE_TYPE_MESH:
+#endif
+ break;
+
+ case CONNMAN_SERVICE_TYPE_GADGET:
+ case CONNMAN_SERVICE_TYPE_ETHERNET:
+ if (service->autoconnect) {
+ __connman_service_connect(service,
+ CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+ break;
+ }
+
+ /* fall through */
+ case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+ case CONNMAN_SERVICE_TYPE_GPS:
+ case CONNMAN_SERVICE_TYPE_VPN:
+ case CONNMAN_SERVICE_TYPE_WIFI:
+ case CONNMAN_SERVICE_TYPE_CELLULAR:
+ do_auto_connect(service, CONNMAN_SERVICE_CONNECT_REASON_AUTO);
+ break;
+ }
+
+#if defined TIZEN_EXT
+ /* TIZEN synchronizes below information when the service creates */
+ if (service->eap != NULL)
+ connman_network_set_string(service->network, "WiFi.EAP",
+ service->eap);
+ if (service->identity != NULL)
+ connman_network_set_string(service->network, "WiFi.Identity",
+ service->identity);
+ if (service->phase2 != NULL)
+ connman_network_set_string(service->network, "WiFi.Phase2",
+ service->phase2);
+ if (service->eap != NULL)
+ connman_network_set_string(service->network, "WiFi.Connector",
+ service->connector);
+ if (service->identity != NULL)
+ connman_network_set_string(service->network, "WiFi.CSignKey",
+ service->c_sign_key);
+ if (service->phase2 != NULL)
+ connman_network_set_string(service->network, "WiFi.NetAccessKey",
+ service->net_access_key);
+#endif
+}
+
/**
* __connman_service_create_from_network:
* @network: network structure
struct connman_service * __connman_service_create_from_network(struct connman_network *network)
{
struct connman_service *service;
- struct connman_device *device;
const char *ident, *group;
char *name;
unsigned int *auto_connect_types, *favorite_types;
service_register(service);
service_schedule_added(service);
- if (service->favorite) {
- device = connman_network_get_device(service->network);
- if (device && !connman_device_get_scanning(device,
- CONNMAN_SERVICE_TYPE_UNKNOWN)) {
-
- switch (service->type) {
- case CONNMAN_SERVICE_TYPE_UNKNOWN:
- case CONNMAN_SERVICE_TYPE_SYSTEM:
- case CONNMAN_SERVICE_TYPE_P2P:
-#if defined TIZEN_EXT_WIFI_MESH
- case CONNMAN_SERVICE_TYPE_MESH:
-#endif
- break;
-
- case CONNMAN_SERVICE_TYPE_GADGET:
- case CONNMAN_SERVICE_TYPE_ETHERNET:
- if (service->autoconnect) {
- __connman_service_connect(service,
- CONNMAN_SERVICE_CONNECT_REASON_AUTO);
- break;
- }
-
- /* fall through */
- case CONNMAN_SERVICE_TYPE_BLUETOOTH:
- case CONNMAN_SERVICE_TYPE_GPS:
- case CONNMAN_SERVICE_TYPE_VPN:
- case CONNMAN_SERVICE_TYPE_WIFI:
- case CONNMAN_SERVICE_TYPE_CELLULAR:
- do_auto_connect(service,
- CONNMAN_SERVICE_CONNECT_REASON_AUTO);
- break;
- }
- }
-
-#if defined TIZEN_EXT
- /* TIZEN synchronizes below information when the service creates */
- if (service->eap != NULL)
- connman_network_set_string(service->network, "WiFi.EAP",
- service->eap);
- if (service->identity != NULL)
- connman_network_set_string(service->network, "WiFi.Identity",
- service->identity);
- if (service->phase2 != NULL)
- connman_network_set_string(service->network, "WiFi.Phase2",
- service->phase2);
- if (service->eap != NULL)
- connman_network_set_string(service->network, "WiFi.Connector",
- service->connector);
- if (service->identity != NULL)
- connman_network_set_string(service->network, "WiFi.CSignKey",
- service->c_sign_key);
- if (service->phase2 != NULL)
- connman_network_set_string(service->network, "WiFi.NetAccessKey",
- service->net_access_key);
-#endif
- }
+ trigger_autoconnect(service);
__connman_notifier_service_add(service, service->name);
.context_unref = agent_context_unref,
};
-#if defined TIZEN_EXT
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
static void ins_setting_init(void)
{
int i;
ins_settings.last_user_selection_time = connman_setting_get_uint("INSLastUserSelectionTime");
ins_settings.last_connected = connman_setting_get_bool("INSLastConnected");
- string = connman_option_get_string("INSPreferredFreq");
+ string = connman_setting_get_string("INSPreferredFreq");
if (g_strcmp0(string, "5GHz") == 0)
ins_settings.preferred_freq = CONNMAN_INS_PREFERRED_FREQ_5GHZ;
else if (g_strcmp0(string, "2.4GHz") == 0)
ins_settings.preferred_freq_score = connman_setting_get_uint("INSPreferredFreqScore");
ins_settings.internet_score = connman_setting_get_uint("INSInternetScore");
- ins_settings.signal_level3_5ghz = connman_setting_get_int("INSSignalLevel3_5GHz");
- ins_settings.signal_level3_24ghz = connman_setting_get_int("INSSignalLevel3_24GHz");
+ /*
+ * In ConnMan, signal strength is used after being converted
+ * to positive value(signal strength + 120).
+ * So the value for comparison should also be converted to the same.
+ */
+ ins_settings.signal_level3_5ghz = connman_setting_get_int("INSSignalLevel3_5GHz") + 120;
+ ins_settings.signal_level3_24ghz = connman_setting_get_int("INSSignalLevel3_24GHz") + 120;
DBG("last_user_selection [%s]", ins_settings.last_user_selection ? "true" : "false");
DBG("last_user_selection_time [%d]", ins_settings.last_user_selection_time);
DBG("signal_level3_5ghz [%d]", ins_settings.signal_level3_5ghz);
DBG("signal_level3_24ghz [%d]", ins_settings.signal_level3_24ghz);
}
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
int __connman_service_init(void)
{
remove_unprovisioned_services();
-#if defined TIZEN_EXT
+#if defined TIZEN_EXT && defined TIZEN_EXT_INS
ins_setting_init();
-#endif
+#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
return 0;
}