blob: 067665e5f25b522437035ce5e9c8524e327857ab [file] [log] [blame]
/*
*
* 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;
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);
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);
offlinemode = __connman_profile_get_offlinemode();
connman_dbus_dict_append_variant(&dict, "OfflineMode",
DBUS_TYPE_BOOLEAN, &offlinemode);
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);
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
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)
type = CONNMAN_SERVICE_TYPE_UNKNOWN;
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
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_wifi_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_wifi_service(msg);
}
static DBusMessage *get_vpn_service(DBusConnection *conn,
DBusMessage *msg, void *data)
{
const char *path;
int err;
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);
err = __connman_provider_create(msg, &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 *configure_wifi_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_wifi_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 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_wifi_service },
{ "GetWifiService", "a{sv}", "o", get_wifi_service },
{ "ConfigureWifiService","a{sv}","", configure_wifi_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 },
{ },
};
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();
}
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);
}