| /* |
| * |
| * Connection Manager |
| * |
| * Copyright (C) 2007-2009 Intel Corporation. All rights reserved. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| * |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif |
| |
| #include <stdlib.h> |
| #include <gdbus.h> |
| |
| #include "powermanager.h" |
| #include "connman.h" |
| |
| #define _DBG_MANAGER(fmt, arg...) DBG(DBG_MANAGER, fmt, ## arg) |
| |
| static void append_profiles(DBusMessageIter *dict) |
| { |
| connman_dbus_dict_append_variant_array(dict, "Profiles", |
| DBUS_TYPE_OBJECT_PATH, __connman_profile_list, NULL); |
| } |
| |
| static void append_services(DBusMessageIter *dict) |
| { |
| connman_dbus_dict_append_variant_array(dict, "Services", |
| DBUS_TYPE_OBJECT_PATH, __connman_service_list, NULL); |
| } |
| |
| static void append_watchlist_services(DBusMessageIter *dict) |
| { |
| connman_dbus_dict_append_variant_array(dict, "ServiceWatchList", |
| DBUS_TYPE_OBJECT_PATH, __connman_service_watchlist, NULL); |
| } |
| |
| static void _append_devices(DBusMessageIter *dict, void *arg) |
| { |
| __connman_element_list(NULL, CONNMAN_ELEMENT_TYPE_DEVICE, dict); |
| } |
| static void append_devices(DBusMessageIter *dict) |
| { |
| connman_dbus_dict_append_variant_array(dict, "Devices", |
| DBUS_TYPE_OBJECT_PATH, _append_devices, NULL); |
| } |
| |
| static void append_available_technologies(DBusMessageIter *dict) |
| { |
| connman_dbus_dict_append_variant_array(dict, "AvailableTechnologies", |
| DBUS_TYPE_STRING, __connman_notifier_list_registered, NULL); |
| } |
| |
| static void append_enabled_technologies(DBusMessageIter *dict) |
| { |
| connman_dbus_dict_append_variant_array(dict, "EnabledTechnologies", |
| DBUS_TYPE_STRING, __connman_notifier_list_enabled, NULL); |
| } |
| |
| static void append_connected_technologies(DBusMessageIter *dict) |
| { |
| connman_dbus_dict_append_variant_array(dict, "ConnectedTechnologies", |
| DBUS_TYPE_STRING, __connman_notifier_list_connected, NULL); |
| } |
| |
| static const char *online_state(void) |
| { |
| return __connman_connection_is_online() == TRUE ? "online" : "offline"; |
| } |
| |
| static DBusMessage *get_properties(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| DBusMessage *reply; |
| DBusMessageIter array, dict; |
| connman_bool_t offlinemode; |
| connman_bool_t arpgateway; |
| const char *str; |
| gchar *checkportal; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| reply = dbus_message_new_method_return(msg); |
| if (reply == NULL) |
| return NULL; |
| |
| dbus_message_iter_init_append(reply, &array); |
| |
| dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY, |
| DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING |
| DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING |
| DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); |
| |
| str = __connman_profile_active_path(); |
| if (str != NULL) |
| connman_dbus_dict_append_variant(&dict, "ActiveProfile", |
| DBUS_TYPE_OBJECT_PATH, &str); |
| |
| append_profiles(&dict); |
| append_services(&dict); |
| append_watchlist_services(&dict); |
| |
| append_devices(&dict); |
| |
| str = online_state(); |
| connman_dbus_dict_append_variant(&dict, "State", |
| DBUS_TYPE_STRING, &str); |
| |
| str = connman_profile_get_country(); |
| if (str != NULL) |
| connman_dbus_dict_append_variant(&dict, "Country", |
| DBUS_TYPE_STRING, &str); |
| |
| offlinemode = __connman_profile_get_offlinemode(); |
| connman_dbus_dict_append_variant(&dict, "OfflineMode", |
| DBUS_TYPE_BOOLEAN, &offlinemode); |
| |
| checkportal = __connman_service_mask_to_list( |
| __connman_profile_get_checkportal()); |
| if (checkportal != NULL) { |
| connman_dbus_dict_append_variant(&dict, "CheckPortalList", |
| DBUS_TYPE_STRING, &checkportal); |
| g_free(checkportal); |
| } |
| |
| str = __connman_profile_get_portal_url(); |
| connman_dbus_dict_append_variant(&dict, "PortalURL", |
| DBUS_TYPE_STRING, &str); |
| |
| append_available_technologies(&dict); |
| append_enabled_technologies(&dict); |
| append_connected_technologies(&dict); |
| |
| str = __connman_service_default(); |
| if (str != NULL) |
| connman_dbus_dict_append_variant(&dict, "DefaultTechnology", |
| DBUS_TYPE_STRING, &str); |
| |
| arpgateway = connman_profile_get_arpgateway(); |
| connman_dbus_dict_append_variant(&dict, "ArpGateway", |
| DBUS_TYPE_BOOLEAN, &arpgateway); |
| |
| dbus_message_iter_close_container(&array, &dict); |
| |
| return reply; |
| } |
| |
| static DBusMessage *set_property(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| DBusMessageIter iter, value; |
| const char *name; |
| int type; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| if (dbus_message_iter_init(msg, &iter) == FALSE) |
| return __connman_error_invalid_arguments(msg); |
| |
| dbus_message_iter_get_basic(&iter, &name); |
| dbus_message_iter_next(&iter); |
| dbus_message_iter_recurse(&iter, &value); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| type = dbus_message_iter_get_arg_type(&value); |
| |
| if (g_str_equal(name, "OfflineMode") == TRUE) { |
| connman_bool_t offlinemode; |
| |
| if (type != DBUS_TYPE_BOOLEAN) |
| return __connman_error_invalid_arguments(msg); |
| |
| dbus_message_iter_get_basic(&value, &offlinemode); |
| |
| __connman_profile_set_offlinemode(offlinemode); |
| } else if (g_str_equal(name, "Country") == TRUE) { |
| const char *country; |
| |
| if (type != DBUS_TYPE_STRING) |
| return __connman_error_invalid_arguments(msg); |
| |
| dbus_message_iter_get_basic(&value, &country); |
| |
| connman_profile_set_country(country); |
| } else if (g_str_equal(name, "CheckPortalList") == TRUE) { |
| const char *list; |
| |
| if (type != DBUS_TYPE_STRING) |
| return __connman_error_invalid_arguments(msg); |
| |
| dbus_message_iter_get_basic(&value, &list); |
| |
| __connman_profile_set_checkportal( |
| __connman_service_list_to_mask(list)); |
| __connman_service_recheck_portal(); |
| } else if (g_str_equal(name, "PortalURL") == TRUE) { |
| const char *url; |
| |
| if (type != DBUS_TYPE_STRING) |
| return __connman_error_invalid_arguments(msg); |
| |
| dbus_message_iter_get_basic(&value, &url); |
| |
| __connman_profile_set_portal_url(url); |
| } else if (g_str_equal(name, "ArpGateway") == TRUE) { |
| connman_bool_t arpgateway; |
| |
| if (type != DBUS_TYPE_BOOLEAN) |
| return __connman_error_invalid_arguments(msg); |
| |
| dbus_message_iter_get_basic(&value, &arpgateway); |
| |
| connman_profile_set_arpgateway(arpgateway); |
| } else |
| return __connman_error_invalid_property(msg); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *get_state(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| const char *str; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| str = online_state(); |
| return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &str, |
| DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *create_profile(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| const char *name, *path; |
| int err; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name, |
| DBUS_TYPE_INVALID); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| err = __connman_profile_create(name, &path); |
| if (err < 0) |
| return __connman_error_failed(msg, -err); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path, |
| DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *remove_profile(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| const char *ident; |
| int err; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &ident, |
| DBUS_TYPE_INVALID); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| err = __connman_profile_remove(ident); |
| if (err < 0) |
| return __connman_error_failed(msg, -err); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *push_profile(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| const char *ident, *path; |
| int err; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &ident, |
| DBUS_TYPE_INVALID); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| err = __connman_profile_push(ident, NULL, &path); |
| if (err < 0) |
| return __connman_error_failed(msg, -err); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path, |
| DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *__pop_profile(DBusMessage *msg, const char *ident) |
| { |
| int err; |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| err = __connman_profile_pop(ident); |
| if (err < 0) |
| return __connman_error_failed(msg, -err); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *pop_profile(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| const char *ident; |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &ident, |
| DBUS_TYPE_INVALID); |
| |
| _DBG_MANAGER("ident %s", ident); |
| |
| return __pop_profile(msg, ident); |
| } |
| |
| static DBusMessage *pop_any_profile(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| _DBG_MANAGER(""); |
| |
| return __pop_profile(msg, NULL); |
| } |
| |
| static DBusMessage *request_scan(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| enum connman_service_type type; |
| const char *str; |
| int err; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str, |
| DBUS_TYPE_INVALID); |
| |
| if (g_strcmp0(str, "") == 0) { |
| /* NB: indicates all wifi and wimax devices */ |
| type = CONNMAN_SERVICE_TYPE_UNKNOWN; |
| } else { |
| type = __connman_service_string2type(str); |
| if (type == CONNMAN_SERVICE_TYPE_UNKNOWN) |
| return __connman_error_invalid_arguments(msg); |
| } |
| |
| err = __connman_element_request_scan(type); |
| if (err < 0) { |
| if (err == -EINPROGRESS) { |
| connman_error("Invalid return code from scan"); |
| err = -EINVAL; |
| } |
| |
| return __connman_error_failed(msg, -err); |
| } |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| } |
| |
| static DBusConnection *connection = NULL; |
| |
| static enum connman_service_type technology_type; |
| static connman_bool_t technology_enabled; |
| static DBusMessage *technology_pending = NULL; |
| static guint technology_timeout = 0; |
| |
| static void technology_reply(int error) |
| { |
| _DBG_MANAGER("technology_timeout %d technology_pending %p " |
| "technology_type %d", technology_timeout, technology_pending, |
| technology_type); |
| |
| if (technology_timeout > 0) { |
| g_source_remove(technology_timeout); |
| technology_timeout = 0; |
| } |
| |
| if (technology_pending != NULL) { |
| if (error > 0) { |
| DBusMessage *reply; |
| |
| reply = __connman_error_failed(technology_pending, |
| error); |
| if (reply != NULL) |
| g_dbus_send_message(connection, reply); |
| } else |
| g_dbus_send_reply(connection, technology_pending, |
| DBUS_TYPE_INVALID); |
| |
| dbus_message_unref(technology_pending); |
| technology_pending = NULL; |
| } |
| |
| technology_type = CONNMAN_SERVICE_TYPE_UNKNOWN; |
| } |
| |
| static gboolean technology_abort(gpointer user_data) |
| { |
| _DBG_MANAGER("technology_timeout %d technology_pending %p " |
| "technology_type %d", technology_timeout, technology_pending, |
| technology_type); |
| |
| technology_timeout = 0; |
| |
| technology_reply(ETIMEDOUT); |
| |
| return FALSE; |
| } |
| |
| static void technology_notify(enum connman_service_type type, |
| connman_bool_t enabled) |
| { |
| _DBG_MANAGER("type %d enabled %d technology_timeout %d " |
| "technology_pending %p technology_type %d", |
| type, enabled, technology_timeout, technology_pending, |
| technology_type); |
| |
| if (type == technology_type && enabled == technology_enabled) |
| technology_reply(0); |
| } |
| |
| static struct connman_notifier technology_notifier = { |
| .name = "manager", |
| .priority = CONNMAN_NOTIFIER_PRIORITY_HIGH, |
| .service_enabled= technology_notify, |
| }; |
| |
| static DBusMessage *enable_technology(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| enum connman_service_type type; |
| const char *str; |
| int err; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| if (technology_pending != NULL) { |
| _DBG_MANAGER("pending %p", technology_pending); |
| return __connman_error_in_progress(msg); |
| } |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str, |
| DBUS_TYPE_INVALID); |
| |
| if (g_strcmp0(str, "ethernet") == 0) |
| type = CONNMAN_SERVICE_TYPE_ETHERNET; |
| else if (g_strcmp0(str, "wifi") == 0) |
| type = CONNMAN_SERVICE_TYPE_WIFI; |
| else if (g_strcmp0(str, "wimax") == 0) |
| type = CONNMAN_SERVICE_TYPE_WIMAX; |
| else if (g_strcmp0(str, "bluetooth") == 0) |
| type = CONNMAN_SERVICE_TYPE_BLUETOOTH; |
| else if (g_strcmp0(str, "cellular") == 0) |
| type = CONNMAN_SERVICE_TYPE_CELLULAR; |
| else |
| return __connman_error_invalid_arguments(msg); |
| |
| if (__connman_notifier_is_enabled(type) == TRUE) { |
| _DBG_MANAGER("%s already enabled", str); |
| return __connman_error_already_enabled(msg); |
| } |
| |
| technology_type = type; |
| technology_enabled = TRUE; |
| technology_pending = dbus_message_ref(msg); |
| |
| err = __connman_element_enable_technology(type); |
| if (err < 0 && err != -EINPROGRESS) { |
| technology_reply(-err); |
| return NULL; |
| } |
| /* |
| * The enable work might complete immediately; verify we |
| * actually have a request pending before starting the timer, |
| * otherwise it'll fire and generate a spurious D-Bus reply. |
| */ |
| if (technology_pending != NULL) |
| technology_timeout = g_timeout_add_seconds(15, |
| technology_abort, NULL); |
| |
| return NULL; |
| } |
| |
| static DBusMessage *disable_technology(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| enum connman_service_type type; |
| const char *str; |
| int err; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| if (technology_pending != NULL) |
| return __connman_error_in_progress(msg); |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str, |
| DBUS_TYPE_INVALID); |
| |
| type = __connman_service_string2type(str); |
| if (type == CONNMAN_SERVICE_TYPE_UNKNOWN) |
| return __connman_error_invalid_arguments(msg); |
| |
| if (__connman_notifier_is_enabled(type) == FALSE) |
| return __connman_error_already_disabled(msg); |
| |
| technology_type = type; |
| technology_enabled = FALSE; |
| technology_pending = dbus_message_ref(msg); |
| |
| err = __connman_element_disable_technology(type); |
| if (err < 0 && err != -EINPROGRESS) { |
| technology_reply(-err); |
| return NULL; |
| } |
| /* |
| * The disable work might complete immediately; verify we |
| * actually have a request pending before starting the timer, |
| * otherwise it'll fire and generate a spurious D-Bus reply. |
| */ |
| if (technology_pending != NULL) |
| technology_timeout = g_timeout_add_seconds(10, |
| technology_abort, NULL); |
| |
| return NULL; |
| } |
| |
| static DBusMessage *get_vpn_service(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| DBusMessage *reply; |
| struct connman_service *service; |
| const char *path; |
| connman_bool_t created; |
| |
| DBG(DBG_MANAGER | DBG_SERVICE, "conn %p", conn); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| reply = __connman_provider_create(msg, &service, &created); |
| if (reply != NULL) |
| return reply; |
| if (service == NULL) |
| return __connman_error_internal_error(msg); |
| |
| reply = __connman_service_set_properties(msg, service); |
| if (reply != NULL) { |
| if (created == TRUE) |
| __connman_service_put(service); |
| return reply; |
| } |
| |
| path = __connman_service_get_path(service); |
| return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path, |
| DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *get_service(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| DBG(DBG_MANAGER | DBG_SERVICE, "conn %p", conn); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| return __connman_get_service(msg); |
| } |
| |
| static DBusMessage *configure_service(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| DBG(DBG_MANAGER | DBG_SERVICE, "conn %p", conn); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| return __connman_configure_service(msg); |
| } |
| |
| static DBusMessage *register_agent(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| const char *sender, *path; |
| int err; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| sender = dbus_message_get_sender(msg); |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, |
| DBUS_TYPE_INVALID); |
| |
| err = __connman_agent_register(sender, path); |
| if (err < 0) |
| return __connman_error_failed(msg, -err); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *unregister_agent(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| const char *sender, *path; |
| int err; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| sender = dbus_message_get_sender(msg); |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, |
| DBUS_TYPE_INVALID); |
| |
| err = __connman_agent_unregister(sender, path); |
| if (err < 0) |
| return __connman_error_failed(msg, -err); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *get_debug_tags(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| DBusMessage *reply; |
| char *taglist; |
| extern gchar *__connman_debug_get_tags(); |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| taglist = __connman_debug_get_tags(); |
| reply = g_dbus_create_reply(msg, DBUS_TYPE_STRING, &taglist, |
| DBUS_TYPE_INVALID); |
| g_free(taglist); |
| return reply; |
| } |
| |
| static DBusMessage *list_debug_tags(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| DBusMessage *reply; |
| char *taglist; |
| extern gchar *__connman_debug_get_all_tags(); |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| taglist = __connman_debug_get_all_tags(); |
| reply = g_dbus_create_reply(msg, DBUS_TYPE_STRING, &taglist, |
| DBUS_TYPE_INVALID); |
| g_free(taglist); |
| return reply; |
| } |
| |
| static DBusMessage *set_debug_tags(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| char *taglist; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &taglist, |
| DBUS_TYPE_INVALID); |
| |
| connman_info("Set debug tags \"%s\"", taglist); |
| if (!__connman_debug_set_tags(taglist)) |
| return __connman_error_invalid_debug_tag(msg); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *get_debugmask(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| uint32_t mask = (uint32_t) __connman_debug_getmask(); |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_UINT32, &mask, |
| DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *set_debugmask(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| uint32_t mask; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &mask, |
| DBUS_TYPE_INVALID); |
| |
| connman_info("Set debug mask 0x%x", mask); |
| (void) __connman_debug_setmask(mask); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *get_service_order(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| char *str; |
| DBusMessage *m; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| str = __connman_service_get_ordering(); |
| m = g_dbus_create_reply(msg, DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID); |
| g_free(str); |
| |
| return m; |
| } |
| |
| static DBusMessage *set_service_order(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| const char *str; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| if (__connman_security_check_privilege(msg, |
| CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0) |
| return __connman_error_permission_denied(msg); |
| |
| dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &str, |
| DBUS_TYPE_INVALID); |
| |
| connman_info("Set service order %s", str); |
| if (__connman_service_set_ordering(str) < 0) |
| return __connman_error_invalid_arguments(msg); |
| |
| /* TODO(sleffler) update state (e.g. routing) */ |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| } |
| |
| static DBusMessage *recheck_portal(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| __connman_service_recheck_portal(); |
| |
| return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); |
| } |
| |
| static GDBusMethodTable manager_methods[] = { |
| { "GetProperties", "", "a{sv}", get_properties }, |
| { "SetProperty", "sv", "", set_property }, |
| { "GetState", "", "s", get_state }, |
| { "CreateProfile", "s", "o", create_profile }, |
| { "RemoveProfile", "s", "", remove_profile }, |
| { "PushProfile", "s", "o", push_profile }, |
| { "PopProfile", "s", "", pop_profile }, |
| { "PopAnyProfile", "", "", pop_any_profile }, |
| { "RequestScan", "s", "", request_scan }, |
| { "EnableTechnology", "s", "", enable_technology, |
| G_DBUS_METHOD_FLAG_ASYNC }, |
| { "DisableTechnology", "s", "", disable_technology, |
| G_DBUS_METHOD_FLAG_ASYNC }, |
| { "GetService", "a{sv}", "o", get_service }, |
| { "GetWifiService", "a{sv}", "o", get_service }, |
| { "ConfigureWifiService", "a{sv}","", configure_service }, |
| { "ConfigureService", "a{sv}", "o", configure_service }, |
| { "GetVPNService", "a{sv}", "o", get_vpn_service }, |
| { "RegisterAgent", "o", "", register_agent }, |
| { "UnregisterAgent", "o", "", unregister_agent }, |
| { "GetDebugTags", "", "s", get_debug_tags }, |
| { "SetDebugTags", "s", "", set_debug_tags }, |
| { "ListDebugTags", "", "s", list_debug_tags }, |
| { "GetDebugMask", "", "u", get_debugmask }, |
| { "SetDebugMask", "u", "", set_debugmask }, |
| { "GetServiceOrder", "", "s", get_service_order }, |
| { "SetServiceOrder", "s", "", set_service_order }, |
| { "RecheckPortal", "", "", recheck_portal }, |
| { }, |
| }; |
| |
| static GDBusSignalTable manager_signals[] = { |
| { "PropertyChanged", "sv" }, |
| { "StateChanged", "s" }, |
| { }, |
| }; |
| |
| static DBusMessage *nm_sleep(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| DBusMessage *reply; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| reply = dbus_message_new_method_return(msg); |
| if (reply == NULL) |
| return NULL; |
| |
| dbus_message_append_args(reply, DBUS_TYPE_INVALID); |
| |
| return reply; |
| } |
| |
| static DBusMessage *nm_wake(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| DBusMessage *reply; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| reply = dbus_message_new_method_return(msg); |
| if (reply == NULL) |
| return NULL; |
| |
| dbus_message_append_args(reply, DBUS_TYPE_INVALID); |
| |
| return reply; |
| } |
| |
| enum { |
| NM_STATE_UNKNOWN = 0, |
| NM_STATE_ASLEEP, |
| NM_STATE_CONNECTING, |
| NM_STATE_CONNECTED, |
| NM_STATE_DISCONNECTED |
| }; |
| |
| static DBusMessage *nm_state(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| DBusMessage *reply; |
| dbus_uint32_t state; |
| |
| _DBG_MANAGER("conn %p", conn); |
| |
| reply = dbus_message_new_method_return(msg); |
| if (reply == NULL) |
| return NULL; |
| |
| if (__connman_connection_is_online() == TRUE) |
| state = NM_STATE_CONNECTED; |
| else |
| state = NM_STATE_DISCONNECTED; |
| |
| dbus_message_append_args(reply, DBUS_TYPE_UINT32, &state, |
| DBUS_TYPE_INVALID); |
| |
| return reply; |
| } |
| |
| static GDBusMethodTable nm_methods[] = { |
| { "sleep", "", "", nm_sleep }, |
| { "wake", "", "", nm_wake }, |
| { "state", "", "u", nm_state }, |
| { }, |
| }; |
| |
| static gboolean nm_compat = FALSE; |
| |
| static const char *powerman_rule = "type=signal,interface=" POWERMAN_INTF; |
| |
| static DBusHandlerResult powerman_filter(DBusConnection *conn, |
| DBusMessage *msg, void *data) |
| { |
| const char *member, *state; |
| DBusError error; |
| |
| if (dbus_message_has_interface(msg, POWERMAN_INTF) == FALSE) |
| return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| |
| member = dbus_message_get_member(msg); |
| if (member == NULL) |
| return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| |
| if (g_str_equal(member, "PowerStateChanged") == TRUE) { |
| dbus_error_init(&error); |
| |
| if (dbus_message_get_args(msg, &error, DBUS_TYPE_STRING, &state, |
| DBUS_TYPE_INVALID) == FALSE) |
| return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| |
| _DBG_MANAGER("system state %s", state); |
| if (g_str_equal(state, "on") == TRUE) { |
| /* We've entered the "on" state from some other state */ |
| __connman_notifier_system_resume(); |
| } else if (g_str_equal(state, "standby") == TRUE || |
| g_str_equal(state, "mem") == TRUE || |
| g_str_equal(state, "disk") == TRUE) { |
| /* We're going into a suspend state */ |
| __connman_notifier_system_suspend(); |
| } |
| } else if (g_str_equal(member, "SuspendDelay") == TRUE) { |
| /* We will be going into a suspend state soon */ |
| _DBG_MANAGER("system power preparing to suspend"); |
| __connman_notifier_system_suspend(); |
| } else if (g_str_equal(member, "StartingShutdown") == TRUE) { |
| __connman_notifier_system_shutdown(); |
| } |
| |
| return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| } |
| |
| int __connman_manager_init(gboolean compat) |
| { |
| _DBG_MANAGER(""); |
| |
| connection = connman_dbus_get_connection(); |
| if (connection == NULL) |
| return -1; |
| |
| if (connman_notifier_register(&technology_notifier) < 0) |
| connman_error("Failed to register technology notifier"); |
| |
| g_dbus_register_interface(connection, CONNMAN_MANAGER_PATH, |
| CONNMAN_MANAGER_INTERFACE, |
| manager_methods, |
| manager_signals, NULL, NULL, NULL); |
| |
| if (compat == TRUE) { |
| g_dbus_register_interface(connection, NM_PATH, NM_INTERFACE, |
| nm_methods, NULL, NULL, NULL, NULL); |
| |
| nm_compat = TRUE; |
| } |
| |
| if (dbus_connection_add_filter(connection, |
| powerman_filter, NULL, NULL) == FALSE) { |
| dbus_connection_unref(connection); |
| connection = NULL; |
| return -1; |
| } |
| |
| dbus_bus_add_match(connection, powerman_rule, NULL); |
| dbus_connection_flush(connection); |
| |
| return 0; |
| } |
| |
| void __connman_manager_cleanup(void) |
| { |
| _DBG_MANAGER(""); |
| |
| connman_notifier_unregister(&technology_notifier); |
| |
| if (connection == NULL) |
| return; |
| |
| if (nm_compat == TRUE) { |
| g_dbus_unregister_interface(connection, NM_PATH, NM_INTERFACE); |
| } |
| |
| g_dbus_unregister_interface(connection, CONNMAN_MANAGER_PATH, |
| CONNMAN_MANAGER_INTERFACE); |
| |
| dbus_bus_remove_match(connection, powerman_rule, NULL); |
| dbus_connection_flush(connection); |
| dbus_connection_remove_filter(connection, powerman_filter, NULL); |
| |
| dbus_connection_unref(connection); |
| } |