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;
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);
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);
#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;
{ }
};
+#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;
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;
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 {
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);
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);
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)
{
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));
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
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;
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);
* 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);
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)
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)
{
return;
interface->current_network = network;
+#if defined TIZEN_EXT
+ SUPPLICANT_DBG("current network [%p]", interface->current_network);
+#endif
if (bss != network->best_bss) {
/*
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;
}
}
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);
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",
* 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);
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);
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);
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);
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;
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);
CONNMAN_SERVICE_SECURITY_OWE = 11,
CONNMAN_SERVICE_SECURITY_DPP = 12,
#endif
+#if defined TIZEN_EXT
+ CONNMAN_SERVICE_SECURITY_MAX
+#endif
};
enum connman_service_state {
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
#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);
Name: connman
Version: 1.37
-Release: 35
+Release: 36
License: GPL-2.0+
Summary: Connection Manager
Url: http://connman.net
#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);
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);
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
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;
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)
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);
}
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,
#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;
}
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);
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)
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);
}
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)
{
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);
bool tizen_tv_extension;
bool auto_ip;
char *global_nameserver;
+ bool supplicant_debug;
#endif
} connman_settings = {
.bg_scan = true,
.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"
#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[] = {
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;
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);
}
}
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;
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)
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;
}
#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))
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;
}
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);
# 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
#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;
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
{
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,
#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;
#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;
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);
};
#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
*/
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;
bool autoconnect;
unsigned int ssid_len;
int err = 0;
+#if defined TIZEN_EXT
+ bool internet_connection;
+#endif
DBG("service %p", 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:
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);
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 */
#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",
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;
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)
{
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;
/*
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;
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();
}
}
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:
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
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)
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();
}
.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;
remove_unprovisioned_services();
+#if defined TIZEN_EXT
+ ins_setting_init();
+#endif
+
return 0;
}
#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)
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;
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,
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;