forked from enlightenment/enlightenment
e/connman: objectify manager and monitor properties
SVN revision: 76026
This commit is contained in:
parent
6decf38d1f
commit
bdbc5ac934
|
@ -2,6 +2,7 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -10,66 +11,251 @@
|
|||
#define CONNMAN_BUS_NAME "net.connman"
|
||||
#define CONNMAN_MANAGER_IFACE CONNMAN_BUS_NAME ".Manager"
|
||||
|
||||
static struct
|
||||
enum Connman_State
|
||||
{
|
||||
E_DBus_Signal_Handler *name_owner_changed;
|
||||
E_DBus_Signal_Handler *services_changed;
|
||||
E_DBus_Signal_Handler *prop_changed;
|
||||
} handlers;
|
||||
CONNMAN_STATE_NONE = -1, /* All unknown states */
|
||||
CONNMAN_STATE_OFFLINE,
|
||||
CONNMAN_STATE_IDLE,
|
||||
CONNMAN_STATE_READY,
|
||||
CONNMAN_STATE_ONLINE,
|
||||
};
|
||||
|
||||
static struct
|
||||
struct Connman_Object
|
||||
{
|
||||
DBusPendingCall *get_name_owner;
|
||||
} pending;
|
||||
const char *path;
|
||||
Eina_List *handlers; /* E_DBus_Signal_Handler */
|
||||
};
|
||||
|
||||
struct Connman_Manager
|
||||
{
|
||||
struct Connman_Object obj;
|
||||
|
||||
Eina_Inlist *services; /* The prioritized list of services */
|
||||
|
||||
/* Properties */
|
||||
enum Connman_State state;
|
||||
bool offline_mode;
|
||||
|
||||
/* Private */
|
||||
struct
|
||||
{
|
||||
DBusPendingCall *get_services;
|
||||
DBusPendingCall *get_properties;
|
||||
} pending;
|
||||
};
|
||||
|
||||
static unsigned int init_count;
|
||||
static E_DBus_Connection *conn;
|
||||
static char *bus_owner;
|
||||
static struct Connman_Manager *connman_manager;
|
||||
|
||||
static DBusPendingCall *pending_get_name_owner;
|
||||
static E_DBus_Signal_Handler *handler_name_owner;
|
||||
|
||||
EAPI int E_CONNMAN_EVENT_MANAGER_IN;
|
||||
EAPI int E_CONNMAN_EVENT_MANAGER_OUT;
|
||||
|
||||
static inline void
|
||||
_e_connman_system_name_owner_exit(void)
|
||||
{
|
||||
e_dbus_signal_handler_del(conn, handlers.services_changed);
|
||||
handlers.services_changed = NULL;
|
||||
e_dbus_signal_handler_del(conn, handlers.prop_changed);
|
||||
handlers.prop_changed = NULL;
|
||||
/* utility functions */
|
||||
|
||||
static bool _dbus_bool_get(DBusMessageIter *itr)
|
||||
{
|
||||
dbus_bool_t val;
|
||||
dbus_message_iter_get_basic(itr, &val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static enum Connman_State str_to_state(const char *s)
|
||||
{
|
||||
if (strcmp(s, "offline") == 0)
|
||||
return CONNMAN_STATE_OFFLINE;
|
||||
if (strcmp(s, "idle") == 0)
|
||||
return CONNMAN_STATE_IDLE;
|
||||
if (strcmp(s, "ready") == 0)
|
||||
return CONNMAN_STATE_READY;
|
||||
if (strcmp(s, "online") == 0)
|
||||
return CONNMAN_STATE_ONLINE;
|
||||
|
||||
ERR("Unknown state %s", s);
|
||||
return CONNMAN_STATE_NONE;
|
||||
}
|
||||
|
||||
/* ---- */
|
||||
|
||||
static void _connman_object_init(struct Connman_Object *obj, const char *path)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN(path);
|
||||
obj->path = path;
|
||||
}
|
||||
|
||||
static void _service_changed(const char *service, DBusMessageIter *props)
|
||||
{
|
||||
}
|
||||
|
||||
static void _manager_services_changed(void *data, DBusMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
static void _manager_get_services_cb(void *data, DBusMessage *reply,
|
||||
DBusError *err)
|
||||
{
|
||||
}
|
||||
|
||||
static void _manager_parse_prop_changed(struct Connman_Manager *cm,
|
||||
const char *name,
|
||||
DBusMessageIter *value)
|
||||
{
|
||||
if (strcmp(name, "State") == 0)
|
||||
{
|
||||
const char *state;
|
||||
dbus_message_iter_get_basic(value, &state);
|
||||
DBG("New state: %s", state);
|
||||
cm->state = str_to_state(state);
|
||||
}
|
||||
else if (strcmp(name, "OfflineMode") == 0)
|
||||
cm->offline_mode = _dbus_bool_get(value);
|
||||
else
|
||||
DBG("Unhandled property '%s'", name);
|
||||
}
|
||||
|
||||
static void _manager_prop_changed(void *data, DBusMessage *msg)
|
||||
{
|
||||
struct Connman_Manager *cm = data;
|
||||
DBusMessageIter iter, var;
|
||||
const char *name;
|
||||
|
||||
if (!msg || !dbus_message_iter_init(msg, &iter))
|
||||
{
|
||||
ERR("Could not parse message %p", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_message_iter_get_basic(&iter, &name);
|
||||
dbus_message_iter_next(&iter);
|
||||
dbus_message_iter_recurse(&iter, &var);
|
||||
|
||||
_manager_parse_prop_changed(cm, name, &var);
|
||||
}
|
||||
|
||||
static void _manager_get_prop_cb(void *data, DBusMessage *reply,
|
||||
DBusError *err)
|
||||
{
|
||||
struct Connman_Manager *cm = data;
|
||||
DBusMessageIter iter, dict;
|
||||
|
||||
cm->pending.get_properties = NULL;
|
||||
|
||||
if (dbus_error_is_set(err))
|
||||
{
|
||||
DBG("Could not get properties. %s: %s", err->name, err->message);
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_message_iter_init(reply, &iter);
|
||||
dbus_message_iter_recurse(&iter, &dict);
|
||||
|
||||
for (; dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID;
|
||||
dbus_message_iter_next(&dict))
|
||||
{
|
||||
DBusMessageIter entry, var;
|
||||
const char *name;
|
||||
|
||||
dbus_message_iter_recurse(&dict, &entry);
|
||||
dbus_message_iter_get_basic(&entry, &name);
|
||||
dbus_message_iter_next(&entry);
|
||||
dbus_message_iter_recurse(&entry, &var);
|
||||
|
||||
_manager_parse_prop_changed(cm, name, &var);
|
||||
}
|
||||
}
|
||||
|
||||
static void _manager_free(struct Connman_Manager *cm)
|
||||
{
|
||||
Eina_List *l;
|
||||
|
||||
EINA_LIST_FREE(cm->obj.handlers, l)
|
||||
e_dbus_signal_handler_del(conn, l->data);
|
||||
|
||||
if (cm->pending.get_services)
|
||||
{
|
||||
dbus_pending_call_cancel(cm->pending.get_services);
|
||||
cm->pending.get_services = NULL;
|
||||
}
|
||||
|
||||
if (cm->pending.get_properties)
|
||||
{
|
||||
dbus_pending_call_cancel(cm->pending.get_properties);
|
||||
cm->pending.get_properties = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct Connman_Manager *_manager_new(void)
|
||||
{
|
||||
DBusMessage *msg_props, *msg_services;
|
||||
const char *path = "/";
|
||||
struct E_DBus_Signal_Handler *h;
|
||||
struct Connman_Manager *cm;
|
||||
|
||||
msg_services = dbus_message_new_method_call(CONNMAN_BUS_NAME, "/",
|
||||
CONNMAN_MANAGER_IFACE, "GetServices");
|
||||
msg_props = dbus_message_new_method_call(CONNMAN_BUS_NAME, "/",
|
||||
CONNMAN_MANAGER_IFACE, "GetProperties");
|
||||
|
||||
if (!msg_services || !msg_services)
|
||||
{
|
||||
ERR("Could not create D-Bus messages");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cm = calloc(1, sizeof(*cm) + 2);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cm, NULL);
|
||||
|
||||
memcpy(cm + sizeof(*cm), path, 1);
|
||||
_connman_object_init(&cm->obj, path);
|
||||
|
||||
h = e_dbus_signal_handler_add(conn, bus_owner,
|
||||
path, CONNMAN_MANAGER_IFACE, "PropertyChanged",
|
||||
_manager_prop_changed, cm);
|
||||
cm->obj.handlers = eina_list_append(cm->obj.handlers, h);
|
||||
|
||||
h = e_dbus_signal_handler_add(conn, bus_owner,
|
||||
path, CONNMAN_MANAGER_IFACE, "ServicesChanged",
|
||||
_manager_services_changed, cm);
|
||||
cm->obj.handlers = eina_list_append(cm->obj.handlers, h);
|
||||
|
||||
/*
|
||||
* PropertyChanged signal in service's path is guaranteed to arrive only
|
||||
* after ServicesChanged above. So we only add the handler later, in a per
|
||||
* service manner.
|
||||
*/
|
||||
|
||||
cm->pending.get_services = e_dbus_message_send(conn, msg_services,
|
||||
_manager_get_services_cb, -1, cm);
|
||||
cm->pending.get_properties = e_dbus_message_send(conn, msg_props,
|
||||
_manager_get_prop_cb, -1, cm);
|
||||
|
||||
return cm;
|
||||
}
|
||||
|
||||
static inline void _e_connman_system_name_owner_exit(void)
|
||||
{
|
||||
free(bus_owner);
|
||||
bus_owner = NULL;
|
||||
|
||||
_manager_free(connman_manager);
|
||||
connman_manager = NULL;
|
||||
|
||||
ecore_event_add(E_CONNMAN_EVENT_MANAGER_OUT, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void _manager_services_changed(void *data __UNUSED__, DBusMessage *msg)
|
||||
static inline void _e_connman_system_name_owner_enter(const char *owner)
|
||||
{
|
||||
}
|
||||
|
||||
static void _manager_prop_changed(void *data __UNUSED__, DBusMessage *msg)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
_e_connman_system_name_owner_enter(const char *owner)
|
||||
{
|
||||
free(bus_owner);
|
||||
bus_owner = strdup(owner);
|
||||
|
||||
handlers.prop_changed = e_dbus_signal_handler_add(conn, bus_owner,
|
||||
"/", CONNMAN_MANAGER_IFACE, "PropertyChanged",
|
||||
_manager_prop_changed, NULL);
|
||||
|
||||
handlers.services_changed = e_dbus_signal_handler_add(conn, bus_owner,
|
||||
"/", CONNMAN_MANAGER_IFACE, "ServicesChanged",
|
||||
_manager_services_changed, NULL);
|
||||
|
||||
connman_manager = _manager_new();
|
||||
ecore_event_add(E_CONNMAN_EVENT_MANAGER_IN, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
_e_connman_system_name_owner_changed(void *data __UNUSED__, DBusMessage *msg)
|
||||
static void _e_connman_system_name_owner_changed(void *data __UNUSED__,
|
||||
DBusMessage *msg)
|
||||
{
|
||||
const char *name, *from, *to;
|
||||
DBusError err;
|
||||
|
@ -105,7 +291,12 @@ _e_connman_get_name_owner(void *data __UNUSED__, DBusMessage *msg, DBusError *er
|
|||
{
|
||||
const char *owner;
|
||||
|
||||
pending.get_name_owner = NULL;
|
||||
pending_get_name_owner = NULL;
|
||||
|
||||
/* Do nothing if already received a signal */
|
||||
if (bus_owner)
|
||||
return;
|
||||
|
||||
DBG("get_name_owner msg=%p", msg);
|
||||
|
||||
if (dbus_error_is_set(err))
|
||||
|
@ -146,12 +337,11 @@ e_connman_system_init(E_DBus_Connection *edbus_conn)
|
|||
E_CONNMAN_EVENT_MANAGER_OUT = ecore_event_type_new();
|
||||
|
||||
conn = edbus_conn;
|
||||
handlers.name_owner_changed = e_dbus_signal_handler_add(conn,
|
||||
handler_name_owner = e_dbus_signal_handler_add(conn,
|
||||
E_DBUS_FDO_BUS, E_DBUS_FDO_PATH, E_DBUS_FDO_INTERFACE,
|
||||
"NameOwnerChanged", _e_connman_system_name_owner_changed,
|
||||
NULL);
|
||||
|
||||
pending.get_name_owner = e_dbus_get_name_owner(conn,
|
||||
pending_get_name_owner = e_dbus_get_name_owner(conn,
|
||||
CONNMAN_BUS_NAME, _e_connman_get_name_owner,
|
||||
NULL);
|
||||
|
||||
|
@ -177,19 +367,9 @@ e_connman_system_shutdown(void)
|
|||
if (init_count > 0)
|
||||
return init_count;
|
||||
|
||||
if (pending.get_name_owner)
|
||||
dbus_pending_call_cancel(pending.get_name_owner);
|
||||
|
||||
memset(&pending, 0, sizeof(pending));
|
||||
|
||||
if (handlers.name_owner_changed)
|
||||
e_dbus_signal_handler_del(conn, handlers.name_owner_changed);
|
||||
if (handlers.services_changed)
|
||||
e_dbus_signal_handler_del(conn, handlers.services_changed);
|
||||
if (handlers.prop_changed)
|
||||
e_dbus_signal_handler_del(conn, handlers.prop_changed);
|
||||
|
||||
memset(&handlers, 0, sizeof(handlers));
|
||||
e_dbus_signal_handler_del(conn, handler_name_owner);
|
||||
if (pending_get_name_owner)
|
||||
dbus_pending_call_cancel(pending_get_name_owner);
|
||||
|
||||
conn = NULL;
|
||||
|
||||
|
@ -198,4 +378,3 @@ e_connman_system_shutdown(void)
|
|||
|
||||
return init_count;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue