summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhyunuk.tak <hyunuk.tak@samsung.com>2020-04-07 12:57:45 +0900
committerhyunuk.tak <hyunuk.tak@samsung.com>2020-04-16 12:39:44 +0900
commit70730f50e09cac648b1c3b48f0a1e6ed40cc510f (patch)
tree649a28589e37dd9ce5b1d17a18aa32ac2e418a7e
parente1c81b4af01d7f63325a516cc298097cf18d5c73 (diff)
downloadconnman-70730f50e09cac648b1c3b48f0a1e6ed40cc510f.tar.gz
connman-70730f50e09cac648b1c3b48f0a1e6ed40cc510f.tar.bz2
connman-70730f50e09cac648b1c3b48f0a1e6ed40cc510f.zip
Change-Id: I049207e7d662f657ca21a4046be953f8f33bbd10 Signed-off-by: hyunuk.tak <hyunuk.tak@samsung.com>
-rwxr-xr-x[-rw-r--r--]gsupplicant/gsupplicant.h24
-rwxr-xr-x[-rw-r--r--]gsupplicant/supplicant.c525
-rwxr-xr-x[-rw-r--r--]include/device.h16
-rwxr-xr-xinclude/network.h8
-rwxr-xr-x[-rw-r--r--]include/service.h9
-rwxr-xr-xinclude/setting.h4
-rw-r--r--packaging/connman.spec2
-rwxr-xr-xplugins/wifi.c89
-rwxr-xr-x[-rw-r--r--]src/connman.h4
-rwxr-xr-x[-rw-r--r--]src/device.c202
-rwxr-xr-x[-rw-r--r--]src/main.c414
-rwxr-xr-xsrc/main.conf34
-rwxr-xr-xsrc/network.c49
-rwxr-xr-x[-rw-r--r--]src/service.c789
-rwxr-xr-xsrc/storage.c37
-rwxr-xr-x[-rw-r--r--]src/wispr.c4
-rwxr-xr-xvpn/main.c12
17 files changed, 2199 insertions, 23 deletions
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index 3e513489..6dfd9c72 100644..100755
--- 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
index 2e8af6ae..957312cd 100644..100755
--- 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
index 77c476a4..98c7bd87 100644..100755
--- 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 14b94429..8cefb796 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
index 03371860..617735e0 100644..100755
--- 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 a8820217..3625f3e3 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 f4fa2a99..31ab4ca7 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 bbfdbf93..bce1424f 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
index 57c30508..833e09a1 100644..100755
--- 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
index df7b2bbc..2029871e 100644..100755
--- 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
index 1fecef07..6dcdced6 100644..100755
--- 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 ab0dc2db..6e26464e 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 d8756ec1..f1183b37 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
index cbedb34e..606ef7da 100644..100755
--- 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 6ca600b2..277e5f53 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
index 57abdf1e..62f6b8db 100644..100755
--- 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 c18fee4f..474c62fb 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;