e/connman: allow to connect and disconnect

Networks that don't require agent interations (i.e. passphrases) can be
(dis)connected now.



SVN revision: 76054
This commit is contained in:
Lucas De Marchi 2012-09-03 22:00:10 +00:00
parent 339cd51087
commit e5f228edba
3 changed files with 173 additions and 1 deletions

View File

@ -62,6 +62,14 @@ struct Connman_Service
enum Connman_State state;
enum Connman_Service_Type type;
uint8_t strength;
/* Private */
struct
{
DBusPendingCall *connect;
DBusPendingCall *disconnect;
void *data;
} pending;
};
/* Ecore Events */
@ -80,6 +88,11 @@ unsigned int e_connman_system_shutdown(void);
*/
struct Connman_Service *econnman_manager_find_service(struct Connman_Manager *cm, const char *path) EINA_ARG_NONNULL(1, 2);
typedef void (*Econnman_Simple_Cb)(void *data, const char *error);
bool econnman_service_connect(struct Connman_Service *cs, Econnman_Simple_Cb cb, void *data);
bool econnman_service_disconnect(struct Connman_Service *cs, Econnman_Simple_Cb cb, void *data);
/* UI calls from econnman */
/*

View File

@ -13,6 +13,9 @@
#define CONNMAN_MANAGER_IFACE CONNMAN_BUS_NAME ".Manager"
#define CONNMAN_SERVICE_IFACE CONNMAN_BUS_NAME ".Service"
#define MILLI_PER_SEC 1000
#define CONNMAN_CONNECTION_TIMEOUT 60 * MILLI_PER_SEC
static unsigned int init_count;
static E_DBus_Connection *conn;
static char *bus_owner;
@ -253,11 +256,28 @@ static void _service_prop_changed(void *data, DBusMessage *msg)
_service_parse_prop_changed(cs, name, &var);
}
struct connection_data {
struct Connman_Service *cs;
Econnman_Simple_Cb cb;
void *user_data;
};
static void _service_free(struct Connman_Service *cs)
{
if (!cs)
return;
if (cs->pending.connect)
{
dbus_pending_call_cancel(cs->pending.connect);
free(cs->pending.data);
}
if (cs->pending.disconnect)
{
dbus_pending_call_cancel(cs->pending.disconnect);
free(cs->pending.data);
}
free(cs->name);
_eina_str_array_clean(cs->security);
eina_array_free(cs->security);
@ -287,6 +307,96 @@ static struct Connman_Service *_service_new(const char *path, DBusMessageIter *p
return cs;
}
static void _service_connection_cb(void *data, DBusMessage *reply,
DBusError *err)
{
struct connection_data *cd = data;
if (cd->cb)
{
const char *s = dbus_error_is_set(err) ? err->message : NULL;
cd->cb(cd->user_data, s);
}
cd->cs->pending.connect = NULL;
cd->cs->pending.disconnect = NULL;
cd->cs->pending.data = NULL;
free(cd);
}
bool econnman_service_connect(struct Connman_Service *cs,
Econnman_Simple_Cb cb, void *data)
{
DBusMessage *msg;
struct connection_data *cd;
EINA_SAFETY_ON_NULL_RETURN_VAL(cs, false);
if (cs->pending.connect || cs->pending.disconnect)
{
ERR("Pending connection: connect=%p disconnect=%p", cs->pending.connect,
cs->pending.disconnect);
return false;
}
msg = dbus_message_new_method_call(CONNMAN_BUS_NAME, cs->obj.path,
CONNMAN_SERVICE_IFACE, "Connect");
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, false);
cd = calloc(1, sizeof(*cd));
EINA_SAFETY_ON_NULL_GOTO(cd, fail);
cd->cs = cs;
cd->cb = cb;
cd->user_data = data;
cs->pending.connect = e_dbus_message_send(conn, msg,
_service_connection_cb, CONNMAN_CONNECTION_TIMEOUT, cd);
return true;
fail:
dbus_message_unref(msg);
return false;
}
bool econnman_service_disconnect(struct Connman_Service *cs,
Econnman_Simple_Cb cb, void *data)
{
DBusMessage *msg;
struct connection_data *cd;
EINA_SAFETY_ON_NULL_RETURN_VAL(cs, false);
if (cs->pending.connect || cs->pending.disconnect)
{
ERR("Pending connection: connect=%p disconnect=%p", cs->pending.connect,
cs->pending.disconnect);
return false;
}
msg = dbus_message_new_method_call(CONNMAN_BUS_NAME, cs->obj.path,
CONNMAN_SERVICE_IFACE, "Disconnect");
EINA_SAFETY_ON_NULL_RETURN_VAL(msg, false);
cd = calloc(1, sizeof(*cd));
EINA_SAFETY_ON_NULL_GOTO(cd, fail);
cd->cs = cs;
cd->cb = cb;
cd->user_data = data;
cs->pending.connect = e_dbus_message_send(conn, msg,
_service_connection_cb, -1, cd);
return true;
fail:
dbus_message_unref(msg);
return false;
}
static struct Connman_Service *_manager_find_service_stringshared(
struct Connman_Manager *cm, const char *path)
{

View File

@ -52,6 +52,54 @@ static Evas_Object * _econnman_service_new_icon(struct Connman_Service *cs,
return icon;
}
static void _econnman_disconnect_cb(void *data, const char *error)
{
const char *path = data;
if (error == NULL)
return;
ERR("Could not disconnect %s: %s", path, error);
}
static void _econnman_connect_cb(void *data, const char *error)
{
const char *path = data;
if (error == NULL)
return;
ERR("Could not connect %s: %s", path, error);
}
static void _econnman_popup_selected_cb(void *data)
{
E_Connman_Instance *inst = data;
const char *path;
struct Connman_Service *cs;
path = e_widget_ilist_selected_value_get(inst->ui.popup.list);
if (path == NULL)
return;
cs = econnman_manager_find_service(inst->ctxt->cm, path);
if (cs == NULL)
return;
switch (cs->state)
{
case CONNMAN_STATE_READY:
case CONNMAN_STATE_ONLINE:
INF("Disconnect %s", path);
econnman_service_disconnect(cs, _econnman_disconnect_cb, (void *) path);
break;
default:
INF("Connect %s", path);
econnman_service_connect(cs, _econnman_connect_cb, (void *) path);
break;
}
}
static void _econnman_popup_update(struct Connman_Manager *cm,
E_Connman_Instance *inst)
{
@ -67,7 +115,8 @@ static void _econnman_popup_update(struct Connman_Manager *cm,
EINA_INLIST_FOREACH(cm->services, cs)
{
Evas_Object *icon = _econnman_service_new_icon(cs, evas);
e_widget_ilist_append(list, icon, cs->name, NULL, NULL, cs->obj.path);
e_widget_ilist_append(list, icon, cs->name, _econnman_popup_selected_cb,
inst, cs->obj.path);
}
e_widget_ilist_thaw(list);