diff --git a/src/ctl/ctl-wifi.c b/src/ctl/ctl-wifi.c index f9d854e..88bb445 100644 --- a/src/ctl/ctl-wifi.c +++ b/src/ctl/ctl-wifi.c @@ -946,14 +946,9 @@ static int ctl_wifi_peer_fn(sd_bus *bus, _shl_free_ char *label = NULL; struct ctl_wifi *w = data; struct ctl_peer *p; - const char *t, *prov, *pin; + const char *t; int r; - if (!sd_bus_message_is_signal(m, - "org.freedesktop.miracle.wifi.Peer", - "ProvisionDiscovery")) - return 0; - t = sd_bus_message_get_path(m); if (!t) return cli_EINVAL(); @@ -963,16 +958,36 @@ static int ctl_wifi_peer_fn(sd_bus *bus, &label); if (r < 0) { return cli_ERR(r); + } else if (r == 0) { + return 0; } else if (r > 0) { p = ctl_wifi_find_peer(w, label); if (!p) return 0; + } + + if (sd_bus_message_is_signal(m, + "org.freedesktop.miracle.wifi.Peer", + "ProvisionDiscovery")) { + /* provision discovery */ + const char *prov, *pin; r = sd_bus_message_read(m, "ss", &prov, &pin); if (r < 0) return cli_log_parser(r); ctl_fn_peer_provision_discovery(p, prov, pin); + } else if (sd_bus_message_is_signal(m, + "org.freedesktop.miracle.wifi.Peer", + "FormationFailure")) { + /* group formation failure */ + const char *reason; + + r = sd_bus_message_read(m, "s", &reason); + if (r < 0) + return cli_log_parser(r); + + ctl_fn_peer_formation_failure(p, reason); } return 0; diff --git a/src/ctl/ctl.h b/src/ctl/ctl.h index 3d5356b..47c37ae 100644 --- a/src/ctl/ctl.h +++ b/src/ctl/ctl.h @@ -251,6 +251,7 @@ void ctl_fn_peer_free(struct ctl_peer *p); void ctl_fn_peer_provision_discovery(struct ctl_peer *p, const char *prov, const char *pin); +void ctl_fn_peer_formation_failure(struct ctl_peer *p, const char *reason); void ctl_fn_peer_connected(struct ctl_peer *p); void ctl_fn_peer_disconnected(struct ctl_peer *p); void ctl_fn_link_new(struct ctl_link *l); diff --git a/src/ctl/sinkctl.c b/src/ctl/sinkctl.c index e37fa46..f865b1d 100644 --- a/src/ctl/sinkctl.c +++ b/src/ctl/sinkctl.c @@ -464,6 +464,21 @@ void ctl_fn_peer_provision_discovery(struct ctl_peer *p, } } +void ctl_fn_peer_formation_failure(struct ctl_peer *p, const char *reason) +{ + if (p->l != running_link || shl_isempty(p->wfd_subelements)) + return; + + if (cli_running()) + cli_printf("[" CLI_YELLOW "FAIL" CLI_DEFAULT "] Peer: %s Reason: %s\n", + p->label, reason); + + if (!running_peer) { + stop_timeout(&scan_timeout); + ctl_link_set_p2p_scanning(p->l, true); + } +} + void ctl_fn_peer_connected(struct ctl_peer *p) { if (p->l != running_link || shl_isempty(p->wfd_subelements)) diff --git a/src/ctl/wifictl.c b/src/ctl/wifictl.c index 5c9ffe0..f15df55 100644 --- a/src/ctl/wifictl.c +++ b/src/ctl/wifictl.c @@ -364,6 +364,13 @@ void ctl_fn_peer_provision_discovery(struct ctl_peer *p, p->label, prov, pin); } +void ctl_fn_peer_formation_failure(struct ctl_peer *p, const char *reason) +{ + if (cli_running()) + cli_printf("[" CLI_YELLOW "FAIL" CLI_DEFAULT "] Peer: %s Reason: %s\n", + p->label, reason); +} + void ctl_fn_peer_connected(struct ctl_peer *p) { if (cli_running()) diff --git a/src/wifi/wifid-dbus.c b/src/wifi/wifid-dbus.c index 042778b..35052a8 100644 --- a/src/wifi/wifid-dbus.c +++ b/src/wifi/wifid-dbus.c @@ -408,6 +408,24 @@ void peer_dbus_provision_discovery(struct peer *p, log_vERR(r); } +void peer_dbus_formation_failure(struct peer *p, const char *reason) +{ + _shl_free_ char *node = NULL; + int r; + + node = peer_dbus_get_path(p); + if (!node) + return; + + r = sd_bus_emit_signal(p->l->m->bus, + node, + "org.freedesktop.miracle.wifi.Peer", + "FormationFailure", + "s", reason); + if (r < 0) + log_vERR(r); +} + void peer_dbus_added(struct peer *p) { _shl_free_ char *node = NULL; diff --git a/src/wifi/wifid-peer.c b/src/wifi/wifid-peer.c index 12101bf..5f16829 100644 --- a/src/wifi/wifid-peer.c +++ b/src/wifi/wifid-peer.c @@ -200,6 +200,15 @@ void peer_supplicant_provision_discovery(struct peer *p, peer_dbus_provision_discovery(p, prov, pin); } +void peer_supplicant_formation_failure(struct peer *p, + const char *reason) +{ + if (!p || !p->public) + return; + + peer_dbus_formation_failure(p, reason); +} + void peer_supplicant_connected_changed(struct peer *p, bool connected) { if (!p || p->connected == connected) diff --git a/src/wifi/wifid-supplicant.c b/src/wifi/wifid-supplicant.c index 7d4d6f9..e478b64 100644 --- a/src/wifi/wifid-supplicant.c +++ b/src/wifi/wifid-supplicant.c @@ -747,6 +747,8 @@ int supplicant_peer_connect(struct supplicant_peer *sp, if (r < 0) return log_ERR(r); + sp->s->pending = sp; + return 0; } @@ -1220,6 +1222,23 @@ static void supplicant_event_p2p_group_removed(struct supplicant *s, supplicant_group_free(g); } +static void supplicant_event_p2p_group_formation_failure(struct supplicant *s, + struct wpas_message *ev) +{ + struct peer *p; + + /* There is no useful information in this event at all. Why would + * anyone want to know to which group formation (or even peer?) this + * event belongs to? No, we have to track all that ourselves, sigh.. */ + if (s->pending) { + log_debug("peer %s connection failed", + s->pending->friendly_name); + p = s->pending->p; + s->pending = NULL; + peer_supplicant_formation_failure(p, "unknown"); + } +} + static void supplicant_event_ap_sta_connected(struct supplicant *s, struct wpas_message *ev) { @@ -1365,6 +1384,8 @@ static void supplicant_event(struct supplicant *s, struct wpas_message *m) supplicant_event_p2p_group_started(s, m); else if (!strcmp(name, "P2P-GROUP-REMOVED")) supplicant_event_p2p_group_removed(s, m); + else if (!strcmp(name, "P2P-GROUP-FORMATION-FAILURE")) + supplicant_event_p2p_group_formation_failure(s, m); else if (!strcmp(name, "AP-STA-CONNECTED")) supplicant_event_ap_sta_connected(s, m); else if (!strcmp(name, "AP-STA-DISCONNECTED")) diff --git a/src/wifi/wifid.h b/src/wifi/wifid.h index 90da9d4..62d5346 100644 --- a/src/wifi/wifid.h +++ b/src/wifi/wifid.h @@ -101,6 +101,7 @@ void peer_supplicant_wfd_subelements_changed(struct peer *p); void peer_supplicant_provision_discovery(struct peer *p, const char *prov, const char *pin); +void peer_supplicant_formation_failure(struct peer *p, const char *reason); void peer_supplicant_connected_changed(struct peer *p, bool connected); _shl_sentinel_ @@ -108,6 +109,7 @@ void peer_dbus_properties_changed(struct peer *p, const char *prop, ...); void peer_dbus_provision_discovery(struct peer *p, const char *prov, const char *pin); +void peer_dbus_formation_failure(struct peer *p, const char *reason); void peer_dbus_added(struct peer *p); void peer_dbus_removed(struct peer *p);