static DBusMessage *change_session(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct connman_session *session = user_data; struct session_info *info = session->info; DBusMessageIter iter, value; const char *name; const char *val; GSList *allowed_bearers; int err; DBG("session %p", session); if (!dbus_message_iter_init(msg, &iter)) return __connman_error_invalid_arguments(msg); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) return __connman_error_invalid_arguments(msg); dbus_message_iter_get_basic(&iter, &name); dbus_message_iter_next(&iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT) return __connman_error_invalid_arguments(msg); dbus_message_iter_recurse(&iter, &value); switch (dbus_message_iter_get_arg_type(&value)) { case DBUS_TYPE_ARRAY: if (g_str_equal(name, "AllowedBearers")) { err = parse_bearers(&value, &allowed_bearers); if (err < 0) return __connman_error_failed(msg, -err); if (session->active) set_active_session(session, false); session->active = false; session_deactivate(session); g_slist_free(info->config.allowed_bearers); session->user_allowed_bearers = allowed_bearers; apply_policy_on_bearers( session->policy_config->allowed_bearers, session->user_allowed_bearers, &info->config.allowed_bearers); session_activate(session); } else { goto err; } break; case DBUS_TYPE_STRING: if (g_str_equal(name, "ConnectionType")) { dbus_message_iter_get_basic(&value, &val); info->config.type = apply_policy_on_type( session->policy_config->type, connman_session_parse_connection_type(val)); } else { goto err; } break; default: goto err; } session_notify(session); return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); err: return __connman_error_invalid_arguments(msg); }
int __connman_session_create(DBusMessage *msg) { const char *owner, *notify_path; char *session_path = NULL; DBusMessageIter iter, array; struct connman_session *session = NULL; struct creation_data *creation_data = NULL; bool user_allowed_bearers = false; bool user_connection_type = false; int err, i; char *str; owner = dbus_message_get_sender(msg); DBG("owner %s", owner); if (ecall_session && ecall_session->ecall) { /* * If there is an emergency call already going on, * ignore session creation attempt */ err = -EBUSY; goto err; } creation_data = g_try_new0(struct creation_data, 1); if (!creation_data) { err = -ENOMEM; goto err; } creation_data->pending = dbus_message_ref(msg); dbus_message_iter_init(msg, &iter); dbus_message_iter_recurse(&iter, &array); while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter entry, value; const char *key, *val; dbus_message_iter_recurse(&array, &entry); dbus_message_iter_get_basic(&entry, &key); dbus_message_iter_next(&entry); dbus_message_iter_recurse(&entry, &value); switch (dbus_message_iter_get_arg_type(&value)) { case DBUS_TYPE_ARRAY: if (g_str_equal(key, "AllowedBearers")) { err = parse_bearers(&value, &creation_data->allowed_bearers); if (err < 0) goto err; user_allowed_bearers = true; } else { err = -EINVAL; goto err; } break; case DBUS_TYPE_STRING: if (g_str_equal(key, "ConnectionType")) { dbus_message_iter_get_basic(&value, &val); creation_data->type = connman_session_parse_connection_type(val); user_connection_type = true; } else { err = -EINVAL; goto err; } } dbus_message_iter_next(&array); } /* * If the user hasn't provided a configuration, we set * the default configuration. * * For AllowedBearers this is '*', ... */ if (!user_allowed_bearers) { add_default_bearer_types(&creation_data->allowed_bearers); if (!creation_data->allowed_bearers) { err = -ENOMEM; goto err; } } /* ... and for ConnectionType it is 'any'. */ if (!user_connection_type) creation_data->type = CONNMAN_SESSION_TYPE_ANY; dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, ¬ify_path); if (!notify_path) { err = -EINVAL; goto err; } str = g_strdup(owner); for (i = 0; str[i] != '\0'; i++) if (str[i] == ':' || str[i] == '.') str[i] = '_'; session_path = g_strdup_printf("/sessions/%s%s", str, notify_path); g_free(str); if (!session_path) { err = -ENOMEM; goto err; } session = g_hash_table_lookup(session_hash, session_path); if (session) { g_free(session_path); session = NULL; err = -EEXIST; goto err; } session = g_try_new0(struct connman_session, 1); if (!session) { g_free(session_path); err = -ENOMEM; goto err; } creation_data->session = session; session->session_path = session_path; session->info = g_try_new0(struct session_info, 1); if (!session->info) { err = -ENOMEM; goto err; } session->info_last = g_try_new0(struct session_info, 1); if (!session->info_last) { err = -ENOMEM; goto err; } session->owner = g_strdup(owner); session->notify_path = g_strdup(notify_path); session->notify_watch = g_dbus_add_disconnect_watch(connection, session->owner, owner_disconnect, session, NULL); err = create_policy_config(session, session_policy_config_cb, creation_data); if (err < 0 && err != -EINPROGRESS) return err; return -EINPROGRESS; err: connman_error("Failed to create session"); free_session(session); cleanup_creation_data(creation_data); return err; }
int __connman_session_create(DBusMessage *msg) { const char *owner, *notify_path; char *session_path = NULL; DBusMessageIter iter, array; struct connman_session *session = NULL; struct user_config *user_config = NULL; connman_bool_t user_allowed_bearers = FALSE; connman_bool_t user_connection_type = FALSE; int err; owner = dbus_message_get_sender(msg); DBG("owner %s", owner); if (ecall_session != NULL && ecall_session->ecall == TRUE) { /* * If there is an emergency call already going on, * ignore session creation attempt */ err = -EBUSY; goto err; } user_config = g_try_new0(struct user_config, 1); if (user_config == NULL) { err = -ENOMEM; goto err; } user_config->pending = dbus_message_ref(msg); dbus_message_iter_init(msg, &iter); dbus_message_iter_recurse(&iter, &array); while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) { DBusMessageIter entry, value; const char *key, *val; dbus_message_iter_recurse(&array, &entry); dbus_message_iter_get_basic(&entry, &key); dbus_message_iter_next(&entry); dbus_message_iter_recurse(&entry, &value); switch (dbus_message_iter_get_arg_type(&value)) { case DBUS_TYPE_ARRAY: if (g_str_equal(key, "AllowedBearers") == TRUE) { err = parse_bearers(&value, &user_config->allowed_bearers); if (err < 0) goto err; user_allowed_bearers = TRUE; } else { err = -EINVAL; goto err; } break; case DBUS_TYPE_STRING: if (g_str_equal(key, "ConnectionType") == TRUE) { dbus_message_iter_get_basic(&value, &val); user_config->type = connman_session_parse_connection_type(val); user_connection_type = TRUE; } else { err = -EINVAL; goto err; } } dbus_message_iter_next(&array); } /* * If the user hasn't provided a configuration, we set * the default configuration. * * For AllowedBearers this is '*', ... */ if (user_allowed_bearers == FALSE) { user_config->allowed_bearers = g_slist_append(NULL, GINT_TO_POINTER(CONNMAN_SERVICE_TYPE_UNKNOWN)); if (user_config->allowed_bearers == NULL) { err = -ENOMEM; goto err; } } /* ... and for ConnectionType it is 'any'. */ if (user_connection_type == FALSE) user_config->type = CONNMAN_SESSION_TYPE_ANY; dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, ¬ify_path); if (notify_path == NULL) { err = -EINVAL; goto err; } session_path = g_strdup_printf("/sessions%s", notify_path); if (session_path == NULL) { err = -ENOMEM; goto err; } session = g_hash_table_lookup(session_hash, session_path); if (session != NULL) { g_free(session_path); session = NULL; err = -EEXIST; goto err; } session = g_try_new0(struct connman_session, 1); if (session == NULL) { g_free(session_path); err = -ENOMEM; goto err; } session->session_path = session_path; session->info = g_try_new0(struct session_info, 1); if (session->info == NULL) { err = -ENOMEM; goto err; } session->info_last = g_try_new0(struct session_info, 1); if (session->info_last == NULL) { err = -ENOMEM; goto err; } session->owner = g_strdup(owner); session->notify_path = g_strdup(notify_path); session->notify_watch = g_dbus_add_disconnect_watch(connection, session->owner, owner_disconnect, session, NULL); err = assign_policy_plugin(session); if (err < 0) goto err; err = create_policy_config(session, session_create_cb, user_config); if (err < 0 && err != -EINPROGRESS) return err; return -EINPROGRESS; err: connman_error("Failed to create session"); free_session(session); cleanup_user_config(user_config); return err; }