CONNMAN_SESSION_ROAMING_POLICY_INTERNATIONAL = 5,
};
+struct service_entry {
+ struct connman_service *service;
+};
+
struct session_info {
char *bearer;
const char *name;
/* track why this service was selected */
enum connman_session_reason reason;
- struct connman_service *service;
+ struct service_entry *entry;
};
struct connman_session {
struct session_info *info = &session->info;
struct session_info *info_last = &session->info_last;
const char *policy;
+ struct connman_service *service;
if (session->append_all == TRUE ||
info->bearer != info_last->bearer) {
}
if (session->append_all == TRUE ||
- info->service != info_last->service) {
+ info->entry != info_last->entry) {
+ if (info->entry == NULL)
+ service = NULL;
+ else
+ service = info->entry->service;
+
connman_dbus_dict_append_dict(dict, "IPv4",
append_ipconfig_ipv4,
- info->service);
+ service);
connman_dbus_dict_append_dict(dict, "IPv6",
append_ipconfig_ipv6,
- info->service);
+ service);
connman_dbus_dict_append_basic(dict, "Interface",
DBUS_TYPE_STRING,
&info->ifname);
info_last->ifname = info->ifname;
- info_last->service = info->service;
+ info_last->entry = info->entry;
}
connman_dbus_setting_changed_dict(session->owner, session->notify_path,
"IPv4", append_ipconfig_ipv4,
- info->service);
+ info->entry->service);
}
static void ipconfig_ipv6_changed(struct connman_session *session)
connman_dbus_setting_changed_dict(session->owner, session->notify_path,
"IPv6", append_ipconfig_ipv6,
- info->service);
+ info->entry->service);
}
static connman_bool_t service_type_match(struct connman_session *session,
g_hash_table_destroy(session->service_hash);
g_sequence_free(session->service_list);
- if (info->service != NULL &&
+ if (info->entry != NULL &&
info->reason == CONNMAN_SESSION_REASON_CONNECT) {
- __connman_service_disconnect(info->service);
+ __connman_service_disconnect(info->entry->service);
}
g_slist_foreach(info->allowed_bearers, cleanup_bearer_info, NULL);
enum connman_service_type type;
int idx;
- if (info->service != NULL) {
- type = connman_service_get_type(info->service);
+ if (info->entry != NULL) {
+ type = connman_service_get_type(info->entry->service);
info->bearer = service2bearer(type);
- info->online = __connman_service_is_connected(info->service);
- info->name = __connman_service_get_name(info->service);
+ info->online = __connman_service_is_connected(info->entry->service);
+ info->name = __connman_service_get_name(info->entry->service);
if (info->name == NULL)
info->name = "";
- idx = __connman_service_get_index(info->service);
+ idx = __connman_service_get_index(info->entry->service);
info->ifname = connman_inet_ifname(idx);
if (info->ifname == NULL)
info->ifname = "";
if (explicit_connect(info->reason) == FALSE)
goto out;
- if (__connman_service_session_dec(info->service) == TRUE)
+ if (__connman_service_session_dec(info->entry->service) == TRUE)
goto out;
if (ecall_session != NULL && ecall_session != session)
goto out;
- __connman_service_disconnect(info->service);
+ __connman_service_disconnect(info->entry->service);
out:
info->reason = CONNMAN_SESSION_REASON_UNKNOWN;
- info->service = NULL;
+ info->entry = NULL;
}
static void select_and_connect(struct connman_session *session,
enum connman_session_reason reason)
{
struct session_info *info = &session->info;
- struct connman_service *service = NULL;
+ struct service_entry *entry = NULL;
GSequenceIter *iter;
connman_bool_t do_connect = FALSE;
iter = g_sequence_get_begin_iter(session->service_list);
while (g_sequence_iter_is_end(iter) == FALSE) {
- service = g_sequence_get(iter);
+ entry = g_sequence_get(iter);
- if (__connman_service_is_connecting(service) == TRUE ||
- __connman_service_is_connected(service) == TRUE) {
+ if (__connman_service_is_connecting(entry->service) == TRUE ||
+ __connman_service_is_connected(entry->service) == TRUE) {
break;
}
- if (__connman_service_is_idle(service) == TRUE &&
+ if (__connman_service_is_idle(entry->service) == TRUE &&
explicit_connect(reason) == TRUE) {
do_connect = TRUE;
break;
}
- service = NULL;
+ entry = NULL;
iter = g_sequence_iter_next(iter);
}
- if (info->service != NULL && info->service != service)
+ if (info->entry != NULL && info->entry != entry)
test_and_disconnect(session);
- if (service != NULL) {
+ if (entry != NULL) {
info->reason = reason;
- info->service = service;
+ info->entry = entry;
if (explicit_connect(reason) == TRUE)
- __connman_service_session_inc(info->service);
+ __connman_service_session_inc(info->entry->service);
if (do_connect == TRUE)
- __connman_service_connect(info->service);
+ __connman_service_connect(info->entry->service);
}
}
DBG("ignore session changed event");
return;
case CONNMAN_SESSION_TRIGGER_SETTING:
- if (info->service != NULL) {
+ if (info->entry != NULL) {
iter = g_hash_table_lookup(session->service_hash,
- info->service);
+ info->entry->service);
if (iter == NULL) {
/*
* This service is not part of this
case CONNMAN_SESSION_TRIGGER_CONNECT:
if (info->online == TRUE) {
info->reason = CONNMAN_SESSION_REASON_CONNECT;
- __connman_service_session_inc(info->service);
+ __connman_service_session_inc(info->entry->service);
break;
}
case CONNMAN_SESSION_TRIGGER_PERIODIC:
if (info->online == TRUE) {
info->reason = CONNMAN_SESSION_REASON_PERIODIC;
- __connman_service_session_inc(info->service);
+ __connman_service_session_inc(info->entry->service);
break;
}
break;
case CONNMAN_SESSION_TRIGGER_ECALL:
- if (info->online == FALSE && info->service != NULL)
+ if (info->online == FALSE && info->entry->service != NULL)
test_and_disconnect(session);
break;
}
- if (info->service != info_last->service) {
+ if (info->entry != info_last->entry) {
update_info(info);
session->info_dirty = TRUE;
}
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
+static struct service_entry *create_service_entry(struct connman_service *service,
+ const char *name,
+ enum connman_service_state state)
+{
+ struct service_entry *entry;
+
+ entry = g_try_new0(struct service_entry, 1);
+ if (entry == NULL)
+ return entry;
+
+ entry->service = service;
+
+ return entry;
+}
+
+static void destroy_service_entry(gpointer data)
+{
+ struct service_entry *entry = data;
+
+ g_free(entry);
+}
+
static void update_allowed_bearers(struct connman_session *session)
{
- struct connman_service *service;
+ struct service_entry *entry;
GSequenceIter *iter;
if (session->service_list != NULL) {
}
session->service_list = __connman_service_get_list(session,
- service_match);
+ service_match,
+ create_service_entry,
+ destroy_service_entry);
g_sequence_sort(session->service_list, sort_services, session);
iter = g_sequence_get_begin_iter(session->service_list);
while (g_sequence_iter_is_end(iter) == FALSE) {
- service = g_sequence_get(iter);
+ entry = g_sequence_get(iter);
- DBG("service %p type %s name %s", service,
- service2bearer(connman_service_get_type(service)),
- __connman_service_get_name(service));
+ DBG("service %p type %s name %s", entry->service,
+ service2bearer(connman_service_get_type(entry->service)),
+ __connman_service_get_name(entry->service));
- g_hash_table_replace(session->service_hash, service, iter);
+ g_hash_table_replace(session->service_hash,
+ entry->service, iter);
iter = g_sequence_iter_next(iter);
}
info->idle_timeout = idle_timeout;
info->ecall = ecall;
info->roaming_policy = roaming_policy;
- info->service = NULL;
+ info->entry = NULL;
info->marker = 0;
info->reason = CONNMAN_SESSION_REASON_UNKNOWN;
info_last->idle_timeout = info->idle_timeout;
info_last->ecall = info->ecall;
info_last->roaming_policy = info->roaming_policy;
- info_last->service = info->service;
+ info_last->entry = info->entry;
info_last->marker = info->marker;
info_last->reason = info->reason;
info_last->allowed_bearers = info->allowed_bearers;
g_sequence_remove(iter);
- info->service = NULL;
+ info->entry = NULL;
session_changed(session, CONNMAN_SESSION_TRIGGER_SERVICE);
}
}
info = &session->info;
info_last = &session->info_last;
- if (info->service == service) {
+ if (info->entry != NULL && info->entry->service == service) {
info->online = __connman_service_is_connected(service);
if (info_last->online != info->online)
session->info_dirty = TRUE;
session = value;
info = &session->info;
- if (info->service == service) {
+ if (info->entry != NULL && info->entry->service == service) {
if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
ipconfig_ipv4_changed(session);
else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)