From: hyunuk.tak Date: Tue, 7 Apr 2020 03:57:45 +0000 (+0900) Subject: Add intelligent Network Selection X-Git-Tag: accepted/tizen/unified/20200417.152700^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=70730f50e09cac648b1c3b48f0a1e6ed40cc510f;p=platform%2Fupstream%2Fconnman.git Add intelligent Network Selection Change-Id: I049207e7d662f657ca21a4046be953f8f33bbd10 Signed-off-by: hyunuk.tak --- diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h old mode 100644 new mode 100755 index 3e51348..6dfd9c7 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -179,6 +179,14 @@ typedef enum { G_SUPPLICANT_PEER_GROUP_FAILED, } GSupplicantPeerState; +#if defined TIZEN_EXT +typedef enum { + G_SUPPLICANT_INS_PREFERRED_FREQ_UNKNOWN, + G_SUPPLICANT_INS_PREFERRED_FREQ_24GHZ, + G_SUPPLICANT_INS_PREFERRED_FREQ_5GHZ, +} GSupplicantINSPreferredFreq; +#endif + struct _GSupplicantSSID { #if defined TIZEN_EXT void *ssid; @@ -469,6 +477,15 @@ const unsigned char *g_supplicant_network_get_countrycode(GSupplicantNetwork void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network); GSupplicantPhy_mode g_supplicant_network_get_phy_mode(GSupplicantNetwork *network); #endif +#if defined TIZEN_EXT +void g_supplicant_network_set_last_connected_bssid(GSupplicantNetwork *network, const unsigned char *bssid); +const unsigned char *g_supplicant_network_get_last_connected_bssid(GSupplicantNetwork *network); +void g_supplicant_network_update_assoc_reject(GSupplicantInterface *interface, + GSupplicantNetwork *network); +GHashTable *g_supplicant_network_get_assoc_reject_table(GSupplicantNetwork *network); +GSupplicantNetwork *g_supplicant_interface_get_network(GSupplicantInterface *interface, + const char *group); +#endif struct _GSupplicantCallbacks { void (*system_ready) (void); @@ -518,6 +535,13 @@ struct _GSupplicantCallbacks { typedef struct _GSupplicantCallbacks GSupplicantCallbacks; +#if defined TIZEN_EXT +void g_supplicant_set_ins_settings(GSupplicantINSPreferredFreq preferred_freq_bssid, + bool last_connected_bssid, bool assoc_reject, bool signal_bssid, + unsigned int preferred_freq_bssid_score, unsigned int last_connected_bssid_score, + unsigned int assoc_reject_score, int signal_level3_5ghz, int signal_level3_24ghz); +#endif + int g_supplicant_register(const GSupplicantCallbacks *callbacks); void g_supplicant_unregister(const GSupplicantCallbacks *callbacks); diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c old mode 100644 new mode 100755 index 2e8af6a..957312c --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -53,6 +53,15 @@ #define WIFI_BSSID_LEN_MAX 6 #endif +#if defined TIZEN_EXT +#define LAST_CONNECTED_TIMEOUT (5 * 60) +#define ASSOC_REJECT_TIMEOUT 10 +#define FREQ_RANGE_24GHZ_CHANNEL_1 2412 +#define FREQ_RANGE_24GHZ_CHANNEL_14 2484 +#define FREQ_RANGE_5GHZ_CHANNEL_32 5160 +#define FREQ_RANGE_5GHZ_CHANNEL_165 5825 +#endif + #define BSS_UNKNOWN_STRENGTH -90 static DBusConnection *connection; @@ -155,6 +164,26 @@ static struct strvalmap mode_capa_map[] = { { } }; +#if defined TIZEN_EXT +struct _GSupplicantINSSettings { + GSupplicantINSPreferredFreq preferred_freq_bssid; + unsigned int preferred_freq_bssid_score; + bool last_connected_bssid; + unsigned int last_connected_bssid_score; + bool assoc_reject; + unsigned int assoc_reject_score; + bool signal_bssid; + int signal_level3_5ghz; + int signal_level3_24ghz; +}; + +static struct _GSupplicantINSSettings ins_settings; + +static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#endif + static GHashTable *interface_table; static GHashTable *bss_mapping; static GHashTable *peer_mapping; @@ -225,6 +254,10 @@ struct _GSupplicantInterface { dbus_bool_t is_5_0_Ghz_supported; int disconnect_reason; #endif +#if defined TIZEN_EXT + unsigned char add_network_bssid[WIFI_BSSID_LEN_MAX]; + unsigned char connected_bssid[WIFI_BSSID_LEN_MAX]; +#endif #if defined TIZEN_EXT_WIFI_MESH bool mesh_support; struct _GSupplicantMeshGroupInfo group_info; @@ -295,6 +328,10 @@ struct _GSupplicantNetwork { unsigned char country_code[COUNTRY_CODE_LENGTH]; GSupplicantPhy_mode phy_mode; #endif +#if defined TIZEN_EXT + unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX]; + GHashTable *assoc_reject_table; +#endif }; struct _GSupplicantPeer { @@ -377,7 +414,29 @@ struct g_connman_bssids { unsigned char bssid[WIFI_BSSID_LEN_MAX]; uint16_t strength; uint16_t frequency; + uint16_t assoc_reject_cnt; + bool is_last_connected; + int ins_score; }; + +struct update_bssid_data { + GSupplicantNetwork *network; + unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX]; + GHashTable *assoc_reject_table; + GSList *bssid_list; +}; + +struct assoc_reject_data { + char *bssid; + GSList *reject_time_list; +}; + +struct assoc_count_data { + time_t ref_time; + int assoc_count; +}; + +static unsigned int last_connected_bss_timeout = 0; #endif static int network_remove(struct interface_data *data); @@ -971,6 +1030,9 @@ static void remove_network(gpointer data) callback_network_removed(network); g_hash_table_destroy(network->config_table); +#if defined TIZEN_EXT + g_hash_table_destroy(network->assoc_reject_table); +#endif g_free(network->path); g_free(network->group); @@ -1023,6 +1085,18 @@ static void remove_peer(gpointer data) g_free(peer); } +#if defined TIZEN_EXT +static void remove_assoc_data(gpointer data) +{ + struct assoc_reject_data *assoc_data = data; + + g_free(assoc_data->bssid); + g_slist_free(assoc_data->reject_time_list); + + g_free(assoc_data); +} +#endif + static void debug_strvalmap(const char *label, struct strvalmap *map, unsigned int val) { @@ -1807,11 +1881,92 @@ void *g_supplicant_network_get_wifi_vsie(GSupplicantNetwork *network) return vsie_list; } +static bool compare_bssid(unsigned char *bssid_a, unsigned char *bssid_b) +{ + if (!memcmp(bssid_a, bssid_b, WIFI_BSSID_LEN_MAX)) + return true; + + return false; +} + +static gchar *convert_bssid_to_str(unsigned char *bssid) +{ + GString *bssid_str; + unsigned int i; + + bssid_str = g_string_sized_new(18); + if (!bssid_str) + return NULL; + + for (i = 0; i < WIFI_BSSID_LEN_MAX; i++) { + g_string_append_printf(bssid_str, "%02x", bssid[i]); + if (i < WIFI_BSSID_LEN_MAX - 1) + g_string_append(bssid_str, ":"); + } + + return g_string_free(bssid_str, FALSE); +} + +static void count_assoc_reject(gpointer data, gpointer user_data) +{ + time_t assoc_reject_time = GPOINTER_TO_INT(data); + struct assoc_count_data *assoc_count = user_data; + + if (assoc_reject_time > assoc_count->ref_time) + assoc_count->assoc_count++; +} + +static uint16_t get_assoc_reject_cnt(GHashTable *assoc_reject_table, unsigned char *bssid) +{ + gchar *bssid_str; + struct assoc_reject_data *assoc_data; + struct assoc_count_data assoc_count; + time_t curr_time; + struct tm* timeinfo; + + if (g_hash_table_size(assoc_reject_table) < 1) + return 0; + + if (!bssid) + return 0; + + if (!memcmp(bssid, invalid_bssid, WIFI_BSSID_LEN_MAX)) + return 0; + + bssid_str = convert_bssid_to_str(bssid); + if (!bssid_str) + return 0; + + assoc_data = g_hash_table_lookup(assoc_reject_table, bssid_str); + if (!assoc_data) { + g_free(bssid_str); + return 0; + } + + if (g_slist_length(assoc_data->reject_time_list) < 1) { + g_free(bssid_str); + return 0; + } + + /* Only events that occur within one hour are appened. */ + curr_time = time(NULL); + timeinfo = localtime(&curr_time); + timeinfo->tm_hour -= 1; + + assoc_count.ref_time = mktime(timeinfo); + assoc_count.assoc_count = 0; + + g_slist_foreach(assoc_data->reject_time_list, count_assoc_reject, &assoc_count); + + g_free(bssid_str); + return assoc_count.assoc_count; +} + static void update_bssid_list(gpointer key, gpointer value, gpointer user_data) { struct g_supplicant_bss *bss = value; struct g_connman_bssids *bssids = NULL; - GSList **list = (GSList **)user_data; + struct update_bssid_data *bssid_data = (struct update_bssid_data *)user_data; bssids = (struct g_connman_bssids *)g_try_malloc0(sizeof(struct g_connman_bssids)); @@ -1825,36 +1980,187 @@ static void update_bssid_list(gpointer key, gpointer value, gpointer user_data) bssids->strength = 100; bssids->frequency = bss->frequency; - *list = g_slist_append(*list, bssids); + + bssids->assoc_reject_cnt = get_assoc_reject_cnt(bssid_data->assoc_reject_table, bssids->bssid); + + bssids->is_last_connected = compare_bssid(bssids->bssid, bssid_data->last_connected_bssid); + + bssid_data->bssid_list = g_slist_append(bssid_data->bssid_list, bssids); } else SUPPLICANT_DBG("Failed to allocate memory"); } +static int calculate_score(dbus_int16_t strength, dbus_uint16_t frequency, + uint16_t assoc_reject_cnt, bool is_last_connected) +{ + int score = 0; + + /* 5GHz & Signal >= RSSI Level 3 */ + switch (ins_settings.preferred_freq_bssid) { + case G_SUPPLICANT_INS_PREFERRED_FREQ_24GHZ: + if ((frequency >= FREQ_RANGE_24GHZ_CHANNEL_1 && + frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) && + (strength > ins_settings.signal_level3_24ghz)) + score += ins_settings.preferred_freq_bssid_score; + + break; + case G_SUPPLICANT_INS_PREFERRED_FREQ_5GHZ: + if ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 && + frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) && + (strength > ins_settings.signal_level3_5ghz)) + score += ins_settings.preferred_freq_bssid_score; + + break; + default: + break; + } + + /* Last connected BSSID */ + if (ins_settings.last_connected_bssid) { + if (is_last_connected) + score += ins_settings.last_connected_bssid_score; + } + + /* Assoc reject */ + if (ins_settings.assoc_reject) + score -= (assoc_reject_cnt * ins_settings.assoc_reject_score); + + /* Signal */ + if (ins_settings.signal_bssid) + score += (((strength > -60) ? -60 : strength) + 85); + + return score; +} + static gint cmp_bss(gconstpointer a, gconstpointer b) { struct g_connman_bssids *entry_a = (struct g_connman_bssids *)a; struct g_connman_bssids *entry_b = (struct g_connman_bssids *)b; + int score_a = calculate_score(entry_a->strength - 120, entry_a->frequency, + entry_a->assoc_reject_cnt, entry_a->is_last_connected); + int score_b = calculate_score(entry_b->strength - 120, entry_b->frequency, + entry_b->assoc_reject_cnt, entry_b->is_last_connected); + + entry_a->ins_score = score_a; + entry_b->ins_score = score_b; - if (entry_a->strength > entry_b->strength) + if (score_a > score_b) return -1; - if (entry_a->strength < entry_b->strength) + if (score_a < score_b) return 1; return 0; } +#if defined TIZEN_EXT_INS +static void print_bssid_sort(gpointer data, gpointer user_data) +{ + struct g_connman_bssids *bssids = data; + + SUPPLICANT_DBG("bssid[%02x:%02x:%02x:%02x:%02x:%02x] score[%d] " + "strength[%d] freq[%d] assoc_reject[%d] last_conn[%d]", + bssids->bssid[0], bssids->bssid[1], bssids->bssid[2], + bssids->bssid[3], bssids->bssid[4], bssids->bssid[5], + bssids->ins_score, bssids->strength, bssids->frequency, + bssids->assoc_reject_cnt, bssids->is_last_connected); +} +#endif + void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network) { - GSList *bssid_list = NULL; + struct update_bssid_data bssid_data; if (g_hash_table_size(network->bss_table) < 1) return NULL; - g_hash_table_foreach(network->bss_table, update_bssid_list, &bssid_list); - bssid_list = g_slist_sort(bssid_list, cmp_bss); + bssid_data.network = network; + memset(&bssid_data, 0, sizeof(bssid_data)); + memcpy(bssid_data.last_connected_bssid, network->last_connected_bssid, WIFI_BSSID_LEN_MAX); + bssid_data.assoc_reject_table = network->assoc_reject_table; + + g_hash_table_foreach(network->bss_table, update_bssid_list, &bssid_data); + bssid_data.bssid_list = g_slist_sort(bssid_data.bssid_list, cmp_bss); +#if defined TIZEN_EXT_INS + g_slist_foreach(bssid_data.bssid_list, print_bssid_sort, NULL); +#endif + + return bssid_data.bssid_list; +} + +void g_supplicant_network_set_last_connected_bssid(GSupplicantNetwork *network, const unsigned char *bssid) +{ + if (!bssid) + return; + + if (!memcmp(bssid, invalid_bssid, WIFI_BSSID_LEN_MAX)) + return; + + memcpy(network->last_connected_bssid, bssid, WIFI_BSSID_LEN_MAX); + + SUPPLICANT_DBG("last connected bssid [%02x:%02x:%02x:%02x:%02x:%02x]", + bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); +} + +const unsigned char *g_supplicant_network_get_last_connected_bssid(GSupplicantNetwork *network) +{ + if (network == NULL) + return NULL; - return bssid_list; + return (const unsigned char *)network->last_connected_bssid; +} + +void g_supplicant_network_update_assoc_reject(GSupplicantInterface *interface, + GSupplicantNetwork *network) +{ + struct assoc_reject_data *assoc_data; + gchar *bssid_str; + time_t curr_time; + + if (!network) + return; + + bssid_str = convert_bssid_to_str(interface->add_network_bssid); + if (!bssid_str) + return; + + assoc_data = g_hash_table_lookup(network->assoc_reject_table, bssid_str); + if (!assoc_data) { + assoc_data = g_try_new0(struct assoc_reject_data, 1); + if (!assoc_data) { + g_free(bssid_str); + return; + } + + assoc_data->bssid = g_strdup(bssid_str); + g_hash_table_insert(network->assoc_reject_table, assoc_data->bssid, assoc_data); + } + + curr_time = time(NULL); + assoc_data->reject_time_list = g_slist_append(assoc_data->reject_time_list, GINT_TO_POINTER(curr_time)); + + SUPPLICANT_DBG("bssid [%s] time [%u]", bssid_str, curr_time); + + g_free(bssid_str); + + callback_network_changed(network, "UpdateAssocReject"); +} + +GHashTable *g_supplicant_network_get_assoc_reject_table(GSupplicantNetwork *network) +{ + if (!network) + return NULL; + + return network->assoc_reject_table; +} + +GSupplicantNetwork *g_supplicant_interface_get_network(GSupplicantInterface *interface, + const char *group) +{ + if (!interface) + return NULL; + + return g_hash_table_lookup(interface->network_table, group); } #endif @@ -2093,6 +2399,42 @@ static char *create_group(struct g_supplicant_bss *bss) return g_string_free(str, FALSE); } +static bool update_best_bss(GSupplicantNetwork *network, + struct g_supplicant_bss *bss, struct g_supplicant_bss *best_bss) +{ + int score_new; + int score_best; + + score_new = calculate_score(bss->signal, bss->frequency, + get_assoc_reject_cnt(network->assoc_reject_table, bss->bssid), + compare_bssid(bss->bssid, network->last_connected_bssid)); + score_best = calculate_score(network->best_bss->signal, network->best_bss->frequency, + get_assoc_reject_cnt(network->assoc_reject_table, network->best_bss->bssid), + compare_bssid(network->best_bss->bssid, network->last_connected_bssid)); + + if (score_new > score_best) { + SUPPLICANT_DBG("new[%02x:%02x:%02x:%02x:%02x:%02x][%u] : " + "best[%02x:%02x:%02x:%02x:%02x:%02x][%u]", + bss->bssid[0], bss->bssid[1], bss->bssid[2], + bss->bssid[3], bss->bssid[4], bss->bssid[5], + score_new, + network->best_bss->bssid[0], network->best_bss->bssid[1], + network->best_bss->bssid[2], network->best_bss->bssid[3], + network->best_bss->bssid[4], network->best_bss->bssid[5], + score_best); + + network->signal = bss->signal; + network->frequency = bss->frequency; + network->best_bss = bss; + + SUPPLICANT_DBG("Update best BSS for %s", network->name); + + return true; + } + + return false; +} + static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss) { GSupplicantInterface *interface = bss->interface; @@ -2172,6 +2514,11 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss) network->config_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); +#if defined TIZEN_EXT + network->assoc_reject_table = g_hash_table_new_full(g_str_hash, g_str_equal, + NULL, remove_assoc_data); +#endif + g_hash_table_replace(interface->network_table, network->group, network); @@ -2191,12 +2538,19 @@ done: * Do not change best BSS if we are connected. It will be done through * CurrentBSS property in case of misalignment with wpa_s or roaming. */ +#if defined TIZEN_EXT + if (network != interface->current_network) { + if (update_best_bss(network, bss, network->best_bss)) + callback_network_changed(network, "Signal"); + } +#else if (network != interface->current_network && bss->signal > network->signal) { network->signal = bss->signal; network->best_bss = bss; callback_network_changed(network, "Signal"); } +#endif g_hash_table_replace(interface->bss_mapping, bss->path, network); g_hash_table_replace(network->bss_table, bss->path, bss); @@ -2818,10 +3172,22 @@ static void update_signal(gpointer key, gpointer value, struct g_supplicant_bss *bss = value; GSupplicantNetwork *network = user_data; +#if defined TIZEN_EXT + if (!network->best_bss || (network->best_bss == bss)) { + if (bss->signal > network->signal) { + network->signal = bss->signal; + network->best_bss = bss; + } + return; + } + + update_best_bss(network, bss, network->best_bss); +#else if (bss->signal > network->signal) { network->signal = bss->signal; network->best_bss = bss; } +#endif } static void update_network_signal(GSupplicantNetwork *network) @@ -2835,6 +3201,61 @@ static void update_network_signal(GSupplicantNetwork *network) SUPPLICANT_DBG("New network signal %d", network->signal); } +#if defined TIZEN_EXT +static gboolean last_connected_timeout(gpointer data) +{ + GSupplicantInterface *interface = data; + GSupplicantNetwork *current_network = interface->current_network; + + SUPPLICANT_DBG("Timeout last connected bss"); + + if (current_network && current_network->best_bss) { + if (compare_bssid(current_network->best_bss->bssid, interface->connected_bssid)) { + g_supplicant_network_set_last_connected_bssid(current_network, interface->connected_bssid); + callback_network_changed(current_network, "LastConnectedBSSID"); + } + } + + last_connected_bss_timeout = 0; + return FALSE; +} + +static void add_timer_for_last_connected(GSupplicantInterface *interface) +{ + GSupplicantNetwork *current_network = interface->current_network; + + if (interface->state == G_SUPPLICANT_STATE_COMPLETED) { + if (current_network) { + struct g_supplicant_bss *best_bss = current_network->best_bss; + + memcpy(interface->connected_bssid, best_bss->bssid, WIFI_BSSID_LEN_MAX); + + if (last_connected_bss_timeout) + g_source_remove(last_connected_bss_timeout); + + last_connected_bss_timeout = g_timeout_add_seconds(LAST_CONNECTED_TIMEOUT, + last_connected_timeout, interface); + + SUPPLICANT_DBG("Add timer for last connected bssid " + "[%02x:%02x:%02x:%02x:%02x:%02x]", + best_bss->bssid[0], best_bss->bssid[1], best_bss->bssid[2], + best_bss->bssid[3], best_bss->bssid[4], best_bss->bssid[5]); + } + } +} + +static void remove_timer_for_last_connected(GSupplicantInterface *interface) +{ + if (interface->state == G_SUPPLICANT_STATE_DISCONNECTED) { + if (last_connected_bss_timeout != 0) { + g_source_remove(last_connected_bss_timeout); + last_connected_bss_timeout = 0; + SUPPLICANT_DBG("Remove timer for last connected bss"); + } + } +} +#endif + static void interface_current_bss(GSupplicantInterface *interface, DBusMessageIter *iter) { @@ -2859,6 +3280,9 @@ static void interface_current_bss(GSupplicantInterface *interface, return; interface->current_network = network; +#if defined TIZEN_EXT + SUPPLICANT_DBG("current network [%p]", interface->current_network); +#endif if (bss != network->best_bss) { /* @@ -2900,6 +3324,9 @@ static void interface_current_bss(GSupplicantInterface *interface, case G_SUPPLICANT_STATE_GROUP_HANDSHAKE: case G_SUPPLICANT_STATE_COMPLETED: callback_network_associated(network); +#if defined TIZEN_EXT + add_timer_for_last_connected(interface); +#endif break; } } @@ -3037,7 +3464,18 @@ static void interface_property(const char *key, DBusMessageIter *iter, interface->state = string2state(str); callback_interface_state(interface); } - +#if defined TIZEN_EXT + switch (interface->state) { + case G_SUPPLICANT_STATE_COMPLETED: + add_timer_for_last_connected(interface); + break; + case G_SUPPLICANT_STATE_DISCONNECTED: + remove_timer_for_last_connected(interface); + break; + default: + break; + } +#endif if (interface->ap_create_in_progress) { if (interface->state == G_SUPPLICANT_STATE_DISCONNECTED) callback_ap_create_fail(interface); @@ -3122,12 +3560,18 @@ static void interface_property(const char *key, DBusMessageIter *iter, if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) { dbus_message_iter_get_basic(iter, &reason_code); callback_disconnect_reason_code(interface, reason_code); +#if defined TIZEN_EXT + SUPPLICANT_DBG("reason code (%d)", reason_code); +#endif } } else if (g_strcmp0(key, "AssocStatusCode") == 0) { int status_code; if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID) { dbus_message_iter_get_basic(iter, &status_code); callback_assoc_status_code(interface, status_code); +#if defined TIZEN_EXT + SUPPLICANT_DBG("status code (%d)", status_code); +#endif } } else { SUPPLICANT_DBG("key %s type %c", @@ -3658,22 +4102,28 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter) * If the new signal is lower than the SSID signal, we need * to check for the new maximum. */ - if (bss->signal < network->signal) { - if (bss != network->best_bss) -#ifndef TIZEN_EXT - return; -#else - { +#if defined TIZEN_EXT + if (!update_best_bss(network, bss, network->best_bss)) { + if (bss != network->best_bss) { callback_network_changed(network, ""); return; } -#endif + + network->signal = bss->signal; + update_network_signal(network); + } +#else + if (bss->signal < network->signal) { + if (bss != network->best_bss) + return; + network->signal = bss->signal; update_network_signal(network); } else { network->signal = bss->signal; network->best_bss = bss; } +#endif SUPPLICANT_DBG("New network signal for %s %d dBm", network->ssid, network->signal); @@ -6474,6 +6924,9 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data) DBusMessageIter dict; struct interface_connect_data *data = user_data; GSupplicantSSID *ssid = data->ssid; +#if defined TIZEN_EXT + GSupplicantInterface *interface = data->interface; +#endif supplicant_dbus_dict_open(iter, &dict); @@ -6511,14 +6964,22 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data) return; } - if (ssid->bssid_for_connect_len) + if (ssid->bssid_for_connect_len) { snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x", ssid->bssid_for_connect[0], ssid->bssid_for_connect[1], ssid->bssid_for_connect[2], ssid->bssid_for_connect[3], ssid->bssid_for_connect[4], ssid->bssid_for_connect[5]); - else + memcpy(interface->add_network_bssid, ssid->bssid_for_connect, WIFI_BSSID_LEN_MAX); + } else { snprintf(bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x", ssid->bssid[0], ssid->bssid[1], ssid->bssid[2], ssid->bssid[3], ssid->bssid[4], ssid->bssid[5]); + memcpy(interface->add_network_bssid, ssid->bssid, WIFI_BSSID_LEN_MAX); + } + + SUPPLICANT_DBG("bssid [%02x:%02x:%02x:%02x:%02x:%02x]", + interface->add_network_bssid[0], interface->add_network_bssid[1], + interface->add_network_bssid[2], interface->add_network_bssid[3], + interface->add_network_bssid[4], interface->add_network_bssid[5]); supplicant_dbus_dict_append_basic(&dict, "bssid", DBUS_TYPE_STRING, &bssid); @@ -7706,6 +8167,34 @@ static void invoke_introspect_method(void) dbus_message_unref(message); } +#if defined TIZEN_EXT +void g_supplicant_set_ins_settings(GSupplicantINSPreferredFreq preferred_freq_bssid, + bool last_connected_bssid, bool assoc_reject, bool signal_bssid, + unsigned int preferred_freq_bssid_score, unsigned int last_connected_bssid_score, + unsigned int assoc_reject_score, int signal_level3_5ghz, int signal_level3_24ghz) +{ + ins_settings.preferred_freq_bssid = preferred_freq_bssid; + ins_settings.last_connected_bssid = last_connected_bssid; + ins_settings.assoc_reject = assoc_reject; + ins_settings.signal_bssid = signal_bssid; + ins_settings.preferred_freq_bssid_score = preferred_freq_bssid_score; + ins_settings.last_connected_bssid_score = last_connected_bssid_score; + ins_settings.assoc_reject_score = assoc_reject_score; + ins_settings.signal_level3_5ghz = signal_level3_5ghz; + ins_settings.signal_level3_24ghz = signal_level3_24ghz; + + SUPPLICANT_DBG("preferred_freq_bssid [%s]", preferred_freq_bssid ? "true" : "false"); + SUPPLICANT_DBG("preferred_freq_bssid_score [%d]", preferred_freq_bssid_score); + SUPPLICANT_DBG("last_connected_bssid [%s]", last_connected_bssid ? "true" : "false"); + SUPPLICANT_DBG("last_connected_bssid_score [%d]", last_connected_bssid_score); + SUPPLICANT_DBG("assoc_reject [%s]", assoc_reject ? "true" : "false"); + SUPPLICANT_DBG("assoc_reject_score [%d]", assoc_reject_score); + SUPPLICANT_DBG("signal_bssid [%s]", signal_bssid ? "true" : "false"); + SUPPLICANT_DBG("signal_level3_5ghz [%d]", signal_level3_5ghz); + SUPPLICANT_DBG("signal_level3_24ghz [%d]", signal_level3_24ghz); +} +#endif + int g_supplicant_register(const GSupplicantCallbacks *callbacks) { connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); diff --git a/include/device.h b/include/device.h old mode 100644 new mode 100755 index 77c476a..98c7bd8 --- a/include/device.h +++ b/include/device.h @@ -123,6 +123,22 @@ struct connman_device *connman_device_create_from_index(int index); struct connman_device *connman_device_find_by_index(int index); int connman_device_reconnect_service(struct connman_device *device); +#if defined TIZEN_EXT +bool connman_device_set_last_user_selection_time(struct connman_device *device, + time_t time); +time_t connman_device_get_last_user_selection_time(struct connman_device *device); +bool connman_device_set_last_user_selection_ident(struct connman_device *device, + const char *ident); +const char *connman_device_get_last_user_selection_ident(struct connman_device *device); +bool connman_device_set_last_connected_ident(struct connman_device *device, + const char *ident); +const char *connman_device_get_last_connected_ident(struct connman_device *device); +void connman_device_save_last_user_selection(struct connman_device *device); +void connman_device_load_last_user_selection(struct connman_device *device); +void connman_device_save_last_connected(struct connman_device *device); +void connman_device_load_last_connected(struct connman_device *device); +#endif + struct connman_device_driver { const char *name; enum connman_device_type type; diff --git a/include/network.h b/include/network.h index 14b9442..8cefb79 100755 --- a/include/network.h +++ b/include/network.h @@ -211,6 +211,14 @@ unsigned char *connman_network_get_countrycode(struct connman_network *network); int connman_network_set_bssid_list(struct connman_network *network, GSList *bssids); void *connman_network_get_bssid_list(struct connman_network *network); +#if defined TIZEN_EXT +int connman_network_set_last_connected_bssid(struct connman_network *network, + const unsigned char *bssid); +unsigned char *connman_network_get_last_connected_bssid(struct connman_network *network); +void connman_network_set_assoc_reject_table(struct connman_network *network, + GHashTable *assoc_reject_table); +GHashTable *connman_network_get_assoc_reject_table(struct connman_network *network); +#endif int connman_network_set_phy_mode(struct connman_network *network, ieee80211_modes_e mode); ieee80211_modes_e connman_network_get_phy_mode(struct connman_network *network); diff --git a/include/service.h b/include/service.h old mode 100644 new mode 100755 index 0337186..617735e --- a/include/service.h +++ b/include/service.h @@ -73,6 +73,9 @@ enum connman_service_security { CONNMAN_SERVICE_SECURITY_OWE = 11, CONNMAN_SERVICE_SECURITY_DPP = 12, #endif +#if defined TIZEN_EXT + CONNMAN_SERVICE_SECURITY_MAX +#endif }; enum connman_service_state { @@ -201,6 +204,12 @@ void connman_service_set_disconnection_requested(struct connman_service *service bool disconnection_requested); #endif +#if defined TIZEN_EXT +void connman_service_set_internet_connection(struct connman_service *service, + bool internet_connection); +bool connman_service_get_internet_connection(struct connman_service *service); +#endif + #ifdef __cplusplus } #endif diff --git a/include/setting.h b/include/setting.h index a882021..3625f3e 100755 --- a/include/setting.h +++ b/include/setting.h @@ -29,6 +29,10 @@ extern "C" { #endif bool connman_setting_get_bool(const char *key); +#if defined TIZEN_EXT +unsigned int connman_setting_get_uint(const char *key); +int connman_setting_get_int(const char *key); +#endif char **connman_setting_get_string_list(const char *key); unsigned int *connman_setting_get_uint_list(const char *key); diff --git a/packaging/connman.spec b/packaging/connman.spec index f4fa2a9..31ab4ca 100644 --- a/packaging/connman.spec +++ b/packaging/connman.spec @@ -5,7 +5,7 @@ Name: connman Version: 1.37 -Release: 35 +Release: 36 License: GPL-2.0+ Summary: Connection Manager Url: http://connman.net diff --git a/plugins/wifi.c b/plugins/wifi.c index bbfdbf9..bce1424 100755 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -4305,8 +4305,19 @@ static void interface_state(GSupplicantInterface *interface) #if defined TIZEN_EXT if (handle_assoc_status_code(interface, wifi)) { GSList *bssid_list = (GSList *)connman_network_get_bssid_list(network); + const char *group = connman_network_get_group(network); + GSupplicantNetwork *supplicant_network; guint bssid_length = 0; + if (group) { + supplicant_network = g_supplicant_interface_get_network(interface, group); + + connman_network_set_assoc_reject_table(network, + g_supplicant_network_get_assoc_reject_table(supplicant_network)); + + g_supplicant_network_update_assoc_reject(interface, supplicant_network); + } + if (bssid_list) bssid_length = g_slist_length(bssid_list); @@ -4817,6 +4828,10 @@ static void network_added(GSupplicantNetwork *supplicant_network) g_supplicant_network_is_hs20AP(supplicant_network)); connman_network_set_bssid_list(network, (GSList *)g_supplicant_network_get_bssid_list(supplicant_network)); + connman_network_set_last_connected_bssid(network, + g_supplicant_network_get_last_connected_bssid(supplicant_network)); + connman_network_set_assoc_reject_table(network, + g_supplicant_network_get_assoc_reject_table(supplicant_network)); #endif connman_network_set_available(network, true); connman_network_set_string(network, "WiFi.Mode", mode); @@ -4829,6 +4844,11 @@ static void network_added(GSupplicantNetwork *supplicant_network) connman_network_set_group(network, group); #if defined TIZEN_EXT + g_supplicant_network_set_last_connected_bssid(supplicant_network, + connman_network_get_last_connected_bssid(network)); +#endif + +#if defined TIZEN_EXT if (wifi_first_scan == true) found_with_first_scan = true; #endif @@ -4924,7 +4944,11 @@ static void network_changed(GSupplicantNetwork *network, const char *property) identifier = g_supplicant_network_get_identifier(network); name = g_supplicant_network_get_name(network); +#if defined TIZEN_EXT + DBG("name %s property %s", name, property); +#else DBG("name %s", name); +#endif if (!wifi) return; @@ -4964,7 +4988,35 @@ static void network_changed(GSupplicantNetwork *network, const char *property) connman_network_set_strength(connman_network, calculate_strength(network)); update_needed = true; - } else + } +#if defined TIZEN_EXT + else if (g_str_equal(property, "LastConnectedBSSID")) { + const char *ident, *group; + char *service_ident; + bool need_save; + + ident = connman_device_get_ident(wifi->device); + group = connman_network_get_group(connman_network); + if (ident && group) { + service_ident = g_strdup_printf("%s_%s_%s", + __connman_network_get_type(connman_network), ident, group); + + need_save = connman_device_set_last_connected_ident(wifi->device, service_ident); + if (need_save) + connman_device_save_last_connected(wifi->device); + } + + connman_network_set_last_connected_bssid(connman_network, + g_supplicant_network_get_last_connected_bssid(network)); + + update_needed = true; + } else if (g_str_equal(property, "UpdateAssocReject")) { + connman_network_set_assoc_reject_table(connman_network, + g_supplicant_network_get_assoc_reject_table(network)); + update_needed = true; + } +#endif + else update_needed = false; if (update_needed) @@ -5380,7 +5432,11 @@ static void scan_done(GSupplicantInterface *interface) static void debug(const char *str) { +#if defined TIZEN_EXT + if (connman_setting_get_bool("ConnmanSupplicantDebug")) +#else if (getenv("CONNMAN_SUPPLICANT_DEBUG")) +#endif connman_debug("%s", str); } @@ -5741,6 +5797,33 @@ static int tech_set_regdom(struct connman_technology *technology, const char *al return g_supplicant_set_country(alpha2, regdom_callback, NULL); } +#if defined TIZEN_EXT +static void supp_ins_init(void) +{ + const char *string; + GSupplicantINSPreferredFreq preferred_freq; + + string = connman_option_get_string("INSPreferredFreqBSSID"); + if (g_strcmp0(string, "5GHz") == 0) + preferred_freq = G_SUPPLICANT_INS_PREFERRED_FREQ_5GHZ; + else if (g_strcmp0(string, "2.4GHz") == 0) + preferred_freq = G_SUPPLICANT_INS_PREFERRED_FREQ_24GHZ; + else + preferred_freq = G_SUPPLICANT_INS_PREFERRED_FREQ_UNKNOWN; + + g_supplicant_set_ins_settings(preferred_freq, + connman_setting_get_bool("INSLastConnectedBSSID"), + connman_setting_get_bool("INSAssocReject"), + connman_setting_get_bool("INSSignalBSSID"), + connman_setting_get_uint("INSPreferredFreqBSSIDScore"), + connman_setting_get_uint("INSLastConnectedBSSIDScore"), + connman_setting_get_uint("INSAssocRejectScore"), + connman_setting_get_int("INSSignalLevel3_5GHz"), + connman_setting_get_int("INSSignalLevel3_24GHz") + ); +} +#endif + static struct connman_technology_driver tech_driver = { .name = "wifi", .type = CONNMAN_SERVICE_TYPE_WIFI, @@ -5774,6 +5857,10 @@ static int wifi_init(void) #if defined TIZEN_EXT failed_bssids = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); #endif + +#if defined TIZEN_EXT + supp_ins_init(); +#endif return 0; } diff --git a/src/connman.h b/src/connman.h old mode 100644 new mode 100755 index 57c3050..833e09a --- a/src/connman.h +++ b/src/connman.h @@ -279,6 +279,10 @@ GKeyFile *__connman_storage_open_global(void); GKeyFile *__connman_storage_load_global(void); int __connman_storage_save_global(GKeyFile *keyfile); void __connman_storage_delete_global(void); +#if defined TIZEN_EXT +GKeyFile *__connman_storage_load_ins(void); +int __connman_storage_save_ins(GKeyFile *keyfile); +#endif GKeyFile *__connman_storage_load_config(const char *ident); GKeyFile *__connman_storage_load_provider_config(const char *ident); diff --git a/src/device.c b/src/device.c old mode 100644 new mode 100755 index df7b2bb..2029871 --- a/src/device.c +++ b/src/device.c @@ -68,6 +68,11 @@ struct connman_device { char *last_network; struct connman_network *network; GHashTable *networks; +#if defined TIZEN_EXT + time_t last_user_selection_time; + char *last_user_selection_ident; + char *last_connected_ident; +#endif }; static void clear_pending_trigger(struct connman_device *device) @@ -423,6 +428,11 @@ static void device_destruct(struct connman_device *device) g_free(device->last_network); +#if defined TIZEN_EXT + g_free(device->last_user_selection_ident); + g_free(device->last_connected_ident); +#endif + g_free(device); } @@ -696,6 +706,194 @@ int connman_device_reconnect_service(struct connman_device *device) return 0; } +#if defined TIZEN_EXT +bool connman_device_set_last_user_selection_time(struct connman_device *device, + time_t time) +{ + if (device->last_user_selection_time != time) { + device->last_user_selection_time = time; + return true; + } + + return false; +} + +time_t connman_device_get_last_user_selection_time(struct connman_device *device) +{ + return device->last_user_selection_time; +} + +bool connman_device_set_last_user_selection_ident(struct connman_device *device, + const char *ident) +{ + if (g_strcmp0(device->last_user_selection_ident, ident) != 0) { + g_free(device->last_user_selection_ident); + device->last_user_selection_ident = g_strdup(ident); + + return true; + } + + return false; +} + +const char *connman_device_get_last_user_selection_ident(struct connman_device *device) +{ + return device->last_user_selection_ident; +} + +bool connman_device_set_last_connected_ident(struct connman_device *device, + const char *ident) +{ + if (g_strcmp0(device->last_connected_ident, ident) != 0) { + g_free(device->last_connected_ident); + device->last_connected_ident = g_strdup(ident); + + return true; + } + + return false; +} + +const char *connman_device_get_last_connected_ident(struct connman_device *device) +{ + return device->last_connected_ident; +} + +void connman_device_save_last_user_selection(struct connman_device *device) +{ + GKeyFile *keyfile; + gchar *get_str; + gchar *selection_str; + + keyfile = __connman_storage_load_ins(); + + selection_str = g_strdup_printf("%s:%ld", + device->last_user_selection_ident, device->last_user_selection_time); + + if (!keyfile) { + keyfile = g_key_file_new(); + + g_key_file_set_string(keyfile, device->interface, "LastUserSelection", selection_str); + DBG("%s", selection_str); + __connman_storage_save_ins(keyfile); + + } else { + get_str = g_key_file_get_string(keyfile, device->interface, "LastUserSelection", NULL); + if (!get_str || g_strcmp0(get_str, selection_str) != 0) { + g_key_file_set_string(keyfile, device->interface, "LastUserSelection", selection_str); + DBG("%s -> %s", get_str, selection_str); + __connman_storage_save_ins(keyfile); + } + + g_free(get_str); + } + + g_free(selection_str); + g_key_file_free(keyfile); +} + +void connman_device_load_last_user_selection(struct connman_device *device) +{ + GKeyFile *keyfile; + gchar *get_str; + char **selection_str; + + keyfile = __connman_storage_load_ins(); + if (!keyfile) + return; + + get_str = g_key_file_get_string(keyfile, device->interface, "LastUserSelection", NULL); + if (get_str) { + selection_str = g_strsplit(get_str, ":", 0); + if (selection_str) { + time_t ref_time; + struct tm* timeinfo; + time_t last_user_selection_time; + + /* Only events that occur within 8 hours are counted. */ + ref_time = time(NULL); + timeinfo = localtime(&ref_time); + timeinfo->tm_hour -= 8; + ref_time = mktime(timeinfo); + + last_user_selection_time = strtol(selection_str[1], NULL, 10); + + if (last_user_selection_time > ref_time) { + if (g_strcmp0(selection_str[0], device->last_user_selection_ident) != 0) { + g_free(device->last_user_selection_ident); + device->last_user_selection_ident = g_strdup(selection_str[0]); + } + + device->last_user_selection_time = last_user_selection_time; + + DBG("%s %ld", device->last_user_selection_ident, device->last_user_selection_time); + } + + g_strfreev(selection_str); + } + + g_free(get_str); + } + + g_key_file_free(keyfile); +} + +void connman_device_save_last_connected(struct connman_device *device) +{ + GKeyFile *keyfile; + gchar *get_str; + + if (!device->last_connected_ident) + return; + + keyfile = __connman_storage_load_ins(); + + if (!keyfile) { + keyfile = g_key_file_new(); + + g_key_file_set_string(keyfile, device->interface, "LastConnected", device->last_connected_ident); + DBG("%s", device->last_connected_ident); + __connman_storage_save_ins(keyfile); + + } else { + get_str = g_key_file_get_string(keyfile, device->interface, "LastConnected", NULL); + if (!get_str || g_strcmp0(get_str, device->last_connected_ident) != 0) { + g_key_file_set_string(keyfile, device->interface, "LastConnected", device->last_connected_ident); + DBG("%s -> %s", get_str, device->last_connected_ident); + __connman_storage_save_ins(keyfile); + } + + g_free(get_str); + } + + g_key_file_free(keyfile); +} + +void connman_device_load_last_connected(struct connman_device *device) +{ + GKeyFile *keyfile; + gchar *get_str; + + keyfile = __connman_storage_load_ins(); + if (!keyfile) + return; + + get_str = g_key_file_get_string(keyfile, device->interface, "LastConnected", NULL); + if (get_str) { + if (g_strcmp0(get_str, device->last_connected_ident) != 0) { + g_free(device->last_connected_ident); + device->last_connected_ident = g_strdup(get_str); + } + + DBG("%s", device->last_connected_ident); + + g_free(get_str); + } + + g_key_file_free(keyfile); +} +#endif + static void mark_network_available(gpointer key, gpointer value, gpointer user_data) { @@ -1531,6 +1729,10 @@ struct connman_device *connman_device_create_from_index(int index) connman_device_set_index(device, index); connman_device_set_interface(device, devname); +#if defined TIZEN_EXT + connman_device_load_last_connected(device); + connman_device_load_last_user_selection(device); +#endif if (ident) { connman_device_set_ident(device, ident); diff --git a/src/main.c b/src/main.c old mode 100644 new mode 100755 index 1fecef0..6dcdced --- a/src/main.c +++ b/src/main.c @@ -98,6 +98,7 @@ static struct { bool tizen_tv_extension; bool auto_ip; char *global_nameserver; + bool supplicant_debug; #endif } connman_settings = { .bg_scan = true, @@ -126,9 +127,66 @@ static struct { .tizen_tv_extension = false, .auto_ip = true, .global_nameserver = NULL, + .supplicant_debug = false, #endif }; +#if defined TIZEN_EXT +static struct { + /* BSSID */ + char *ins_preferred_freq_bssid; + bool ins_last_connected_bssid; + bool ins_assoc_reject; + bool ins_signal_bssid; + unsigned int ins_preferred_freq_bssid_score; + unsigned int ins_last_connected_bssid_score; + unsigned int ins_assoc_reject_score; + /* SSID */ + bool ins_last_user_selection; + unsigned int ins_last_user_selection_time; + bool ins_last_connected; + char *ins_preferred_freq; + char **ins_security_priority; + unsigned int ins_security_priority_count; + bool ins_signal; + bool ins_internet; + unsigned int ins_last_user_selection_score; + unsigned int ins_last_connected_score; + unsigned int ins_preferred_freq_score; + unsigned int ins_security_priority_score; + unsigned int ins_internet_score; + /* Common */ + int ins_signal_level3_5ghz; + int ins_signal_level3_24ghz; +} connman_ins_settings = { + /* BSSID */ + .ins_preferred_freq_bssid = NULL, + .ins_last_connected_bssid = true, + .ins_assoc_reject = true, + .ins_signal_bssid = true, + .ins_preferred_freq_bssid_score = 20, + .ins_last_connected_bssid_score = 20, + .ins_assoc_reject_score = 10, + /* SSID */ + .ins_last_user_selection = true, + .ins_last_user_selection_time = 480, + .ins_last_connected = true, + .ins_preferred_freq = NULL, + .ins_security_priority = NULL, + .ins_security_priority_count = 0, + .ins_signal = true, + .ins_internet = true, + .ins_last_user_selection_score = 30, + .ins_last_connected_score = 30, + .ins_preferred_freq_score = 60, + .ins_security_priority_score = 5, + .ins_internet_score = 30, + /* Common */ + .ins_signal_level3_5ghz = -76, + .ins_signal_level3_24ghz = -74, +}; +#endif + #define CONF_BG_SCAN "BackgroundScanning" #define CONF_PREF_TIMESERVERS "FallbackTimeservers" #define CONF_AUTO_CONNECT_TECHS "DefaultAutoConnectTechnologies" @@ -152,9 +210,38 @@ static struct { #define CONF_USE_GATEWAYS_AS_TIMESERVERS "UseGatewaysAsTimeservers" #if defined TIZEN_EXT #define CONF_CELLULAR_INTERFACE "NetworkCellularInterfaceList" -#define CONF_TIZEN_TV_EXT "TizenTVExtension" -#define CONF_ENABLE_AUTO_IP "EnableAutoIp" +#define CONF_TIZEN_TV_EXT "TizenTVExtension" +#define CONF_ENABLE_AUTO_IP "EnableAutoIp" #define CONF_GLOBAL_NAMESERVER "GlobalNameserver" +#define CONF_CONNMAN_SUPPLICANT_DEBUG "ConnmanSupplicantDebug" +#endif + +#if defined TIZEN_EXT +/* BSSID */ +#define CONF_INS_PREFERRED_FREQ_BSSID "INSPreferredFreqBSSID" +#define CONF_INS_PREFERRED_FREQ_BSSID_SCORE "INSPreferredFreqBSSIDScore" +#define CONF_INS_LAST_CONNECTED_BSSID "INSLastConnectedBSSID" +#define CONF_INS_LAST_CONNECTED_BSSID_SCORE "INSLastConnectedBSSIDScore" +#define CONF_INS_ASSOC_REJECT "INSAssocReject" +#define CONF_INS_ASSOC_REJECT_SCORE "INSAssocRejectScore" +#define CONF_INS_SIGNAL_BSSID "INSSignalBSSID" +/* SSID */ +#define CONF_INS_LAST_USER_SELECTION "INSLastUserSelection" +#define CONF_INS_LAST_USER_SELECTION_TIME "INSLastUserSelectionTime" +#define CONF_INS_LAST_USER_SELECTION_SCORE "INSLastUserSelectionScore" +#define CONF_INS_LAST_CONNECTED "INSLastConnected" +#define CONF_INS_LAST_CONNECTED_SCORE "INSLastConnectedScore" +#define CONF_INS_PREFERRED_FREQ "INSPreferredFreq" +#define CONF_INS_PREFERRED_FREQ_SCORE "INSPreferredFreqScore" +#define CONF_INS_SECURITY_PRIORITY "INSSecurityPriority" +#define CONF_INS_SECURITY_PRIORITY_COUNT "INSSecurityPriorityCount" +#define CONF_INS_SECURITY_PRIORITY_SCORE "INSSecurityPriorityScore" +#define CONF_INS_SIGNAL "INSSignal" +#define CONF_INS_INTERNET "INSInternet" +#define CONF_INS_INTERNET_SCORE "INSInternetScore" +/* Common */ +#define CONF_INS_SIGNAL_LEVEL3_5GHZ "INSSignalLevel3_5GHz" +#define CONF_INS_SIGNAL_LEVEL3_24GHZ "INSSignalLevel3_24GHz" #endif static const char *supported_options[] = { @@ -183,10 +270,42 @@ static const char *supported_options[] = { CONF_TIZEN_TV_EXT, CONF_ENABLE_AUTO_IP, CONF_GLOBAL_NAMESERVER, + CONF_CONNMAN_SUPPLICANT_DEBUG, #endif NULL }; +#if defined TIZEN_EXT +static const char *supported_ins_options[] = { + /* BSSID */ + CONF_INS_PREFERRED_FREQ_BSSID, + CONF_INS_PREFERRED_FREQ_BSSID_SCORE, + CONF_INS_LAST_CONNECTED_BSSID, + CONF_INS_LAST_CONNECTED_BSSID_SCORE, + CONF_INS_ASSOC_REJECT, + CONF_INS_ASSOC_REJECT_SCORE, + CONF_INS_SIGNAL_BSSID, + /* SSID */ + CONF_INS_LAST_USER_SELECTION, + CONF_INS_LAST_USER_SELECTION_TIME, + CONF_INS_LAST_USER_SELECTION_SCORE, + CONF_INS_LAST_CONNECTED, + CONF_INS_LAST_CONNECTED_SCORE, + CONF_INS_PREFERRED_FREQ, + CONF_INS_PREFERRED_FREQ_SCORE, + CONF_INS_SECURITY_PRIORITY, + CONF_INS_SECURITY_PRIORITY_COUNT, + CONF_INS_SECURITY_PRIORITY_SCORE, + CONF_INS_SIGNAL, + CONF_INS_INTERNET, + CONF_INS_INTERNET_SCORE, + /* Common */ + CONF_INS_SIGNAL_LEVEL3_5GHZ, + CONF_INS_SIGNAL_LEVEL3_24GHZ, + NULL +}; +#endif + static GKeyFile *load_config(const char *file) { GError *err = NULL; @@ -270,7 +389,12 @@ static void check_config(GKeyFile *config) keys = g_key_file_get_groups(config, NULL); for (j = 0; keys && keys[j]; j++) { +#if defined TIZEN_EXT + if (g_strcmp0(keys[j], "General") != 0 && + g_strcmp0(keys[j], "INS") != 0) +#else if (g_strcmp0(keys[j], "General") != 0) +#endif connman_warn("Unknown group %s in %s", keys[j], MAINFILE); } @@ -296,9 +420,192 @@ static void check_config(GKeyFile *config) } g_strfreev(keys); + +#if defined TIZEN_EXT + keys = g_key_file_get_keys(config, "INS", NULL, NULL); + + for (j = 0; keys && keys[j]; j++) { + bool found; + int i; + + found = false; + for (i = 0; supported_ins_options[i]; i++) { + if (g_strcmp0(keys[j], supported_ins_options[i]) == 0) { + found = true; + break; + } + } + if (!found && !supported_ins_options[i]) + connman_warn("Unknown option %s in %s", + keys[j], MAINFILE); + } + + g_strfreev(keys); +#endif } #if defined TIZEN_EXT +static void check_Tizen_INS_configuration(GKeyFile *config) +{ + GError *error = NULL; + char *ins_preferred_freq_bssid; + char *ins_preferred_freq; + char **ins_security_priority; + bool boolean; + int integer; + gsize len; + + ins_preferred_freq_bssid = __connman_config_get_string(config, "INS", + CONF_INS_PREFERRED_FREQ_BSSID, &error); + if (!error) + connman_ins_settings.ins_preferred_freq_bssid = ins_preferred_freq_bssid; + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_PREFERRED_FREQ_BSSID_SCORE, &error); + if (!error && integer >= 0) + connman_ins_settings.ins_preferred_freq_bssid_score = integer; + + g_clear_error(&error); + + boolean = __connman_config_get_bool(config, "INS", + CONF_INS_LAST_CONNECTED_BSSID, &error); + if (!error) + connman_ins_settings.ins_last_connected_bssid = boolean; + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_LAST_CONNECTED_BSSID_SCORE, &error); + if (!error && integer >= 0) + connman_ins_settings.ins_last_connected_bssid_score = integer; + + g_clear_error(&error); + + boolean = __connman_config_get_bool(config, "INS", + CONF_INS_ASSOC_REJECT, &error); + if (!error) + connman_ins_settings.ins_assoc_reject = boolean; + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_ASSOC_REJECT_SCORE, &error); + if (!error && integer >= 0) + connman_ins_settings.ins_assoc_reject_score = integer; + + g_clear_error(&error); + + boolean = __connman_config_get_bool(config, "INS", + CONF_INS_SIGNAL_BSSID, &error); + if (!error) + connman_ins_settings.ins_signal_bssid = boolean; + + g_clear_error(&error); + + boolean = __connman_config_get_bool(config, "INS", + CONF_INS_LAST_USER_SELECTION, &error); + if (!error) + connman_ins_settings.ins_last_user_selection = boolean; + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_LAST_USER_SELECTION_TIME, &error); + if (!error && integer >= 0) + connman_ins_settings.ins_last_user_selection_time = integer; + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_LAST_USER_SELECTION_SCORE, &error); + if (!error && integer >= 0) + connman_ins_settings.ins_last_user_selection_score = integer; + + g_clear_error(&error); + + boolean = __connman_config_get_bool(config, "INS", + CONF_INS_LAST_CONNECTED, &error); + if (!error) + connman_ins_settings.ins_last_connected = boolean; + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_LAST_CONNECTED_SCORE, &error); + if (!error && integer >= 0) + connman_ins_settings.ins_last_connected_score = integer; + + g_clear_error(&error); + + ins_preferred_freq = __connman_config_get_string(config, "INS", + CONF_INS_PREFERRED_FREQ, &error); + if (!error) + connman_ins_settings.ins_preferred_freq = ins_preferred_freq; + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_PREFERRED_FREQ_SCORE, &error); + if (!error && integer >= 0) + connman_ins_settings.ins_preferred_freq_score = integer; + + g_clear_error(&error); + + ins_security_priority = g_key_file_get_string_list(config, "INS", + CONF_INS_SECURITY_PRIORITY, &len, &error); + + if (error == NULL) { + connman_ins_settings.ins_security_priority = ins_security_priority; + connman_ins_settings.ins_security_priority_count = len; + } + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_SECURITY_PRIORITY_SCORE, &error); + if (!error && integer >= 0) + connman_ins_settings.ins_security_priority_score = integer; + + g_clear_error(&error); + + boolean = __connman_config_get_bool(config, "INS", + CONF_INS_SIGNAL, &error); + if (!error) + connman_ins_settings.ins_signal = boolean; + + g_clear_error(&error); + + boolean = __connman_config_get_bool(config, "INS", + CONF_INS_INTERNET, &error); + if (!error) + connman_ins_settings.ins_internet = boolean; + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_INTERNET_SCORE, &error); + if (!error && integer >= 0) + connman_ins_settings.ins_internet_score = integer; + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_SIGNAL_LEVEL3_5GHZ, &error); + if (!error) + connman_ins_settings.ins_signal_level3_5ghz = integer; + + g_clear_error(&error); + + integer = g_key_file_get_integer(config, "INS", + CONF_INS_SIGNAL_LEVEL3_24GHZ, &error); + if (!error) + connman_ins_settings.ins_signal_level3_24ghz = integer; + + g_clear_error(&error); +} + static void check_Tizen_configuration(GKeyFile *config) { GError *error = NULL; @@ -335,6 +642,15 @@ static void check_Tizen_configuration(GKeyFile *config) connman_settings.global_nameserver = global_nameserver; g_clear_error(&error); + + boolean = __connman_config_get_bool(config, "General", + CONF_CONNMAN_SUPPLICANT_DEBUG, &error); + if (!error) + connman_settings.supplicant_debug = boolean; + + g_clear_error(&error); + + check_Tizen_INS_configuration(config); } static void set_nofile_inc(void) @@ -752,6 +1068,14 @@ const char *connman_option_get_string(const char *key) if (g_str_equal(key, CONF_GLOBAL_NAMESERVER)) return connman_settings.global_nameserver; #endif + +#if defined TIZEN_EXT + if (g_str_equal(key, CONF_INS_PREFERRED_FREQ_BSSID)) + return connman_ins_settings.ins_preferred_freq_bssid; + + if (g_str_equal(key, CONF_INS_PREFERRED_FREQ)) + return connman_ins_settings.ins_preferred_freq; +#endif return NULL; } @@ -790,11 +1114,85 @@ bool connman_setting_get_bool(const char *key) #if defined TIZEN_EXT if (g_str_equal(key, CONF_ENABLE_AUTO_IP)) return connman_settings.auto_ip; + + if (g_str_equal(key, CONF_CONNMAN_SUPPLICANT_DEBUG)) + return connman_settings.supplicant_debug; +#endif + +#if defined TIZEN_EXT + if (g_str_equal(key, CONF_INS_LAST_CONNECTED_BSSID)) + return connman_ins_settings.ins_last_connected_bssid; + + if (g_str_equal(key, CONF_INS_ASSOC_REJECT)) + return connman_ins_settings.ins_assoc_reject; + + if (g_str_equal(key, CONF_INS_SIGNAL_BSSID)) + return connman_ins_settings.ins_signal_bssid; + + if (g_str_equal(key, CONF_INS_LAST_USER_SELECTION)) + return connman_ins_settings.ins_last_user_selection; + + if (g_str_equal(key, CONF_INS_LAST_CONNECTED)) + return connman_ins_settings.ins_last_connected; + + if (g_str_equal(key, CONF_INS_SIGNAL)) + return connman_ins_settings.ins_signal; + + if (g_str_equal(key, CONF_INS_INTERNET)) + return connman_ins_settings.ins_internet; #endif return false; } +#if defined TIZEN_EXT +unsigned int connman_setting_get_uint(const char *key) +{ + if (g_str_equal(key, CONF_INS_PREFERRED_FREQ_BSSID_SCORE)) + return connman_ins_settings.ins_preferred_freq_bssid_score; + + if (g_str_equal(key, CONF_INS_LAST_CONNECTED_BSSID_SCORE)) + return connman_ins_settings.ins_last_connected_bssid_score; + + if (g_str_equal(key, CONF_INS_ASSOC_REJECT_SCORE)) + return connman_ins_settings.ins_assoc_reject_score; + + if (g_str_equal(key, CONF_INS_LAST_USER_SELECTION_TIME)) + return connman_ins_settings.ins_last_user_selection_time; + + if (g_str_equal(key, CONF_INS_SECURITY_PRIORITY_COUNT)) + return connman_ins_settings.ins_security_priority_count; + + if (g_str_equal(key, CONF_INS_LAST_USER_SELECTION_SCORE)) + return connman_ins_settings.ins_last_user_selection_score; + + if (g_str_equal(key, CONF_INS_LAST_CONNECTED_SCORE)) + return connman_ins_settings.ins_last_connected_score; + + if (g_str_equal(key, CONF_INS_PREFERRED_FREQ_SCORE)) + return connman_ins_settings.ins_preferred_freq_score; + + if (g_str_equal(key, CONF_INS_SECURITY_PRIORITY_SCORE)) + return connman_ins_settings.ins_security_priority_score; + + if (g_str_equal(key, CONF_INS_INTERNET_SCORE)) + return connman_ins_settings.ins_internet_score; + + return 0; +} + +int connman_setting_get_int(const char *key) +{ + if (g_str_equal(key, CONF_INS_SIGNAL_LEVEL3_5GHZ)) + return connman_ins_settings.ins_signal_level3_5ghz; + + if (g_str_equal(key, CONF_INS_SIGNAL_LEVEL3_24GHZ)) + return connman_ins_settings.ins_signal_level3_24ghz; + + return 0; +} +#endif + char **connman_setting_get_string_list(const char *key) { if (g_str_equal(key, CONF_PREF_TIMESERVERS)) @@ -814,6 +1212,11 @@ char **connman_setting_get_string_list(const char *key) return connman_settings.cellular_interfaces; #endif +#if defined TIZEN_EXT + if (g_str_equal(key, CONF_INS_SECURITY_PRIORITY)) + return connman_ins_settings.ins_security_priority; +#endif + return NULL; } @@ -1032,6 +1435,13 @@ int main(int argc, char *argv[]) g_strfreev(connman_settings.blacklisted_interfaces); g_strfreev(connman_settings.tethering_technologies); +#if defined TIZEN_EXT + g_free(connman_ins_settings.ins_preferred_freq_bssid); + g_free(connman_ins_settings.ins_preferred_freq); + if (connman_ins_settings.ins_security_priority) + g_strfreev(connman_ins_settings.ins_security_priority); +#endif + g_free(option_debug); g_free(option_wifi); diff --git a/src/main.conf b/src/main.conf index ab0dc2d..6e26464 100755 --- a/src/main.conf +++ b/src/main.conf @@ -168,3 +168,37 @@ NetworkCellularInterfaceList = pdp,rmnet,seth_td,seth_w # if all nameservers are failed to resolve DNS query. The nameserver # entries must be in numeric format. # GlobalNameserver = 8.8.8.8 + +# Enable supplicant debugging log +ConnmanSupplicantDebug = false + +[INS] +# INS(Intelligent Network Selection) configuration: BSSID Selection. +INSPreferredFreqBSSID = 5GHz +INSPreferredFreqBSSIDScore = 20 +INSLastConnectedBSSID = true +INSLastConnectedBSSIDScore = 20 +INSAssocReject = true +INSAssocRejectScore = 10 +INSSignalBSSID = true + +# INS(Intelligent Network Selection) configuration: SSID Selection. +INSLastUserSelection = true +INSLastUserSelectionTime = 480 +INSLastUserSelectionScore = 30 +# (INSLastUserSelectionTime - selection time diff) / (INSLastUserSelectionTime / INSLastUserSelectionScore) +# This means '(480 - selection time) / x) <= 30' +INSLastConnected = true +INSLastConnectedScore = 30 +INSPreferredFreq = 5GHz +INSPreferredFreqScore = 60 +INSSecurityPriority = SAE,RSN +INSSecurityPriorityScore = 5 +# In this case, SAE(10 score), RSN(5 score) +INSSignal = true +INSInternet = true +INSInternetScore = 30 + +# INS(Intelligent Network Selection) configuration: Common. +INSSignalLevel3_5GHz = -76 +INSSignalLevel3_24GHz = -74 diff --git a/src/network.c b/src/network.c index d8756ec..f1183b3 100755 --- a/src/network.c +++ b/src/network.c @@ -52,6 +52,12 @@ #define DHCP_RETRY_TIMEOUT 10 +#if defined TIZEN_EXT +static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#endif + static GSList *network_list = NULL; static GSList *driver_list = NULL; @@ -131,6 +137,10 @@ struct connman_network { char *c_sign_key; char *net_access_key; #endif +#if defined TIZEN_EXT + unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX]; + GHashTable *assoc_reject_table; +#endif } wifi; #if defined TIZEN_EXT @@ -2509,6 +2519,45 @@ void *connman_network_get_bssid_list(struct connman_network *network) { return network->wifi.bssid_list; } + +int connman_network_set_last_connected_bssid(struct connman_network *network, + const unsigned char *bssid) +{ + if (!bssid) + return -EINVAL; + + if (!memcmp(bssid, invalid_bssid, WIFI_BSSID_LEN_MAX)) + return -EINVAL; + + memcpy(network->wifi.last_connected_bssid, bssid, WIFI_BSSID_LEN_MAX); + + return 0; +} + +unsigned char *connman_network_get_last_connected_bssid(struct connman_network *network) +{ + return (unsigned char *)network->wifi.last_connected_bssid; +} + +void connman_network_set_assoc_reject_table(struct connman_network *network, + GHashTable *assoc_reject_table) +{ + if (!network) + return; + + if (!assoc_reject_table) + return; + + network->wifi.assoc_reject_table = assoc_reject_table; +} + +GHashTable *connman_network_get_assoc_reject_table(struct connman_network *network) +{ + if (!network) + return NULL; + + return network->wifi.assoc_reject_table; +} #endif int connman_network_set_nameservers(struct connman_network *network, diff --git a/src/service.c b/src/service.c old mode 100644 new mode 100755 index cbedb34..606ef7d --- a/src/service.c +++ b/src/service.c @@ -44,6 +44,13 @@ #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 FREQ_RANGE_5GHZ_CHANNEL_165 5825 +#endif + static DBusConnection *connection = NULL; static GList *service_list = NULL; @@ -64,6 +71,38 @@ struct saved_profiles { #endif +#if defined TIZEN_EXT +enum connman_ins_preferred_freq { + CONNMAN_INS_PREFERRED_FREQ_UNKNOWN, + CONNMAN_INS_PREFERRED_FREQ_24GHZ, + CONNMAN_INS_PREFERRED_FREQ_5GHZ, +}; + +struct connman_ins_settings { + bool last_user_selection; + unsigned int last_user_selection_time; + unsigned int last_user_selection_score; + bool last_connected; + unsigned int last_connected_score; + enum connman_ins_preferred_freq preferred_freq; + unsigned int preferred_freq_score; + unsigned int security_priority[CONNMAN_SERVICE_SECURITY_MAX]; + unsigned int security_priority_count; + unsigned int security_priority_score; + bool signal; + bool internet; + unsigned int internet_score; + int signal_level3_5ghz; + int signal_level3_24ghz; +}; + +static struct connman_ins_settings ins_settings; + +static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#endif + struct connman_stats { bool valid; bool enabled; @@ -184,6 +223,12 @@ struct connman_service { 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; + int ins_score; +#endif }; static bool allow_property_changed(struct connman_service *service); @@ -200,6 +245,13 @@ struct find_data { }; #if defined TIZEN_EXT +struct assoc_reject_data { + char *bssid; + GSList *reject_time_list; +}; +#endif + +#if defined TIZEN_EXT /* * Public APIs to use user_pdn_connection_refcount */ @@ -572,6 +624,242 @@ int __connman_service_load_modifiable(struct connman_service *service) return 0; } +#if defined TIZEN_EXT +static void save_assoc_reject(gpointer key, gpointer value, gpointer user_data) +{ + struct assoc_reject_data *assoc_rd = value; + GString *assoc_reject_str = user_data; + GSList *list; + char *val_str; + + if (g_slist_length(assoc_rd->reject_time_list) < 1) + return; + + for (list = assoc_rd->reject_time_list; list; list = list->next) { + time_t assoc_reject_time = GPOINTER_TO_INT(list->data); + + val_str = g_strdup_printf("%s_%ld", assoc_rd->bssid, assoc_reject_time); + + if (assoc_reject_str->len > 0) + g_string_append_printf(assoc_reject_str, " %s", val_str); + else + g_string_append(assoc_reject_str, val_str); + + g_free(val_str); + } +} + +static void count_assoc_reject(gpointer key, gpointer value, gpointer user_data) +{ + struct assoc_reject_data *assoc_data = value; + int *assoc_reject_count = user_data; + + *assoc_reject_count += g_slist_length(assoc_data->reject_time_list); +} + +static bool update_assoc_reject(struct connman_service *service) +{ + GHashTable *assoc_reject_table; + int assoc_reject_count; + + if (!service->network) + return false; + + assoc_reject_table = connman_network_get_assoc_reject_table(service->network); + if (assoc_reject_table) { + assoc_reject_count = 0; + g_hash_table_foreach(assoc_reject_table, count_assoc_reject, &assoc_reject_count); +#if defined TIZEN_EXT_INS + DBG("assoc reject count [%d -> %d]", + service->assoc_reject_count, assoc_reject_count); +#endif + if (service->assoc_reject_count != assoc_reject_count) { + service->assoc_reject_count = assoc_reject_count; + return true; + } + } + + return false; +} + +static int service_ext_load(struct connman_service *service) +{ + GKeyFile *keyfile; + GHashTable *reject_table; + char **reject_list; + gsize reject_len; + struct assoc_reject_data *reject_data; + char **bssid_time; + char *bssid; + time_t reject_time; + time_t curr_time; + time_t ref_time; + struct tm* ref_timeinfo; + int i; + int err = 0; + + DBG("service %p", service); + + if (!service->network) + return -EINVAL; + + if (service->type != CONNMAN_SERVICE_TYPE_WIFI) + return -EINVAL; + + keyfile = connman_storage_load_service(service->identifier); + if (!keyfile) + return -EIO; + + reject_table = connman_network_get_assoc_reject_table(service->network); + + reject_list = g_key_file_get_string_list(keyfile, + service->identifier, "AssocReject", &reject_len, NULL); + + if (!reject_list || reject_len == 0) { + g_strfreev(reject_list); + goto done; + } + + /* Only events that occur within one hour are appened. */ + curr_time = time(NULL); + ref_timeinfo = localtime(&curr_time); + ref_timeinfo->tm_hour -= 1; + ref_time = mktime(ref_timeinfo); + + for (i = 0; reject_list[i]; i++) { + bssid_time = g_strsplit(reject_list[i], "_", 0); + if (!bssid_time) { + err = -ERANGE; + continue; + } + + bssid = bssid_time[0]; + reject_time = strtol(bssid_time[1], NULL, 10); + + if (reject_time < ref_time) { + g_strfreev(bssid_time); + err = -ERANGE; + continue; + } + + reject_data = g_hash_table_lookup(reject_table, bssid); + if (!reject_data) { + reject_data = g_try_new0(struct assoc_reject_data, 1); + if (!reject_data) { + g_strfreev(bssid_time); + err = -ERANGE; + continue; + } + + memset(reject_data, 0, sizeof(struct assoc_reject_data)); + reject_data->bssid = g_strdup(bssid); + g_hash_table_insert(reject_table, reject_data->bssid, reject_data); + } + + reject_data->reject_time_list = g_slist_append(reject_data->reject_time_list, + GINT_TO_POINTER(reject_time)); + +#if defined TIZEN_EXT_INS + DBG("assoc reject [%s_%ld]", bssid, reject_time); +#endif + + g_strfreev(bssid_time); + } + + g_strfreev(reject_list); + +done: + g_key_file_free(keyfile); + return err; +} + +static int service_ext_save(struct connman_service *service) +{ + GKeyFile *keyfile; + GHashTable *reject_table; + GString *reject_str; + char **reject_list; + guint reject_len; + int err = 0; + + DBG("service %p", service); + + if (!service->network) + return -EINVAL; + + if (service->type != CONNMAN_SERVICE_TYPE_WIFI) + return -EINVAL; + + keyfile = __connman_storage_open_service(service->identifier); + if (!keyfile) + return -EIO; + + /* Last connected BSSID */ + if (memcmp(service->last_connected_bssid, invalid_bssid, WIFI_BSSID_LEN_MAX)) { + char *identifier = service->identifier; + GString *bssid_str; + unsigned int i; + + bssid_str = g_string_sized_new(MAC_ADDRESS_LENGTH); + if (!bssid_str) { + err = -ENOMEM; + goto next; + } + + for (i = 0; i < WIFI_BSSID_LEN_MAX; i++) { + g_string_append_printf(bssid_str, + "%02x", service->last_connected_bssid[i]); + if (i < WIFI_BSSID_LEN_MAX - 1) + g_string_append(bssid_str, ":"); + } + + g_key_file_set_string(keyfile, identifier, + "LastConnectedBSSID", bssid_str->str); + +#if defined TIZEN_EXT_INS + DBG("last connected bssid[%s]", bssid_str->str); +#endif + + g_string_free(bssid_str, TRUE); + } + +next: + + /* Assoc reject */ + reject_table = connman_network_get_assoc_reject_table(service->network); + if (reject_table && g_hash_table_size(reject_table) > 0) { + reject_str = g_string_new(NULL); + if (!reject_str) { + err = -ENOMEM; + goto done; + } + + g_hash_table_foreach(reject_table, save_assoc_reject, reject_str); + + reject_list = g_strsplit_set(reject_str->str, " ", 0); + reject_len = g_strv_length(reject_list); + + g_key_file_set_string_list(keyfile, service->identifier, + "AssocReject", (const gchar **)reject_list, reject_len); + +#if defined TIZEN_EXT_INS + DBG("assoc reject table [%d]", reject_len); +#endif + + g_strfreev(reject_list); + g_string_free(reject_str, TRUE); + } else { + g_key_file_remove_key(keyfile, service->identifier, "AssocReject", NULL); + } + +done: + __connman_storage_save_service(keyfile, service->identifier); + + g_key_file_free(keyfile); + return err; +} +#endif + static int service_load(struct connman_service *service) { GKeyFile *keyfile; @@ -581,6 +869,9 @@ static int service_load(struct connman_service *service) bool autoconnect; unsigned int ssid_len; int err = 0; +#if defined TIZEN_EXT + bool internet_connection; +#endif DBG("service %p", service); @@ -661,6 +952,46 @@ static int service_load(struct connman_service *service) g_free(hex_ssid); } + +#if defined TIZEN_EXT + /* Last connected BSSID */ + if (service->network) { + gchar *bssid_str; + unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX]; + char **str_list; + unsigned int i; + + bssid_str = g_key_file_get_string(keyfile, + service->identifier, "LastConnectedBSSID", NULL); + + if (bssid_str) { + str_list = g_strsplit(bssid_str, ":", 0); + + if (str_list) { + for (i = 0; i < WIFI_BSSID_LEN_MAX; i++) + last_connected_bssid[i] = strtol(str_list[i], NULL, 16); + + memcpy(service->last_connected_bssid, + last_connected_bssid, WIFI_BSSID_LEN_MAX); + + connman_network_set_last_connected_bssid(service->network, + last_connected_bssid); + + g_strfreev(str_list); + } + + g_free(bssid_str); + } + } + + /* Internet connection */ + internet_connection = g_key_file_get_boolean(keyfile, + service->identifier, "InternetConnection", &error); + if (!error) + service->is_internet_connection = internet_connection; + + g_clear_error(&error); +#endif /* fall through */ case CONNMAN_SERVICE_TYPE_GADGET: @@ -899,6 +1230,9 @@ static int service_save(struct connman_service *service) if (service->network) { const unsigned char *ssid; unsigned int ssid_len = 0; +#if defined TIZEN_EXT + GHashTable *assoc_reject_table; +#endif ssid = connman_network_get_blob(service->network, "WiFi.SSID", &ssid_len); @@ -927,6 +1261,74 @@ static int service_save(struct connman_service *service) freq = connman_network_get_frequency(service->network); g_key_file_set_integer(keyfile, service->identifier, "Frequency", freq); + +#if defined TIZEN_EXT + /* Last connected BSSID */ + if (memcmp(service->last_connected_bssid, invalid_bssid, WIFI_BSSID_LEN_MAX)) { + char *identifier = service->identifier; + GString *bssid_str; + unsigned int i; + + bssid_str = g_string_sized_new(18); + if (!bssid_str) { + err = -ENOMEM; + goto done; + } + + for (i = 0; i < WIFI_BSSID_LEN_MAX; i++) { + g_string_append_printf(bssid_str, + "%02x", service->last_connected_bssid[i]); + if (i < WIFI_BSSID_LEN_MAX - 1) + g_string_append(bssid_str, ":"); + } + + g_key_file_set_string(keyfile, identifier, + "LastConnectedBSSID", bssid_str->str); + +#if defined TIZEN_EXT_INS + DBG("last connected bssid[%s]", bssid_str->str); +#endif + + g_string_free(bssid_str, TRUE); + } + + /* Assoc reject */ + assoc_reject_table = connman_network_get_assoc_reject_table(service->network); + if (assoc_reject_table && g_hash_table_size(assoc_reject_table) > 0) { + GString *assoc_reject_str; + char **assoc_reject_list; + guint assoc_reject_len; + + assoc_reject_str = g_string_new(NULL); + if (!assoc_reject_str) { + err = -ENOMEM; + goto done; + } + + g_hash_table_foreach(assoc_reject_table, save_assoc_reject, assoc_reject_str); + + assoc_reject_list = g_strsplit_set(assoc_reject_str->str, " ", 0); + assoc_reject_len = g_strv_length(assoc_reject_list); + + g_key_file_set_string_list(keyfile, service->identifier, + "AssocReject", (const gchar **)assoc_reject_list, assoc_reject_len); + +#if defined TIZEN_EXT_INS + DBG("assoc reject table [%d]", assoc_reject_len); +#endif + + g_strfreev(assoc_reject_list); + g_string_free(assoc_reject_str, TRUE); + } else + g_key_file_remove_key(keyfile, service->identifier, "AssocReject", NULL); + + /* Internet connection */ + g_key_file_set_boolean(keyfile, service->identifier, + "InternetConnection", service->is_internet_connection); +#if defined TIZEN_EXT_INS + DBG("internet connection [%s]", service->is_internet_connection ? "true" : "false"); +#endif +#endif } /* fall through */ @@ -2353,12 +2755,31 @@ static void state_changed(struct connman_service *service) #if defined TIZEN_EXT static void connect_reason_changed(struct connman_service *service) { + struct connman_device *device; + if (!service->path) return; if (!allow_property_changed(service)) return; + if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) { + device = connman_network_get_device(service->network); + if (device) { + bool need_save = false; + + need_save |= connman_device_set_last_user_selection_ident(device, service->identifier); + need_save |= connman_device_set_last_user_selection_time(device, time(NULL)); + + DBG("last user selection ident[%s] time[%ld]", + connman_device_get_last_user_selection_ident(device), + connman_device_get_last_user_selection_time(device)); + + if (need_save) + connman_device_save_last_user_selection(device); + } + } + connman_dbus_property_changed_basic(service->path, CONNMAN_SERVICE_INTERFACE, "ConnectReason", @@ -2408,6 +2829,27 @@ static void strength_changed(struct connman_service *service) DBUS_TYPE_BYTE, &service->strength); } +#if defined TIZEN_EXT +static bool update_last_connected_bssid(struct connman_service *service) +{ + const unsigned char *last_connected_bssid; + + if (!service->network) + return false; + + last_connected_bssid = connman_network_get_last_connected_bssid(service->network); + if (memcmp(last_connected_bssid, invalid_bssid, WIFI_BSSID_LEN_MAX) == 0) + return false; + + if (memcmp(last_connected_bssid, service->last_connected_bssid, WIFI_BSSID_LEN_MAX) != 0) { + memcpy(service->last_connected_bssid, last_connected_bssid, WIFI_BSSID_LEN_MAX); + return true; + } + + return false; +} +#endif + static void favorite_changed(struct connman_service *service) { dbus_bool_t favorite; @@ -4016,6 +4458,30 @@ const char *connman_service_get_proxy_url(struct connman_service *service) return service->pac; } +#if defined TIZEN_EXT +void connman_service_set_internet_connection(struct connman_service *service, + bool internet_connection) +{ + if (!service) + return; + + if (service->is_internet_connection != internet_connection) { + service->is_internet_connection = internet_connection; + + g_get_current_time(&service->modified); + service_save(service); + } +} + +bool connman_service_get_internet_connection(struct connman_service *service) +{ + if (!service) + return false; + + return service->is_internet_connection; +} +#endif + void __connman_service_set_proxy_autoconfig(struct connman_service *service, const char *url) { @@ -6536,6 +7002,11 @@ static void service_initialize(struct connman_service *service) service->wps = false; service->wps_advertizing = false; #if defined TIZEN_EXT + 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; /* @@ -6632,13 +7103,173 @@ void connman_service_unref_debug(struct connman_service *service, g_hash_table_remove(service_hash, service->identifier); } +#if defined TIZEN_EXT +static int calculate_score_last_user_selection(struct connman_service *service) +{ + int score = 0; + struct connman_device *device; + const char *last_user_selection_ident; + time_t last_user_selection_time; + unsigned int frequency; + time_t curr_time; + time_t ref_time; + struct tm* ref_timeinfo; + + device = connman_network_get_device(service->network); + 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); + + if (ins_settings.last_user_selection) { + if (g_strcmp0(last_user_selection_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))) { + + /* Only events that occur within 8 hours are counted. */ + curr_time = time(NULL); + ref_timeinfo = localtime(&curr_time); + ref_timeinfo->tm_hour -= 8; + ref_time = mktime(ref_timeinfo); + + if (last_user_selection_time > ref_time) { + int time_diff = (curr_time - last_user_selection_time) / 60; + int denominator = ins_settings.last_user_selection_time - time_diff; + int numerator = ins_settings.last_user_selection_time / + ins_settings.last_user_selection_score; + int last_user_score = denominator / numerator; + + score += (last_user_score > ins_settings.last_user_selection_score ? + ins_settings.last_user_selection_score : last_user_score); + } + } + } + + return score; +} + +static int calculate_score_last_connected(struct connman_service *service) +{ + int score = 0; + struct connman_device *device; + const char *last_connected_ident; + unsigned int frequency; + + device = connman_network_get_device(service->network); + 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; + } + + return score; +} + +static int calculate_score_frequency(struct connman_service *service) +{ + int score = 0; + unsigned int frequency; + + frequency = connman_network_get_frequency(service->network); + + switch (ins_settings.preferred_freq) { + case CONNMAN_INS_PREFERRED_FREQ_24GHZ: + if ((frequency >= FREQ_RANGE_24GHZ_CHANNEL_14 && + frequency <= FREQ_RANGE_24GHZ_CHANNEL_14) && + (service->strength >= ins_settings.signal_level3_24ghz)) + score += ins_settings.preferred_freq_score; + + break; + case CONNMAN_INS_PREFERRED_FREQ_5GHZ: + if ((frequency >= FREQ_RANGE_5GHZ_CHANNEL_32 && + frequency <= FREQ_RANGE_5GHZ_CHANNEL_165) && + (service->strength >= ins_settings.signal_level3_5ghz)) + score += ins_settings.preferred_freq_score; + + break; + default: + break; + } + + return score; +} + +static int calculate_score_security_priority(struct connman_service *service) +{ + int score = 0; + + if (ins_settings.security_priority_count) + score += ins_settings.security_priority[service->security]; + + return score; +} + +static int calculate_score_internet_connection(struct connman_service *service) +{ + int score = 0; + + if (ins_settings.internet) { + if (service->is_internet_connection) + score += ins_settings.internet_score; + } + + return score; +} + +static int calculate_score_strength(struct connman_service *service) +{ + int score = 0; + + if (ins_settings.signal) + score += (((service->strength > 60) ? 60 : service->strength) - 35); + + return score; +} + +static int calculate_score(struct connman_service *service) +{ + int score = 0; + + if (service->type != CONNMAN_SERVICE_TYPE_WIFI) { + score += calculate_score_internet_connection(service); + service->ins_score = score; + return score; + } + + score += calculate_score_last_user_selection(service); + score += calculate_score_last_connected(service); + score += calculate_score_frequency(service); + score += calculate_score_security_priority(service); + score += calculate_score_internet_connection(service); + score += calculate_score_strength(service); + + service->ins_score = score; + return score; +} +#endif + static gint service_compare(gconstpointer a, gconstpointer b) { struct connman_service *service_a = (void *) a; struct connman_service *service_b = (void *) b; enum connman_service_state state_a, state_b; bool a_connected, b_connected; +#if defined TIZEN_EXT + int score_a; + int score_b; +#else gint strength; +#endif state_a = service_a->state; state_b = service_b->state; @@ -6727,17 +7358,60 @@ static gint service_compare(gconstpointer a, gconstpointer b) return 1; } +#if defined TIZEN_EXT + score_a = calculate_score(service_a); + score_b = calculate_score(service_b); + if (score_b != score_a) + return score_b - score_a; +#else strength = (gint) service_b->strength - (gint) service_a->strength; if (strength) return strength; +#endif return g_strcmp0(service_a->name, service_b->name); } +#if defined TIZEN_EXT_INS +static void print_service_sort(gpointer data, gpointer user_data) +{ + struct connman_service *service = data; + struct connman_device *device; + const char *last_user_selection_ident; + const char *last_connected_ident; + unsigned int frequency; + time_t ref_time; + struct tm* timeinfo; + time_t last_user_selection_time; + + device = connman_network_get_device(service->network); + last_user_selection_ident = connman_device_get_last_user_selection_ident(device); + last_user_selection_time = connman_device_get_last_user_selection_time(device); + last_connected_ident = connman_device_get_last_connected_ident(device); + frequency = connman_network_get_frequency(service->network); + + /* Only events that occur within 8 hours are checked. */ + ref_time = time(NULL); + timeinfo = localtime(&ref_time); + timeinfo->tm_hour -= 8; + ref_time = mktime(timeinfo); + + DBG("name[%s] score[%d] strength[%d] freq[%d] last_usr[%d] last_conn[%d] internet[%d]", + service->name, service->ins_score, service->strength, frequency, + (g_strcmp0(last_user_selection_ident, service->identifier) == 0 && + last_user_selection_time > ref_time) ? 1 : 0, + g_strcmp0(last_connected_ident, service->identifier) == 0 ? 1 : 0, + service->is_internet_connection); +} +#endif + 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 + g_list_foreach(service_list, print_service_sort, NULL); +#endif service_schedule_changed(); } } @@ -7657,6 +8331,10 @@ static int service_indicate_state(struct connman_service *service) single_connected_tech(service); #endif +#if defined TIZEN_EXT + if (service->type == CONNMAN_SERVICE_TYPE_WIFI) + connman_service_set_internet_connection(service, true); +#endif break; case CONNMAN_SERVICE_STATE_DISCONNECT: @@ -8784,8 +9462,12 @@ static int service_register(struct connman_service *service) DBG("path %s", service->path); #if defined TIZEN_EXT + int ret; service_load(service); - int ret = __connman_config_provision_service(service); + ret = service_ext_load(service); + if (ret == -ERANGE) + service_ext_save(service); + ret = __connman_config_provision_service(service); if (ret < 0) DBG("Failed to provision service"); #else @@ -9416,6 +10098,9 @@ void __connman_service_update_from_network(struct connman_network *network) bool roaming; const char *name; bool stats_enable; +#if defined TIZEN_EXT + bool need_save = false; +#endif service = connman_service_lookup_from_network(network); if (!service) @@ -9472,6 +10157,16 @@ roaming: roaming_changed(service); sorting: +#if defined TIZEN_EXT + need_save |= update_last_connected_bssid(service); + need_save |= update_assoc_reject(service); + if (need_save) { + g_get_current_time(&service->modified); + service_ext_save(service); + need_sort = true; + } +#endif + if (need_sort) { service_list_sort(); } @@ -9654,6 +10349,94 @@ static struct connman_agent_driver agent_driver = { .context_unref = agent_context_unref, }; +#if defined TIZEN_EXT +static void ins_setting_init(void) +{ + int i; + const char *string; + char **string_list; + unsigned int string_count; + + ins_settings.last_user_selection = connman_setting_get_bool("INSLastUserSelection"); + 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"); + if (g_str_equal(string, "5GHz")) + ins_settings.preferred_freq = CONNMAN_INS_PREFERRED_FREQ_5GHZ; + else if (g_str_equal(string, "2.4GHz")) + ins_settings.preferred_freq = CONNMAN_INS_PREFERRED_FREQ_24GHZ; + else + ins_settings.preferred_freq = CONNMAN_INS_PREFERRED_FREQ_UNKNOWN; + + ins_settings.security_priority_count = connman_setting_get_uint("INSSecurityPriorityCount"); + ins_settings.security_priority_score = connman_setting_get_uint("INSSecurityPriorityScore"); + string_count = ins_settings.security_priority_count; + + memset(ins_settings.security_priority, 0, sizeof(ins_settings.security_priority)); + string_list = connman_setting_get_string_list("INSSecurityPriority"); + for (i = 0; string_list && string_list[i]; i++) { + unsigned int security_score = string_count * ins_settings.security_priority_score; + + if (g_str_equal(string_list[i], "WEP")) + ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_WEP] = security_score; + else if (g_str_equal(string_list[i], "PSK")) + ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_PSK] = security_score; + else if (g_str_equal(string_list[i], "8021X")) + ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_8021X] = security_score; + else if (g_str_equal(string_list[i], "WPA")) + ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_WPA] = security_score; + else if (g_str_equal(string_list[i], "RSN")) + ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_RSN] = security_score; + else if (g_str_equal(string_list[i], "SAE")) + ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_SAE] = security_score; + else if (g_str_equal(string_list[i], "OWE")) + ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_OWE] = security_score; + else if (g_str_equal(string_list[i], "DPP")) + ins_settings.security_priority[CONNMAN_SERVICE_SECURITY_DPP] = security_score; + + string_count--; + } + + ins_settings.signal = connman_setting_get_bool("INSSignal"); + ins_settings.internet = connman_setting_get_bool("INSInternet"); + + ins_settings.last_user_selection_score = connman_setting_get_uint("INSLastUserSelectionScore"); + ins_settings.last_connected_score = connman_setting_get_uint("INSLastConnectedScore"); + 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"); + + 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("last_user_selection_score [%d]", ins_settings.last_user_selection_score); + + DBG("last_connected [%s]", ins_settings.last_connected ? "true" : "false"); + DBG("last_connected_score [%d]", ins_settings.last_connected_score); + + DBG("preferred_freq [%s]", ins_settings.preferred_freq ? "true" : "false"); + DBG("preferred_freq_score [%d]", ins_settings.preferred_freq_score); + + DBG("security_priority_count [%d]", ins_settings.security_priority_count); + for (i = 0; i < CONNMAN_SERVICE_SECURITY_MAX; i++) { + if (ins_settings.security_priority[i]) + DBG("security_priority %s [%d]", security2string(i), + ins_settings.security_priority[i]); + } + DBG("security_priority_score [%d]", ins_settings.security_priority_score); + + DBG("signal [%s]", ins_settings.signal ? "true" : "false"); + + DBG("internet [%s]", ins_settings.internet ? "true" : "false"); + DBG("internet_score [%d]", ins_settings.internet_score); + + DBG("signal_level3_5ghz [%d]", ins_settings.signal_level3_5ghz); + DBG("signal_level3_24ghz [%d]", ins_settings.signal_level3_24ghz); +} +#endif + int __connman_service_init(void) { int err; @@ -9681,6 +10464,10 @@ int __connman_service_init(void) remove_unprovisioned_services(); +#if defined TIZEN_EXT + ins_setting_init(); +#endif + return 0; } diff --git a/src/storage.c b/src/storage.c index 6ca600b..277e5f5 100755 --- a/src/storage.c +++ b/src/storage.c @@ -35,6 +35,9 @@ #define SETTINGS "settings" #define DEFAULT "default.profile" +#if defined TIZEN_EXT +#define INS_SETTINGS "settings.ins" +#endif #define MODE (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | \ S_IXGRP | S_IROTH | S_IXOTH) @@ -130,6 +133,40 @@ int __connman_storage_save_global(GKeyFile *keyfile) return ret; } +#if defined TIZEN_EXT +GKeyFile *__connman_storage_load_ins(void) +{ + gchar *pathname; + GKeyFile *keyfile = NULL; + + pathname = g_strdup_printf("%s/%s", STORAGEDIR, INS_SETTINGS); + if (!pathname) + return NULL; + + keyfile = storage_load(pathname); + + g_free(pathname); + + return keyfile; +} + +int __connman_storage_save_ins(GKeyFile *keyfile) +{ + gchar *pathname; + int ret; + + pathname = g_strdup_printf("%s/%s", STORAGEDIR, INS_SETTINGS); + if (!pathname) + return -ENOMEM; + + ret = storage_save(keyfile, pathname); + + g_free(pathname); + + return ret; +} +#endif + void __connman_storage_delete_global(void) { gchar *pathname; diff --git a/src/wispr.c b/src/wispr.c old mode 100644 new mode 100755 index 57abdf1..62f6b8d --- a/src/wispr.c +++ b/src/wispr.c @@ -422,6 +422,10 @@ static void wispr_portal_error(struct connman_wispr_portal_context *wp_context) DBG("Failed to proceed wispr/portal web request"); wp_context->wispr_result = CONNMAN_WISPR_RESULT_FAILED; + +#if defined TIZEN_EXT + connman_service_set_internet_connection(wp_context->service, false); +#endif } static void portal_manage_status(GWebResult *result, diff --git a/vpn/main.c b/vpn/main.c index c18fee4..474c62f 100755 --- a/vpn/main.c +++ b/vpn/main.c @@ -232,6 +232,18 @@ bool connman_setting_get_bool(const char *key) return false; } +#if defined TIZEN_EXT +unsigned int connman_setting_get_uint(const char *key) +{ + return 0; +} + +int connman_setting_get_int(const char *key) +{ + return 0; +} +#endif + char **connman_setting_get_string_list(const char *key) { return NULL;