[PATCH] wifi: implemented feature of tracking tethering clients
by Vasyl Vavrychuk
wpa_supplicant supports StaAuthorized StaDeauthorized D-Bus signal that
we handle and store information. Then stored information about connected
tethering clients is exposed via GetTetheringClients method and
TetheringClientsChanged signal of manager.
---
Makefile.am | 3 +-
client/commands.c | 27 ++++++++
client/tethering.c | 62 +++++++++++++++++++
client/tethering.h | 38 ++++++++++++
doc/manager-api.txt | 12 ++++
gsupplicant/gsupplicant.h | 4 ++
gsupplicant/supplicant.c | 64 +++++++++++++++++++
include/tethering.h | 36 +++++++++++
plugins/wifi.c | 29 +++++++++
src/connman.h | 3 +
src/manager.c | 24 ++++++++
src/tethering.c | 126 ++++++++++++++++++++++++++++++++++++++
12 files changed, 427 insertions(+), 1 deletion(-)
create mode 100644 client/tethering.c
create mode 100644 client/tethering.h
create mode 100644 include/tethering.h
diff --git a/Makefile.am b/Makefile.am
index d6dfbf1c..4614cb90 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,7 +12,7 @@ include_HEADERS = include/log.h include/plugin.h \
include/storage.h include/provision.h \
include/session.h include/ipaddress.h include/agent.h \
include/inotify.h include/peer.h include/machine.h \
- include/acd.h
+ include/acd.h include/tethering.h
nodist_include_HEADERS = include/version.h
@@ -308,6 +308,7 @@ client_connmanctl_SOURCES = client/dbus_helpers.h client/dbus_helpers.c \
client/input.h client/input.c \
client/agent.h client/agent.c \
client/peers.h client/peers.c \
+ client/tethering.h client/tethering.c \
client/vpnconnections.h client/vpnconnections.c \
client/main.c
diff --git a/client/commands.c b/client/commands.c
index bf3531fd..26d2c509 100644
--- a/client/commands.c
+++ b/client/commands.c
@@ -318,6 +318,18 @@ static int peers_list(DBusMessageIter *iter,
return 0;
}
+static int tethering_clients_list(DBusMessageIter *iter,
+ const char *error, void *user_data)
+{
+ if (!error) {
+ __connmanctl_tethering_clients_list(iter);
+ fprintf(stdout, "\n");
+ } else
+ fprintf(stderr, "Error: %s\n", error);
+
+ return 0;
+}
+
static int object_properties(DBusMessageIter *iter,
const char *error, void *user_data)
{
@@ -639,6 +651,19 @@ static int cmd_tether(char *args[], int num, struct connman_option *options)
return tether_set(args[1], set_tethering);
}
+static int cmd_tethering_clients(char *args[], int num, struct connman_option *options)
+{
+ char *path;
+
+ if (num > 1)
+ return -E2BIG;
+
+ return __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager", "GetTetheringClients",
+ tethering_clients_list, NULL, NULL, NULL);
+}
+
static int scan_return(DBusMessageIter *iter, const char *error,
void *user_data)
{
@@ -2730,6 +2755,8 @@ static const struct {
NULL, cmd_tether,
"Enable, disable tethering, set SSID and passphrase for wifi",
lookup_tether },
+ { "tethering_clients", NULL, NULL, cmd_tethering_clients,
+ "Display tethering clients", NULL },
{ "services", "[<service>]", service_options, cmd_services,
"Display services", lookup_service_arg },
{ "peers", "[peer]", NULL, cmd_peers,
diff --git a/client/tethering.c b/client/tethering.c
new file mode 100644
index 00000000..ce3688a4
--- /dev/null
+++ b/client/tethering.c
@@ -0,0 +1,62 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2014 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+
+#include "tethering.h"
+
+void __connmanctl_tethering_clients_list(DBusMessageIter *iter)
+{
+ DBusMessageIter array;
+ char *addr = NULL;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
+ dbus_message_iter_get_basic(&array, &addr);
+
+ fprintf(stdout, "%s", addr);
+
+ if (dbus_message_iter_has_next(&array))
+ fprintf(stdout, "\n");
+
+ dbus_message_iter_next(&array);
+ }
+
+ dbus_message_iter_next(iter);
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return;
+
+ dbus_message_iter_recurse(iter, &array);
+ while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
+ dbus_message_iter_get_basic(&array, &addr);
+
+ fprintf(stdout, "\n%s %s", "removed", addr);
+
+ if (dbus_message_iter_has_next(&array))
+ fprintf(stdout, "\n");
+
+ dbus_message_iter_next(&array);
+ }
+}
diff --git a/client/tethering.h b/client/tethering.h
new file mode 100644
index 00000000..c6b58de1
--- /dev/null
+++ b/client/tethering.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2014 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __CONNMANCTL_TETHERING_H
+#define __CONNMANCTL_TETHERING_H
+
+#include <dbus/dbus.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void __connmanctl_tethering_clients_list(DBusMessageIter *iter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CONNMANCTL_TETHERING_H */
diff --git a/doc/manager-api.txt b/doc/manager-api.txt
index 2d2739ff..bfb07bd3 100644
--- a/doc/manager-api.txt
+++ b/doc/manager-api.txt
@@ -46,6 +46,11 @@ Methods dict GetProperties()
Possible Errors: [service].Error.InvalidArguments
+ array{string} GetTetheringClients() [experimental]
+
+ Returns a sorted list of MAC addresses of clients
+ connected to tethered technologies.
+
object ConnectProvider(dict provider) [deprecated]
Connect to a VPN specified by the given provider
@@ -255,6 +260,13 @@ Signals TechnologyAdded(object path, dict properties)
object changes. For that it is required to watch the
PropertyChanged signal of the peer object.
+ TetheringClientsChanged(array{string}, array{string}) [experimental]
+
+ This signal indicates a change in the tethering clients.
+ List of all tethering clients currently registered connman is
+ passed via the first array. And a list of tethering clients that
+ have been removed via the second array.
+
PropertyChanged(string name, variant value)
This signal indicates a changed value of the given
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index db61595b..bfb52db7 100644
--- a/gsupplicant/gsupplicant.h
+++ b/gsupplicant/gsupplicant.h
@@ -352,6 +352,10 @@ struct _GSupplicantCallbacks {
void (*network_changed) (GSupplicantNetwork *network,
const char *property);
void (*network_associated) (GSupplicantNetwork *network);
+ void (*sta_authorized) (GSupplicantInterface *interface,
+ const char *addr);
+ void (*sta_deauthorized) (GSupplicantInterface *interface,
+ const char *addr);
void (*peer_found) (GSupplicantPeer *peer);
void (*peer_lost) (GSupplicantPeer *peer);
void (*peer_changed) (GSupplicantPeer *peer,
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index 0cb621b9..12391482 100644
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -614,6 +614,30 @@ static void callback_network_associated(GSupplicantNetwork *network)
callbacks_pointer->network_associated(network);
}
+static void callback_sta_authorized(GSupplicantInterface *interface,
+ const char *addr)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->sta_authorized)
+ return;
+
+ callbacks_pointer->sta_authorized(interface, addr);
+}
+
+static void callback_sta_deauthorized(GSupplicantInterface *interface,
+ const char *addr)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->sta_deauthorized)
+ return;
+
+ callbacks_pointer->sta_deauthorized(interface, addr);
+}
+
static void callback_peer_found(GSupplicantPeer *peer)
{
if (!callbacks_pointer)
@@ -2731,6 +2755,44 @@ static void signal_network_removed(const char *path, DBusMessageIter *iter)
interface_network_removed(iter, interface);
}
+static void signal_sta_authorized(const char *path, DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+ DBusMessageIter array;
+ const char *addr = NULL;
+
+ SUPPLICANT_DBG("");
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (!interface)
+ return;
+
+ dbus_message_iter_get_basic(iter, &addr);
+ if (!addr)
+ return;
+
+ callback_sta_authorized(interface, addr);
+}
+
+static void signal_sta_deauthorized(const char *path, DBusMessageIter *iter)
+{
+ GSupplicantInterface *interface;
+ DBusMessageIter array;
+ const char *addr = NULL;
+
+ SUPPLICANT_DBG("");
+
+ interface = g_hash_table_lookup(interface_table, path);
+ if (!interface)
+ return;
+
+ dbus_message_iter_get_basic(iter, &addr);
+ if (!addr)
+ return;
+
+ callback_sta_deauthorized(interface, addr);
+}
+
static void signal_bss_changed(const char *path, DBusMessageIter *iter)
{
GSupplicantInterface *interface;
@@ -3505,6 +3567,8 @@ static struct {
{ SUPPLICANT_INTERFACE ".Interface", "BSSRemoved", signal_bss_removed },
{ SUPPLICANT_INTERFACE ".Interface", "NetworkAdded", signal_network_added },
{ SUPPLICANT_INTERFACE ".Interface", "NetworkRemoved", signal_network_removed },
+ { SUPPLICANT_INTERFACE ".Interface", "StaAuthorized", signal_sta_authorized },
+ { SUPPLICANT_INTERFACE ".Interface", "StaDeauthorized", signal_sta_deauthorized },
{ SUPPLICANT_INTERFACE ".BSS", "PropertiesChanged", signal_bss_changed },
diff --git a/include/tethering.h b/include/tethering.h
new file mode 100644
index 00000000..0d29b235
--- /dev/null
+++ b/include/tethering.h
@@ -0,0 +1,36 @@
+/*
+ *
+ * Connection Manager
+ *
+ * Copyright (C) 2007-2013 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef __CONNMAN_TETHERING_H
+#define __CONNMAN_TETHERING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void __connman_tethering_client_register(const char *addr);
+void __connman_tethering_client_unregister(const char *addr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CONNMAN_TETHERING_H */
diff --git a/plugins/wifi.c b/plugins/wifi.c
index e437daeb..6fa20312 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -55,6 +55,7 @@
#include <connman/provision.h>
#include <connman/utsname.h>
#include <connman/machine.h>
+#include <connman/tethering.h>
#include <gsupplicant/gsupplicant.h>
@@ -2985,6 +2986,32 @@ static void network_associated(GSupplicantNetwork *network)
interface_state(interface);
}
+static void sta_authorized(GSupplicantInterface *interface,
+ const char *addr)
+{
+ struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
+
+ DBG("wifi %p station %s authorized", wifi, addr);
+
+ if (!wifi || !wifi->tethering)
+ return;
+
+ __connman_tethering_client_register(addr);
+}
+
+static void sta_deauthorized(GSupplicantInterface *interface,
+ const char *addr)
+{
+ struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
+
+ DBG("wifi %p station %s deauthorized", wifi, addr);
+
+ if (!wifi || !wifi->tethering)
+ return;
+
+ __connman_tethering_client_unregister(addr);
+}
+
static void apply_peer_services(GSupplicantPeer *peer,
struct connman_peer *connman_peer)
{
@@ -3205,6 +3232,8 @@ static const GSupplicantCallbacks callbacks = {
.network_removed = network_removed,
.network_changed = network_changed,
.network_associated = network_associated,
+ .sta_authorized = sta_authorized,
+ .sta_deauthorized = sta_deauthorized,
.peer_found = peer_found,
.peer_lost = peer_lost,
.peer_changed = peer_changed,
diff --git a/src/connman.h b/src/connman.h
index 13553833..dfcacc62 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -630,12 +630,15 @@ bool __connman_config_get_bool(GKeyFile *key_file,
bool __connman_config_address_provisioned(const char *address,
const char *netmask);
+#include <connman/tethering.h>
+
int __connman_tethering_init(void);
void __connman_tethering_cleanup(void);
const char *__connman_tethering_get_bridge(void);
int __connman_tethering_set_enabled(void);
void __connman_tethering_set_disabled(void);
+void __connman_tethering_list_clients(DBusMessageIter *array);
int __connman_private_network_request(DBusMessage *msg, const char *owner);
int __connman_private_network_release(const char *path);
diff --git a/src/manager.c b/src/manager.c
index d15ce203..b2de863c 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -214,6 +214,27 @@ static DBusMessage *get_peers(DBusConnection *conn,
return reply;
}
+static DBusMessage *get_tethering_clients(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter, array;
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &iter);
+
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &array);
+
+ __connman_tethering_list_clients(&array);
+
+ dbus_message_iter_close_container(&iter, &array);
+ return reply;
+}
+
static DBusMessage *connect_provider(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -519,6 +540,9 @@ static const GDBusMethodTable manager_methods[] = {
{ GDBUS_METHOD("GetPeers",
NULL, GDBUS_ARGS({ "peers", "a(oa{sv})" }),
get_peers) },
+ { GDBUS_METHOD("GetTetheringClients",
+ NULL, GDBUS_ARGS({ "tethering_clients", "as" }),
+ get_tethering_clients) },
{ GDBUS_DEPRECATED_ASYNC_METHOD("ConnectProvider",
GDBUS_ARGS({ "provider", "a{sv}" }),
GDBUS_ARGS({ "path", "o" }),
diff --git a/src/tethering.c b/src/tethering.c
index d222afca..61951075 100644
--- a/src/tethering.c
+++ b/src/tethering.c
@@ -61,6 +61,13 @@ static struct connman_ippool *dhcp_ippool = NULL;
static DBusConnection *connection;
static GHashTable *pn_hash;
+static GHashTable *clients_table = NULL;
+
+struct _clients_notify {
+ int id;
+ GHashTable *remove;
+} *clients_notify;
+
struct connman_private_network {
char *owner;
char *path;
@@ -181,6 +188,18 @@ static void tethering_restart(struct connman_ippool *pool, void *user_data)
__connman_tethering_set_enabled();
}
+static void unregister_client(gpointer key,
+ gpointer value, gpointer user_data)
+{
+ const char *addr = key;
+ __connman_tethering_client_unregister(addr);
+}
+
+static void unregister_all_clients(void)
+{
+ g_hash_table_foreach(clients_table, unregister_client, NULL);
+}
+
int __connman_tethering_set_enabled(void)
{
int index;
@@ -301,6 +320,8 @@ void __connman_tethering_set_disabled(void)
if (__sync_fetch_and_sub(&tethering_enabled, 1) != 1)
return;
+ unregister_all_clients();
+
__connman_ipv6pd_cleanup();
index = connman_inet_ifindex(BRIDGE_NAME);
@@ -327,6 +348,21 @@ void __connman_tethering_set_disabled(void)
DBG("tethering stopped");
}
+static void append_client(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ const char *addr = key;
+ DBusMessageIter *array = user_data;
+
+ dbus_message_iter_append_basic(array, DBUS_TYPE_STRING,
+ &addr);
+}
+
+void __connman_tethering_list_clients(DBusMessageIter *array)
+{
+ g_hash_table_foreach(clients_table, append_client, array);
+}
+
static void setup_tun_interface(unsigned int flags, unsigned change,
void *data)
{
@@ -440,6 +476,70 @@ static void ippool_disconnect(struct connman_ippool *pool, void *user_data)
g_hash_table_remove(pn_hash, pn->path);
}
+static gboolean client_send_changed(gpointer data)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter, array;
+
+ DBG("");
+
+ clients_notify->id = 0;
+
+ signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "TetheringClientsChanged");
+ if (!signal)
+ return FALSE;
+
+ dbus_message_iter_init_append(signal, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &array);
+
+ g_hash_table_foreach(clients_table, append_client, &array);
+
+ dbus_message_iter_close_container(&iter, &array);
+
+ dbus_message_iter_init_append(signal, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+ DBUS_TYPE_STRING_AS_STRING, &array);
+
+ g_hash_table_foreach(clients_notify->remove, append_client, &array);
+
+ dbus_message_iter_close_container(&iter, &array);
+
+ dbus_connection_send(connection, signal, NULL);
+ dbus_message_unref(signal);
+
+ g_hash_table_remove_all(clients_notify->remove);
+
+ return FALSE;
+}
+
+static void client_schedule_changed(void)
+{
+ if (clients_notify->id != 0)
+ return;
+
+ clients_notify->id = g_timeout_add(100, client_send_changed, NULL);
+}
+
+static void client_added(const char *addr)
+{
+ DBG("client %s", addr);
+
+ g_hash_table_remove(clients_notify->remove, addr);
+
+ client_schedule_changed();
+}
+
+static void client_removed(const char *addr)
+{
+ DBG("client %s", addr);
+
+ g_hash_table_replace(clients_notify->remove, g_strdup(addr), NULL);
+
+ client_schedule_changed();
+}
+
int __connman_private_network_request(DBusMessage *msg, const char *owner)
{
struct connman_private_network *pn;
@@ -529,6 +629,18 @@ int __connman_private_network_release(const char *path)
return 0;
}
+void __connman_tethering_client_register(const char *addr)
+{
+ g_hash_table_insert(clients_table, g_strdup(addr), NULL);
+ client_added(addr);
+}
+
+void __connman_tethering_client_unregister(const char *addr)
+{
+ g_hash_table_remove(clients_table, g_strdup(addr));
+ client_removed(addr);
+}
+
int __connman_tethering_init(void)
{
DBG("");
@@ -542,6 +654,12 @@ int __connman_tethering_init(void)
pn_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, remove_private_network);
+ clients_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ clients_notify = g_new0(struct _clients_notify, 1);
+ clients_notify->remove = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
return 0;
}
@@ -562,5 +680,13 @@ void __connman_tethering_cleanup(void)
return;
g_hash_table_destroy(pn_hash);
+
+ g_hash_table_destroy(clients_notify->remove);
+ g_free(clients_notify);
+ clients_notify = NULL;
+
+ g_hash_table_destroy(clients_table);
+ clients_table = NULL;
+
dbus_connection_unref(connection);
}
--
2.19.1
2 years, 3 months
Error with UDP server
by Doron Behar
I'm having a problem when I run connman only at home, I keep getting
this error repeatedly in the journal:
Oct 30 22:42:31 NUC connmand[404]: Error with UDP server fdc9:8a32:cbfb:0:16ae:dbff:fe55:f320
According to a reverse whois search, the server IPV6 address specified
in the message belongs to my ISP.
Additionally, I feel like at home my internet connection is much slower
then when I connect to my Android Hotspot WiFi.
Even if I configure this connection with IPV6 off the error persists.
It feels like a problem on my ISP's side but how can I debug this?
2 years, 4 months
[Question] Gateway route in multi-home environment
by Andrea Capirchio
Hi,
I am developing an embedded system running connman 1.36 over linux.
My system is multi-home, so I have one network interface connected to
two subnets that cannot see each other.
Assuming that I have a gateway present on "subnet 2" (relative to "address
2"), and that the
primary address of the interface is "address 1", that was assigned
manually at boot time, I have the following routing table (from $ ip r):
1. <gateway addr> dev <interface>
// added by connman
2. <dns addr> via <gateway addr> dev <interface>
// added by connman
3. <local subnet2>/<netmask2> dev <interface> src <local address2> //
added by connman
4. <local subnet1>/<netmask1> dev <interface> src <local address1> //
added manually
5. default via <gateway addr> dev <interface>
// added by connman
I think that the first rule is wrong.
Explaination:
With this configuration, PING from the device to the gateway is not
working.
This because linux chooses rule number 1 to route the packets to the
gateway, but this does not specify the source IP of the interface, so
the primary IP is chosen as source address.
The primary is the IP relative to "subnet 1" while the gateway can only
communicate with IPs from "subnet 2", so the gateway cannot answer to my
device.
I am considering to patch this, but should the rule be erased?
Or if it is useful to some purpose, should I add the src IP to rule
number 1?
Cheers,
Andrea
2 years, 4 months
[PATCHv6 6/6] wps: add new WPS API for technology
by Natsuki.Itaya@sony.com
Add new WPS APIs, but this APIs are under discution...
Signed-off-by: n-itaya <Natsuki.Itaya(a)sony.com>
---
include/technology.h | 5 +
src/technology.c | 231 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 236 insertions(+)
diff --git a/include/technology.h b/include/technology.h
index 97db6607..830f1d0e 100644
--- a/include/technology.h
+++ b/include/technology.h
@@ -34,6 +34,11 @@ 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,
diff --git a/src/technology.c b/src/technology.c
index 4c1cbbbb..4b72f4b4 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,212 @@ 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) {
+ reply = create_reply_start_sta_wps_success(technology,
+ technology->wps_reply);
+ } else
+ reply = __connman_error_failed(technology->wps_reply, -error);
+
+ 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);
+
+ 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 +1321,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("StartApWps",
+ GDBUS_ARGS({ "authentication", "s" }),
+ NULL, start_ap_wps) },
+ { GDBUS_ASYNC_METHOD("StartStaWps",
+ GDBUS_ARGS({ "authentication", "s" }),
+ NULL, start_sta_wps) },
+ { GDBUS_ASYNC_METHOD("CancelWps",
+ NULL, NULL, cancel_wps) },
{ },
};
--
2.17.1
2 years, 4 months
Crash when running connmand along iwd
by Doron Behar
I have connman version 1.36 and iwd version 0.10 installed and every
time I run iwd along with connman it crashes.
Here is part of the output of `journalctl --unit iwd --unit connman`:
Oct 26 15:04:03 NUC systemd[1]: Starting Wireless service...
Oct 26 15:04:03 NUC iwd[3721]: Wireless daemon version 0.10
Oct 26 15:04:03 NUC systemd[1]: Started Wireless service.
Oct 26 15:04:03 NUC iwd[3721]: Wiphy: 0, Name: phy0
Oct 26 15:04:03 NUC iwd[3721]: Bands: 2.4 GHz 5 GHz
Oct 26 15:04:03 NUC iwd[3721]: Ciphers: CCMP TKIP BIP
Oct 26 15:04:03 NUC iwd[3721]: Supported iftypes: ad-hoc station ap
Oct 26 15:04:03 NUC iwd[3721]: No ControlPortOverNL80211 setting, defaulting to False
Oct 26 15:04:03 NUC connmand[2988]: wlp2s0 {RX} 10603 packets 1056120 bytes
Oct 26 15:04:03 NUC connmand[2988]: wlp2s0 {TX} 420 packets 102727 bytes
Oct 26 15:04:03 NUC connmand[2988]: wlp2s0 {update} flags 36867 <UP>
Oct 26 15:04:03 NUC connmand[2988]: wlp2s0 {newlink} index 3 address 34:13:E8:35:48:E6 mtu 1500
Oct 26 15:04:03 NUC connmand[2988]: wlp2s0 {newlink} index 3 operstate 2 <DOWN>
Oct 26 15:04:03 NUC connmand[2988]: Aborting (signal 11) [/usr/bin/connmand]
Oct 26 15:04:03 NUC connmand[2988]: ++++++++ backtrace ++++++++
Oct 26 15:04:03 NUC connmand[2988]: #0 0x7fc7a3e01e00 in /usr/lib/libc.so.6
Oct 26 15:04:03 NUC connmand[2988]: #1 0x561d85e16ea7 in /usr/bin/connmand
Oct 26 15:04:03 NUC connmand[2988]: #2 0x561d85e1746b in /usr/bin/connmand
Oct 26 15:04:03 NUC connmand[2988]: #3 0x561d85e810d4 in /usr/bin/connmand
Oct 26 15:04:03 NUC connmand[2988]: #4 0x561d85e8235e in /usr/bin/connmand
Oct 26 15:04:03 NUC connmand[2988]: #5 0x561d85e7cd04 in /usr/bin/connmand
Oct 26 15:04:03 NUC connmand[2988]: #6 0x561d85e7cf08 in /usr/bin/connmand
Oct 26 15:04:03 NUC connmand[2988]: #7 0x7fc7a414cd75 in /usr/lib/libdbus-1.so.3
Oct 26 15:04:03 NUC connmand[2988]: #8 0x561d85e7bed1 in /usr/bin/connmand
Oct 26 15:04:03 NUC connmand[2988]: #9 0x7fc7a41f4271 in /usr/lib/libglib-2.0.so.0
Oct 26 15:04:03 NUC connmand[2988]: #10 0x7fc7a41f5f89 in /usr/lib/libglib-2.0.so.0
Oct 26 15:04:03 NUC connmand[2988]: #11 0x7fc7a41f6f62 in /usr/lib/libglib-2.0.so.0
Oct 26 15:04:03 NUC connmand[2988]: #12 0x561d85df6c8b in /usr/bin/connmand
Oct 26 15:04:03 NUC connmand[2988]: #13 0x7fc7a3dee223 in /usr/lib/libc.so.6
Oct 26 15:04:03 NUC connmand[2988]: +++++++++++++++++++++++++++
With `wpa_supplicant` I don't have this problem but I'd really like to
get rid of it and move to `iwd`.
Thanks.
2 years, 4 months
[PATCHv3 4/6] wps: add new WPS API implementation
by Natsuki.Itaya@sony.com
Add the handler which receive WPS credential and force save information
into applicable service.
Add new status property for display WPS status.
Signed-off-by: n-itaya <Natsuki.Itaya(a)sony.com>
---
src/connman.h | 6 ++++++
src/error.c | 16 ++++++++++++++++
src/peer.c | 5 ++---
src/service.c | 21 +++++++++++++++++++++
4 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/src/connman.h b/src/connman.h
index 82e77d37..16ecbb5a 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -54,6 +54,8 @@ DBusMessage *__connman_error_operation_aborted(DBusMessage *msg);
DBusMessage *__connman_error_operation_timeout(DBusMessage *msg);
DBusMessage *__connman_error_invalid_service(DBusMessage *msg);
DBusMessage *__connman_error_invalid_property(DBusMessage *msg);
+DBusMessage *__connman_error_pin_rejected(DBusMessage *msg);
+DBusMessage *__connman_error_pbc_overlap(DBusMessage *msg);
int __connman_manager_init(void);
void __connman_manager_cleanup(void);
@@ -665,6 +667,8 @@ int __connman_service_init(void);
void __connman_service_cleanup(void);
int __connman_service_load_modifiable(struct connman_service *service);
+void __connman_service_append_struct(struct connman_service *service,
+ DBusMessageIter *iter);
void __connman_service_list_struct(DBusMessageIter *iter);
int __connman_service_compare(const struct connman_service *a,
@@ -843,6 +847,7 @@ int __connman_peer_service_unregister(const char *owner,
int specification_length,
const unsigned char *query,
int query_length, int version);
+enum connman_peer_wps_method __connman_check_wps_method(const char *wpspin);
#include <connman/session.h>
@@ -853,6 +858,7 @@ int __connman_service_iterate_services(service_iterate_cb cb, void *user_data);
void __connman_service_mark_dirty();
void __connman_service_save(struct connman_service *service);
+void __connman_service_force_save(struct connman_service *service);
#include <connman/notifier.h>
diff --git a/src/error.c b/src/error.c
index 4f24ae25..f0b35bdc 100644
--- a/src/error.c
+++ b/src/error.c
@@ -67,6 +67,10 @@ DBusMessage *__connman_error_failed(DBusMessage *msg, int errnum)
return __connman_error_in_progress(msg);
case ENOKEY:
return __connman_error_passphrase_required(msg);
+ case EKEYREJECTED:
+ return __connman_error_pin_rejected(msg);
+ case EAGAIN:
+ return __connman_error_pbc_overlap(msg);
}
return g_dbus_create_error(msg, CONNMAN_ERROR_INTERFACE
@@ -185,3 +189,15 @@ DBusMessage *__connman_error_invalid_property(DBusMessage *msg)
return g_dbus_create_error(msg, CONNMAN_ERROR_INTERFACE
".InvalidProperty", "Invalid property");
}
+
+DBusMessage *__connman_error_pin_rejected(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, CONNMAN_ERROR_INTERFACE
+ ".PinRejected", "PIN Rejected");
+}
+
+DBusMessage *__connman_error_pbc_overlap(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, CONNMAN_ERROR_INTERFACE
+ ".PbcOverlap", "PBC Overlap");
+}
diff --git a/src/peer.c b/src/peer.c
index 1b9b80e3..70ffeab4 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -545,8 +545,7 @@ static const char *get_dbus_sender(struct connman_peer *peer)
return dbus_message_get_sender(peer->pending);
}
-static enum connman_peer_wps_method check_wpspin(struct connman_peer *peer,
- const char *wpspin)
+enum connman_peer_wps_method __connman_check_wps_method(const char *wpspin)
{
int len, i;
@@ -591,7 +590,7 @@ static void request_authorization_cb(struct connman_peer *peer,
goto out;
}
- wps_method = check_wpspin(peer, wpspin);
+ wps_method = __connman_check_wps_method(wpspin);
err = peer_driver->connect(peer, wps_method, wpspin);
if (err == -EINPROGRESS)
diff --git a/src/service.c b/src/service.c
index 733c0728..da323d0d 100644
--- a/src/service.c
+++ b/src/service.c
@@ -817,6 +817,15 @@ void __connman_service_save(struct connman_service *service)
service_save(service);
}
+void __connman_service_force_save(struct connman_service *service)
+{
+ if (!service)
+ return;
+
+ service->new_service = false;
+ service_save(service);
+}
+
static enum connman_service_state combine_state(
enum connman_service_state state_a,
enum connman_service_state state_b)
@@ -2577,6 +2586,18 @@ static void append_struct(gpointer value, gpointer user_data)
append_struct_service(iter, append_dict_properties, service);
}
+void __connman_service_append_struct(struct connman_service *service,
+ DBusMessageIter *iter)
+{
+ if (!service)
+ return;
+
+ if (!iter)
+ return;
+
+ append_struct(service, iter);
+}
+
void __connman_service_list_struct(DBusMessageIter *iter)
{
g_list_foreach(service_list, append_struct, iter);
--
2.17.1
2 years, 4 months
[PATCHv3 3/6] wps: add new WPS API implementation
by Natsuki.Itaya@sony.com
Add new WPS start API which does not specify any service.
Signed-off-by: n-itaya <Natsuki.Itaya(a)sony.com>
---
plugins/wifi.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/plugins/wifi.c b/plugins/wifi.c
index dc08c6af..0d096aa2 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -42,6 +42,7 @@
#include <glib.h>
#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman.h>
#include <connman/plugin.h>
#include <connman/inet.h>
#include <connman/device.h>
@@ -123,6 +124,12 @@ struct wifi_tethering_info {
GSupplicantSSID *ssid;
};
+struct wifi_wps_offered_data {
+ struct connman_service *service;
+ char *expect_ident;
+ char *passphrase;
+};
+
struct wifi_data {
char *identifier;
struct connman_device *device;
@@ -156,11 +163,19 @@ struct wifi_data {
unsigned int p2p_connection_timeout;
struct connman_peer *pending_peer;
GSList *peers;
+ bool p2p_connected;
bool p2p_connecting;
bool p2p_device;
int servicing;
int disconnect_code;
int assoc_code;
+
+ bool wps_running;
+ bool wps_success;
+ unsigned int wps_timeout;
+ GSList *wps_offered_list;
+ bool wps_after_scan;
+ GSupplicantWPSParams wps_params;
};
static GList *iface_list = NULL;
@@ -174,6 +189,26 @@ static int tech_set_tethering(struct connman_technology *technology,
const char *identifier, const char *passphrase,
const char *bridge, bool enabled);
+/* WPS Functions */
+#define WPS_TIMEOUT_INTERVAL_MSECS (125 * 1000)
+
+static void wps_event_success(GSupplicantInterface *interface);
+static void wps_event_fail(GSupplicantInterface *interface, int error);
+static struct wifi_wps_offered_data *wps_alloc_offered_data(
+ struct wifi_data *wifi, const char *group,
+ const char *passphrase);
+static void wps_free_offered_data(struct wifi_wps_offered_data *wps_data);
+static unsigned int wps_get_accepted_count(struct wifi_data *wifi);
+static unsigned int wps_get_offered_count(struct wifi_data *wifi);
+static bool wps_try_update_services(struct wifi_data *wifi);
+static void wps_finish(struct wifi_data *wifi, int error);
+static void wps_cleanup(struct wifi_data *wifi);
+static void wps_scan_callback(int result, GSupplicantInterface *interface,
+ void *user_data);
+static gboolean wps_timeout(gpointer data);
+static void wps_retry_callback(int result, GSupplicantInterface *interface,
+ void *user_data);
+
static int p2p_tech_probe(struct connman_technology *technology)
{
p2p_technology = technology;
@@ -417,6 +452,29 @@ static int peer_disconnect(struct connman_peer *peer)
return ret;
}
+static int peer_disconnect_all(struct wifi_data *wifi)
+{
+ GSList *list;
+ int result = 0, err = -EALREADY;
+
+ DBG("");
+
+ for (list = wifi->peers; list; list = list->next) {
+ struct connman_peer *peer = list->data;
+ GSupplicantPeer *gs_peer =
+ g_supplicant_interface_peer_lookup
+ (wifi->interface, connman_peer_get_identifier(peer));
+
+ if (g_supplicant_peer_is_in_a_group(gs_peer)) {
+ err = peer_disconnect(peer);
+ if (err != -EINPROGRESS)
+ result = err;
+ }
+ }
+
+ return result;
+}
+
struct peer_service_registration {
peer_service_registration_cb_t callback;
void *user_data;
@@ -1583,6 +1641,7 @@ static int wifi_disable(struct connman_device *device)
return -ENODEV;
wifi->connected = false;
+ wifi->p2p_connected = false;
wifi->disconnecting = false;
if (wifi->pending_network)
@@ -2199,6 +2258,9 @@ static int network_connect(struct connman_network *network)
if (!wifi)
return -ENODEV;
+ if (wifi->wps_running)
+ return -EBUSY;
+
ssid = g_try_malloc0(sizeof(GSupplicantSSID));
if (!ssid)
return -ENOMEM;
@@ -2375,6 +2437,8 @@ static bool handle_wps_completion(GSupplicantInterface *interface,
{
bool wps;
+ DBG("");
+
wps = connman_network_get_bool(network, "WiFi.UseWPS");
if (wps) {
const unsigned char *ssid, *wps_ssid;
@@ -2486,6 +2550,36 @@ static void interface_state(GSupplicantInterface *interface)
finalize_interface_creation(wifi);
}
+ if (wifi->wps_running) {
+ DBG("WPS running");
+ switch (state) {
+ case G_SUPPLICANT_STATE_SCANNING:
+ if (!wifi->wps_success)
+ connman_technology_wps_state_change_notify
+ (wifi_technology, "scan");
+ return;
+ case G_SUPPLICANT_STATE_ASSOCIATED:
+ connman_technology_wps_state_change_notify
+ (wifi_technology, "processing");
+ return;
+ case G_SUPPLICANT_STATE_DISCONNECTED:
+ if (wifi->wps_success) {
+ if (wps_try_update_services(wifi)) {
+ wps_finish(wifi, 0);
+ } else {
+ wifi->wps_after_scan = true;
+ DBG("Need scan");
+ reset_autoscan(wifi->device);
+ throw_wifi_scan(device,
+ wps_scan_callback);
+ }
+ }
+ return;
+ default:
+ return;
+ }
+ }
+
network = wifi->network;
if (!network)
return;
--
2.17.1
2 years, 4 months
[PATCHv3 1/6] wps: add new WPS API
by Natsuki.Itaya@sony.com
Here is the summery of the patch:
* connman should conduct WPS protocol without specifying SSID/band.
* connman should save a received credential into applicable wifi
service after completing WPS protocol.
* Then connman should notify WPS success with credential saved
service list.
* After that, user selects and calls connect from service list.
* User also can retry the connection without retrying WPS even if
the connection to AP gets unstable.
Previous connman wps API conducts WPS procedure with specific wifi
service (SSID), which causes following issues in those cases:
* Multi-band Operation:
- Many APs in the market operate WPS protocol over multi-band and
the SSID is different between band A and band B.
- However, current connman WPS implementation cannot specify
the operation band.
- Therefore, wpa_supplicant might proceed with conducting WPS
procedure and connecting to SSID (AP) which is different from
connman-specified SSID (service).
- In such case, connman disconnects WPS connection and judges as
a failure.
* Multi credential delivery:
- There might be a case the AP distributes multiple credentials.
- In current implementation, the wpa_supplicant might select and
connect with the SSID which is different from specified service, too.
- connman disconnects this WPS connection and judges as a failure
* Unconfigured AP:
- The SSID and security setting would be updated after the WPS procedure.
- wpa_supplicant can connect with correct AP, but the SSID and setting
are different from specified service then connman disconnects with AP.
So, user would see such problems and since those scenarios are tested
during WPS certification testing, current connman cannot pass
the WPS certification.
Moreover, connman discards WPS credential when connman fails
the association with AP even after WPS protocol has successfully completed.
In this case, the user need retry WPS protocol, so I think WPS protocol
and connection should be separated.
Signed-off-by: n-itaya <Natsuki.Itaya(a)sony.com>
---
doc/agent-api.txt | 6 ++++++
doc/technology-api.txt | 43 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/doc/agent-api.txt b/doc/agent-api.txt
index e3c1dcde..f52ed4bd 100644
--- a/doc/agent-api.txt
+++ b/doc/agent-api.txt
@@ -141,6 +141,12 @@ Fields string Name
In case of a RequestPeerAuthorization, this field will
be set as mandatory.
+ To use this in order to get connected to a given
+ services is deprecated and should not be used. Methods
+ Technology.StartStaWps and Technology.StartApWps
+ are provided by ConnMan and user should use those two
+ instead.
+
string Username
Username for WISPr authentication. This field will be
diff --git a/doc/technology-api.txt b/doc/technology-api.txt
index f22e9b29..62d2c612 100644
--- a/doc/technology-api.txt
+++ b/doc/technology-api.txt
@@ -40,6 +40,49 @@ Methods dict GetProperties() [deprecated]
via the PeersChanged signal from the manager
interface.
+ void StartApWps(string authentication)
+
+ Start a WPS Session when the system is playing AP
+ role (Tethering) in order to allow potential Ex-STAs
+ to get connected by using WPS.
+
+ The argument indicates the WPS authentication method
+ which can be an empty string, if user wants to use
+ push-button method, or a pin code if user wants to
+ use the pin method.
+
+ This method is supported only by WiFi technology.
+
+ Possible Errors: [service].Error.InvalidArguments
+ [service].Error.PermissionDenied
+ [service].Error.NotSupported
+
+ void StartStaWps(string authentication)
+
+ Start a WPS Session in STA role in order to be able
+ to get connected with an Ex-AP with WPS capabilities.
+
+ The argument indicates the WPS authentication method
+ which can be an empty string, if user wants to use
+ push-button method, or a pin code if user wants to
+ use the pin method.
+
+ This method is supported only by WiFi technology.
+
+ Possible Errors: [service].Error.InvalidArguments
+ [service].Error.OperationAborted
+ [service].Error.OperationTimeout
+ [service].Error.NotConnected
+ [service].Error.NotSupported
+
+ void CancelWps()
+
+ Cancel ongoing WPS session.
+
+ This method is supported only by WiFi technology.
+
+ Possible Errors: [service].Error.NotSupported
+
Signals PropertyChanged(string name, variant value)
This signal indicates a changed value of the given
--
2.17.1
2 years, 4 months
[PATCH] p2p: when disabling p2p technology we should disconnect from peers
by Vasyl Vavrychuk
Having disabled but connected technology does not make sense.
---
src/connman.h | 1 +
src/peer.c | 12 ++++++++++++
src/technology.c | 1 +
3 files changed, 14 insertions(+)
diff --git a/src/connman.h b/src/connman.h
index 13553833..c4190fd0 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -826,6 +826,7 @@ void __connman_peer_cleanup(void);
void __connman_peer_list_struct(DBusMessageIter *array);
const char *__connman_peer_get_path(struct connman_peer *peer);
+void __connman_peer_disconnect_all(void);
int __connman_peer_service_init(void);
void __connman_peer_service_cleanup(void);
diff --git a/src/peer.c b/src/peer.c
index dbd9cd68..2102f119 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -1180,6 +1180,18 @@ const char *__connman_peer_get_path(struct connman_peer *peer)
return peer->path;
}
+static void disconnect_peer_hash_table(gpointer key,
+ gpointer value, gpointer user_data)
+{
+ struct connman_peer *peer = value;
+ peer_disconnect(peer);
+}
+
+void __connman_peer_disconnect_all(void)
+{
+ g_hash_table_foreach(peers_table, disconnect_peer_hash_table, NULL);
+}
+
int __connman_peer_init(void)
{
DBG("");
diff --git a/src/technology.c b/src/technology.c
index bd2e06a9..62ab6ab5 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -782,6 +782,7 @@ static int technology_disable(struct connman_technology *technology)
if (technology->type == CONNMAN_SERVICE_TYPE_P2P) {
technology->enable_persistent = false;
__connman_device_stop_scan(CONNMAN_SERVICE_TYPE_P2P);
+ __connman_peer_disconnect_all();
return technology_disabled(technology);
} else if (technology->type == CONNMAN_SERVICE_TYPE_WIFI) {
struct connman_technology *p2p;
--
2.19.1
2 years, 4 months
[PATCH 1/2] include: Add connman_technology_get_type() prototype
by Slava Monich
---
include/technology.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/technology.h b/include/technology.h
index 97db660..7508a9a 100644
--- a/include/technology.h
+++ b/include/technology.h
@@ -42,6 +42,8 @@ int connman_technology_set_regdom(const char *alpha2);
void connman_technology_regdom_notify(struct connman_technology *technology,
const char *alpha2);
+enum connman_service_type connman_technology_get_type
+ (struct connman_technology *technology);
bool connman_technology_get_wifi_tethering(const char **ssid,
const char **psk);
bool connman_technology_is_tethering_allowed(enum connman_service_type type);
--
1.9.1
2 years, 4 months