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
***************************************

Reply via email to