From dd3c8eac9cba57a8b2bdc03ee6c98841978f8c90 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 11 Feb 2014 14:15:01 +0100 Subject: [PATCH] miracled: hook up peer-connection with dbus Hook up the peer-dbus API with the underlying peer objects. This allows to handle incoming requests and deal with connection issues. Signed-off-by: David Herrmann --- src/miracled-dbus.c | 65 ++++++++++++++++++++++++++++++++++++--- src/miracled-peer.c | 74 +++++++++++++++++++++++++++++++++++++++++++++ src/miracled.h | 8 +++++ 3 files changed, 142 insertions(+), 5 deletions(-) diff --git a/src/miracled-dbus.c b/src/miracled-dbus.c index 4981f8f..6b6f373 100644 --- a/src/miracled-dbus.c +++ b/src/miracled-dbus.c @@ -43,25 +43,55 @@ static int peer_dbus_allow(sd_bus *bus, sd_bus_message *msg, void *data, sd_bus_error *err) { - return -EINVAL; + struct peer *p = data; + const char *pin; + int r; + + r = sd_bus_message_read(msg, "s", &pin); + if (r < 0) + return r; + + r = peer_allow(p, pin); + if (r < 0) + return r; + + return sd_bus_reply_method_return(msg, NULL); } static int peer_dbus_reject(sd_bus *bus, sd_bus_message *msg, void *data, sd_bus_error *err) { - return -EINVAL; + struct peer *p = data; + + peer_reject(p); + return sd_bus_reply_method_return(msg, NULL); } static int peer_dbus_connect(sd_bus *bus, sd_bus_message *msg, void *data, sd_bus_error *err) { - return -EINVAL; + struct peer *p = data; + const char *prov, *pin; + int r; + + r = sd_bus_message_read(msg, "ss", &prov, &pin); + if (r < 0) + return r; + + r = peer_connect(p, prov, pin); + if (r < 0) + return r; + + return sd_bus_reply_method_return(msg, NULL); } static int peer_dbus_disconnect(sd_bus *bus, sd_bus_message *msg, void *data, sd_bus_error *err) { - return -EINVAL; + struct peer *p = data; + + peer_disconnect(p); + return sd_bus_reply_method_return(msg, NULL); } static int peer_dbus_get_link(sd_bus *bus, @@ -199,7 +229,7 @@ static const sd_bus_vtable peer_dbus_vtable[] = { peer_dbus_reject, 0), SD_BUS_METHOD("Connect", - NULL, + "ss", NULL, peer_dbus_connect, 0), @@ -264,6 +294,31 @@ static int peer_dbus_find(sd_bus *bus, return 1; } +void peer_dbus_provision_request(struct peer *p, + const char *type, + const char *pin) +{ + _cleanup_free_ char *path = NULL; + int r; + + if (!type) + return; + if (!pin) + pin = ""; + + path = shl_strcat("/org/freedesktop/miracle/peer/", p->name); + if (!path) + return log_vENOMEM(); + + r = sd_bus_emit_signal(p->l->m->bus, + path, + "org.freedesktop.miracle.Peer", + "ProvisionRequest", + "ss", type, pin); + if (r < 0) + log_vERR(r); +} + void peer_dbus_properties_changed(struct peer *p, const char *prop, ...) { _cleanup_free_ char *path = NULL; diff --git a/src/miracled-peer.c b/src/miracled-peer.c index 1acf45f..91d991b 100644 --- a/src/miracled-peer.c +++ b/src/miracled-peer.c @@ -205,13 +205,49 @@ const char *peer_get_remote_address(struct peer *p) return NULL; } +static const char *peer_provision_str[WIFI_PROVISION_CNT] = { + [WIFI_PROVISION_PBC] = "pbc", + [WIFI_PROVISION_DISPLAY] = "display", + [WIFI_PROVISION_PIN] = "pin", +}; + +static const char *peer_provision_to_str(unsigned int prov) +{ + if (prov >= WIFI_PROVISION_CNT) + return NULL; + + return peer_provision_str[prov]; +} + +static unsigned int peer_provision_from_str(const char *prov) +{ + unsigned int i; + + if (!prov || !*prov) + return WIFI_PROVISION_CNT; + + for (i = 0; i < WIFI_PROVISION_CNT; ++i) + if (peer_provision_str[i]) + if (!strcmp(prov, peer_provision_str[i])) + return i; + + return WIFI_PROVISION_CNT; +} + void peer_process_wifi(struct peer *p, struct wifi_event *ev) { + const char *prov; + if (!p || !p->d) return; switch (ev->type) { case WIFI_DEV_PROVISION: + prov = peer_provision_to_str(ev->dev_provision.type); + if (!prov) + break; + + peer_dbus_provision_request(p, prov, ev->dev_provision.pin); break; case WIFI_DEV_CONNECT: peer_dbus_properties_changed(p, "Connected", NULL); @@ -224,3 +260,41 @@ void peer_process_wifi(struct peer *p, struct wifi_event *ev) break; } } + +int peer_allow(struct peer *p, const char *pin) +{ + if (!p || !p->d) + return -EOPNOTSUPP; + + wifi_dev_allow(p->d, pin); + return 0; +} + +void peer_reject(struct peer *p) +{ + if (!p || !p->d) + return; + + wifi_dev_reject(p->d); +} + +int peer_connect(struct peer *p, const char *prov, const char *pin) +{ + if (!p || !p->d) + return -EOPNOTSUPP; + + if (!prov) + prov = ""; + if (!pin) + pin = ""; + + return wifi_dev_connect(p->d, peer_provision_from_str(prov), pin); +} + +void peer_disconnect(struct peer *p) +{ + if (!p || !p->d) + return; + + wifi_dev_disconnect(p->d); +} diff --git a/src/miracled.h b/src/miracled.h index 2b4c1c2..c03367c 100644 --- a/src/miracled.h +++ b/src/miracled.h @@ -71,6 +71,11 @@ const char *peer_get_remote_address(struct peer *p); void peer_process_wifi(struct peer *p, struct wifi_event *ev); +int peer_allow(struct peer *p, const char *pin); +void peer_reject(struct peer *p); +int peer_connect(struct peer *p, const char *prov, const char *pin); +void peer_disconnect(struct peer *p); + /* link */ enum link_type { @@ -143,6 +148,9 @@ struct peer *manager_find_peer(struct manager *m, const char *name); /* dbus */ +void peer_dbus_provision_request(struct peer *p, + const char *type, + const char *pin); _shl_sentinel_ void peer_dbus_properties_changed(struct peer *p, const char *prop, ...); void peer_dbus_added(struct peer *p);