Send connman mailing list submissions to connman@lists.01.org To subscribe or unsubscribe via the World Wide Web, visit https://lists.01.org/mailman/listinfo/connman or, via email, send a message with subject or body 'help' to connman-requ...@lists.01.org
You can reach the person managing the list at connman-ow...@lists.01.org When replying, please edit your Subject line so it is more specific than "Re: Contents of connman digest..." Today's Topics: 1. [PATCH 4/4] wps: add new WPS API for technology (natsuki.it...@sony.com) 2. [PATCH 1/2] connection: Set and unset active flag when changing default gateway (Jussi Laakkonen) 3. [PATCH 2/2] connection: Check for active flag when updating default gateway (Jussi Laakkonen) ---------------------------------------------------------------------- Message: 1 Date: Fri, 31 Aug 2018 11:17:47 +0000 From: <natsuki.it...@sony.com> To: <w...@monom.org> Cc: <connman@lists.01.org>, <i...@lists.01.org>, <natsuki.it...@sony.com> Subject: [PATCH 4/4] wps: add new WPS API for technology Message-ID: <7a4e6fce7871824e939cd5043f4016402ad14...@jpyokxms103.jp.sony.com> Content-Type: text/plain; charset="us-ascii" This implementation is follow the the original patch. https://lists.01.org/pipermail/connman/2018-January/022367.html Signed-off-by: n-itaya <natsuki.it...@sony.com> --- include/technology.h | 20 +++- src/technology.c | 233 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 1 deletion(-) diff --git a/include/technology.h b/include/technology.h index 97db6607..febf6685 100644 --- a/include/technology.h +++ b/include/technology.h @@ -34,10 +34,19 @@ extern "C" { * @short_description: Functions for handling technology details */ +enum connman_technology_wps_mode { + CONNMAN_TECHNOLOGY_WPS_STA_MODE = 0, + CONNMAN_TECHNOLOGY_WPS_AP_MODE = 1, +}; + struct connman_technology; int connman_technology_tethering_notify(struct connman_technology *technology, - bool enabled); + bool enabled); + +void connman_technology_wps_state_change_notify +(struct connman_technology *technology, const char *state); + int connman_technology_set_regdom(const char *alpha2); void connman_technology_regdom_notify(struct connman_technology *technology, const char *alpha2); @@ -46,6 +55,11 @@ bool connman_technology_get_wifi_tethering(const char **ssid, const char **psk); bool connman_technology_is_tethering_allowed(enum connman_service_type type); +void connman_technology_add_wps_offered(struct connman_technology *technology, + const char *path); +void connman_technology_reply_start_sta_wps +(struct connman_technology *technology, int error); + struct connman_technology_driver { const char *name; enum connman_service_type type; @@ -62,6 +76,10 @@ struct connman_technology_driver { const char *bridge, bool enabled); int (*set_regdom) (struct connman_technology *technology, const char *alpha2); + int (*start_wps)(struct connman_technology *technology, + enum connman_technology_wps_mode mode, + const char *wps_pin); + int (*cancel_wps)(struct connman_technology *technology); }; int connman_technology_driver_register(struct connman_technology_driver *driver); diff --git a/src/technology.c b/src/technology.c index 4c1cbbbb..906a6ec3 100644 --- a/src/technology.c +++ b/src/technology.c @@ -74,6 +74,14 @@ struct connman_technology { DBusMessage *pending_reply; guint pending_timeout; + /* + * Used to handle WPS errors within the two-minute interval. + * It is done only for WPS in STA mode, because for AP the + * wpa_supplicant does not report any events/errors. + */ + DBusMessage *wps_reply; + GSList *wps_offered; + GSList *scan_pending; bool rfkill_driven; @@ -277,6 +285,15 @@ static int set_tethering(struct connman_technology *technology, return result; } +void connman_technology_wps_state_change_notify( + struct connman_technology *technology, + const char *state) +{ + connman_dbus_property_changed_basic(technology->path, + CONNMAN_TECHNOLOGY_INTERFACE, "WpsState", + DBUS_TYPE_STRING, &state); +} + void connman_technology_regdom_notify(struct connman_technology *technology, const char *alpha2) { @@ -576,6 +593,214 @@ static void technology_removed_signal(struct connman_technology *technology) DBUS_TYPE_INVALID); } +void connman_technology_add_wps_offered(struct connman_technology *technology, + const char *path) +{ + char *dup_path = g_strdup(path); + + if (!dup_path) + return; + technology->wps_offered = + g_slist_append(technology->wps_offered, dup_path); +} + +static void append_wps_service_structs(DBusMessageIter *iter, void *user_data) +{ + struct connman_technology *technology = user_data; + GSList *list; + + for (list = technology->wps_offered; list; list = list->next) { + const char *ident = list->data; + struct connman_service *service; + + service = __connman_service_lookup_from_ident(ident); + if (!service) + continue; + __connman_service_append_struct(service, iter); + } +} + +static DBusMessage +*create_reply_start_sta_wps_success( + struct connman_technology *technology, + DBusMessage *reply) +{ + DBusMessage *msg; + + msg = dbus_message_new_method_return(reply); + if (!msg) + return NULL; + + __connman_dbus_append_objpath_dict_array(msg, + append_wps_service_structs, + technology); + + return msg; +} + +static void free_wps_offered(gpointer data, gpointer user_data) +{ + if (!data) + return; + + g_free(data); +} + +void +connman_technology_reply_start_sta_wps(struct connman_technology *technology, + int error) +{ + DBusMessage *reply; + + if (!technology->wps_reply) + return; + + if (error < 0) + reply = __connman_error_failed(technology->wps_reply, -error); + else { + reply = create_reply_start_sta_wps_success(technology, + technology->wps_reply); + } + + g_dbus_send_message(connection, reply); + + dbus_message_unref(technology->wps_reply); + technology->wps_reply = NULL; + + g_slist_foreach(technology->wps_offered, free_wps_offered, NULL); + g_slist_free(technology->wps_offered); + technology->wps_offered = NULL; +} + +static int start_wps(struct connman_technology *technology, + DBusMessage *msg, enum connman_technology_wps_mode mode) +{ + GSList *tech_drivers; + DBusMessageIter iter; + enum connman_peer_wps_method wps_method; + const char *auth; + int err, result = -EOPNOTSUPP; + + if (technology->type != CONNMAN_SERVICE_TYPE_WIFI) + return -EOPNOTSUPP; + + __sync_synchronize(); + if (!technology->enabled) + return -EACCES; + + if (!dbus_message_iter_init(msg, &iter)) + return -EINVAL; + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) + return -EINVAL; + + dbus_message_iter_get_basic(&iter, &auth); + + wps_method = __connman_check_wps_method(auth); + if (wps_method == CONNMAN_PEER_WPS_UNKNOWN) + return -EINVAL; + if (wps_method == CONNMAN_PEER_WPS_PBC) + auth = NULL; + + for (tech_drivers = technology->driver_list; tech_drivers; + tech_drivers = g_slist_next(tech_drivers)) { + struct connman_technology_driver *driver = tech_drivers->data; + + if (!driver || + !driver->start_wps || + driver->type != CONNMAN_SERVICE_TYPE_WIFI) + continue; + + err = driver->start_wps(technology, mode, auth); + + if (result == -EINPROGRESS) + continue; + + if (err == -EINPROGRESS) + result = err; + } + + return result; +} + +static DBusMessage *start_ap_wps(DBusConnection *conn, DBusMessage *msg, + void *user_data) +{ + struct connman_technology *technology = user_data; + int err; + + /* It is required to enable tethering before starting WPS in AP mode */ + if (!technology->tethering) { + DBG("Error: Tethering is required"); + return __connman_error_permission_denied(msg); + } + + err = start_wps(technology, msg, CONNMAN_TECHNOLOGY_WPS_AP_MODE); + if (err == -EINPROGRESS) + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); + + return __connman_error_failed(msg, -err); +} + +static DBusMessage *start_sta_wps(DBusConnection *conn, DBusMessage *msg, + void *user_data) +{ + struct connman_technology *technology = user_data; + int err; + + if (technology->wps_reply) + connman_technology_reply_start_sta_wps(technology, + -ECONNABORTED); + + err = start_wps(technology, msg, CONNMAN_TECHNOLOGY_WPS_STA_MODE); + if (err == -EINPROGRESS) { + technology->wps_reply = dbus_message_ref(msg); + return NULL; + } + + return __connman_error_failed(msg, -err); +} + +static DBusMessage *cancel_wps(DBusConnection *conn, DBusMessage *msg, + void *user_data) +{ + struct connman_technology *technology = user_data; + GSList *tech_drivers; + int err = 0, result = -EOPNOTSUPP; + + if (technology->type != CONNMAN_SERVICE_TYPE_WIFI) + return __connman_error_not_supported(msg); + + __sync_synchronize(); + if (!technology->enabled) + return __connman_error_permission_denied(msg); + + if (technology->wps_reply) + connman_technology_reply_start_sta_wps(technology, + -ECONNABORTED); + + for (tech_drivers = technology->driver_list; tech_drivers; + tech_drivers = g_slist_next(tech_drivers)) { + struct connman_technology_driver *driver = tech_drivers->data; + + if (!driver || !driver->cancel_wps || + driver->type != CONNMAN_SERVICE_TYPE_WIFI) + continue; + + err = driver->cancel_wps(technology); + if (result == -EINPROGRESS) + continue; + + if (err == -EINPROGRESS) + result = err; + } + + if (result == -EINPROGRESS) + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); + + return __connman_error_failed(msg, -result); +} + static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *message, void *user_data) { @@ -1098,6 +1323,14 @@ static const GDBusMethodTable technology_methods[] = { GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL, set_property) }, { GDBUS_ASYNC_METHOD("Scan", NULL, NULL, scan) }, + { GDBUS_ASYNC_METHOD("Start_AP_WPS", + GDBUS_ARGS({ "authentication", "s" }), + NULL, start_ap_wps) }, + { GDBUS_ASYNC_METHOD("Start_STA_WPS", + GDBUS_ARGS({ "authentication", "s" }), + NULL, start_sta_wps) }, + { GDBUS_ASYNC_METHOD("Cancel_WPS", + NULL, NULL, cancel_wps) }, { }, }; -- 2.17.1 ------------------------------ Message: 2 Date: Fri, 31 Aug 2018 14:35:23 +0300 From: Jussi Laakkonen <jussi.laakko...@jolla.com> To: connman@lists.01.org Subject: [PATCH 1/2] connection: Set and unset active flag when changing default gateway Message-ID: <1535715324-2522-1-git-send-email-jussi.laakko...@jolla.com> The active flag for gateway should be set also when it is set or unset as default gateway as it is done with VPN gateways. The active flag is used in finding the active gateway (find_active_gateway(), choosing the default gateway (choose_default_gateway()), updating the default gateway (__connman_connection_update_gateway()) and to delete routes (disable_gateway()). The active flag is set/unset when adding or removing the gateway but not touched when updating the interface using set_default_gateway() and unset_default_gateway(). This adds setting of the flag in both of the uses of the set/unset default gateway and unset_default_gateway(). This adds setting of the flag in both of the uses of the set/unset default gateway. --- src/connection.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/connection.c b/src/connection.c index 6b005e7..198432f 100644 --- a/src/connection.c +++ b/src/connection.c @@ -460,6 +460,7 @@ static void set_default_gateway(struct gateway_data *data, "0.0.0.0") == 0) { if (connman_inet_set_gateway_interface(index) < 0) return; + data->ipv4_gateway->active = true; goto done; } @@ -468,6 +469,7 @@ static void set_default_gateway(struct gateway_data *data, "::") == 0) { if (connman_inet_set_ipv6_gateway_interface(index) < 0) return; + data->ipv6_gateway->active = true; goto done; } @@ -534,6 +536,7 @@ static void unset_default_gateway(struct gateway_data *data, g_strcmp0(data->ipv4_gateway->gateway, "0.0.0.0") == 0) { connman_inet_clear_gateway_interface(index); + data->ipv4_gateway->active = false; return; } @@ -541,6 +544,7 @@ static void unset_default_gateway(struct gateway_data *data, g_strcmp0(data->ipv6_gateway->gateway, "::") == 0) { connman_inet_clear_ipv6_gateway_interface(index); + data->ipv6_gateway->active = false; return; } -- 2.7.4 ------------------------------ Message: 3 Date: Fri, 31 Aug 2018 14:35:24 +0300 From: Jussi Laakkonen <jussi.laakko...@jolla.com> To: connman@lists.01.org Subject: [PATCH 2/2] connection: Check for active flag when updating default gateway Message-ID: <1535715324-2522-2-git-send-email-jussi.laakko...@jolla.com> Set default gateway if it has been updated or if it has not been set as active yet. The check for active interface is required in cases that are induced by a race condition caused by a change of interfaces that are either too fast or too slow to go down, or to get up. In such case the interface that should be used as default gateway may end up with no default route set in routing table. This is because the change happens in a situation where the old default service A going down is still online, when the new service B that is becoming the new default, is still in ready state. The new default service B is not detected as default gateway because of the service list order. The new service B has been added to gateway_hash and the routes other than the default route have been set into routing table. After this the routes of the old default service A are removed but because of the old default service A still being the default service according to service list, the removal of routes of the old default service A does not get the new default gateway B to be selected as the default gateway. After this the old default service A is properly disconnected and set to idle setting the new default service B as the default service. The next call to this update gateway function results in a situation where updated flag is not set, hence new default service B is the only one in the gateway_hash. By checking also the active flag of the gateway the new default gateway B in the scenario above will have a default route set also in routing table. --- src/connection.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/connection.c b/src/connection.c index 198432f..582f34d 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1012,12 +1012,18 @@ bool __connman_connection_update_gateway(void) } } - if (updated && default_gateway) { - if (default_gateway->ipv4_gateway) + /* + * Set default gateway if it has been updated or if it has not been + * set as active yet. + */ + if (default_gateway) { + if (default_gateway->ipv4_gateway && + (updated || !default_gateway->ipv4_gateway->active)) set_default_gateway(default_gateway, CONNMAN_IPCONFIG_TYPE_IPV4); - if (default_gateway->ipv6_gateway) + if (default_gateway->ipv6_gateway && + (updated || !default_gateway->ipv6_gateway->active)) set_default_gateway(default_gateway, CONNMAN_IPCONFIG_TYPE_IPV6); } -- 2.7.4 ------------------------------ Subject: Digest Footer _______________________________________________ connman mailing list connman@lists.01.org https://lists.01.org/mailman/listinfo/connman ------------------------------ End of connman Digest, Vol 34, Issue 25 ***************************************