Thus the upper layer, if providing an agent, will get a report from connman and it will be possible at this point to ask for a proper retry. --- src/peer.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 13 deletions(-)
diff --git a/src/peer.c b/src/peer.c index 50df50e..feb8e75 100644 --- a/src/peer.c +++ b/src/peer.c @@ -27,6 +27,8 @@ #include <gdbus.h> #include <gdhcp/gdhcp.h> +#include <connman/agent.h> + #include "connman.h" static DBusConnection *connection = NULL; @@ -464,6 +466,7 @@ static int peer_disconnect(struct connman_peer *peer) { int err = -ENOTSUP; + connman_agent_cancel(peer); reply_pending(peer, ECONNABORTED); if (peer->connection_master) @@ -660,6 +663,55 @@ static int start_dhcp_client(struct connman_peer *peer) return __connman_dhcp_start(peer->ipconfig, NULL, dhcp_callback, peer); } +static void report_error_cb(void *user_context, bool retry, void *user_data) +{ + struct connman_peer *peer = user_context; + + if (retry) { + int err; + err = peer_connect(peer); + + if (err == 0 || err == -EINPROGRESS) + return; + } + + reply_pending(peer, ENOTCONN); + + peer_disconnect(peer); + + if (!peer->connection_master) { + __connman_dhcp_stop(peer->ipconfig); + __connman_ipconfig_disable(peer->ipconfig); + } else + stop_dhcp_server(peer); + + peer->connection_master = false; + peer->sub_device = NULL; +} + +static const char *get_dbus_sender(struct connman_peer *peer) +{ + if (!peer->pending) + return NULL; + + return dbus_message_get_sender(peer->pending); +} + +static int manage_peer_error(struct connman_peer *peer) +{ + int err; + + err = __connman_agent_report_peer_error(peer, peer->path, + "connect-failed", report_error_cb, + get_dbus_sender(peer), NULL); + if (err != -EINPROGRESS) { + report_error_cb(peer, false, NULL); + return err; + } + + return 0; +} + int connman_peer_set_state(struct connman_peer *peer, enum connman_peer_state new_state) { @@ -697,19 +749,8 @@ int connman_peer_set_state(struct connman_peer *peer, break; case CONNMAN_PEER_STATE_FAILURE: - reply_pending(peer, ENOTCONN); - - peer_disconnect(peer); - - if (!peer->connection_master) { - __connman_dhcp_stop(peer->ipconfig); - __connman_ipconfig_disable(peer->ipconfig); - } else - stop_dhcp_server(peer); - - peer->connection_master = false; - peer->sub_device = NULL; - + if (manage_peer_error(peer) == 0) + return 0; break; }; @@ -852,6 +893,7 @@ void connman_peer_unregister(struct connman_peer *peer) if (!peer->path || !peer->registered) return; + connman_agent_cancel(peer); reply_pending(peer, EIO); g_dbus_unregister_interface(connection, peer->path, -- 1.8.5.5 _______________________________________________ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman