[PATCH] notifier: constify vtables
by Slava Monich
connman_notifier vtables are read-only structures. Declaring them const
at compile time allows the compiler to actually make them read-only at
runtime.
---
include/notifier.h | 4 ++--
plugins/iospm.c | 2 +-
plugins/nmcompat.c | 2 +-
plugins/pacrunner.c | 2 +-
plugins/vpn.c | 2 +-
src/dnsproxy.c | 4 ++--
src/ipv6pd.c | 2 +-
src/manager.c | 2 +-
src/nat.c | 2 +-
src/notifier.c | 22 +++++++++++-----------
src/provider.c | 2 +-
src/session.c | 2 +-
src/timeserver.c | 2 +-
tools/iptables-unit.c | 6 +++---
14 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/include/notifier.h b/include/notifier.h
index 50b5fb4..9c0909c 100644
--- a/include/notifier.h
+++ b/include/notifier.h
@@ -57,8 +57,8 @@ struct connman_notifier {
void (*idle_state) (bool idle);
};
-int connman_notifier_register(struct connman_notifier *notifier);
-void connman_notifier_unregister(struct connman_notifier *notifier);
+int connman_notifier_register(const struct connman_notifier *notifier);
+void connman_notifier_unregister(const struct connman_notifier *notifier);
#ifdef __cplusplus
}
diff --git a/plugins/iospm.c b/plugins/iospm.c
index fcb4cea..cded9e0 100644
--- a/plugins/iospm.c
+++ b/plugins/iospm.c
@@ -86,7 +86,7 @@ static void iospm_offline_mode(bool enabled)
send_indication(IOSPM_FLIGHT_MODE, enabled);
}
-static struct connman_notifier iospm_notifier = {
+static const struct connman_notifier iospm_notifier = {
.name = "iospm",
.priority = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
.service_enabled= iospm_service_enabled,
diff --git a/plugins/nmcompat.c b/plugins/nmcompat.c
index 883ce9b..274baab 100644
--- a/plugins/nmcompat.c
+++ b/plugins/nmcompat.c
@@ -173,7 +173,7 @@ static void offline_mode(bool enabled)
current_service = NULL;
}
-static struct connman_notifier notifier = {
+static const struct connman_notifier notifier = {
.name = "nmcompat",
.priority = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
.default_changed = default_changed,
diff --git a/plugins/pacrunner.c b/plugins/pacrunner.c
index d2464a5..9c652f3 100644
--- a/plugins/pacrunner.c
+++ b/plugins/pacrunner.c
@@ -277,7 +277,7 @@ static void proxy_changed(struct connman_service *service)
create_proxy_configuration();
}
-static struct connman_notifier pacrunner_notifier = {
+static const struct connman_notifier pacrunner_notifier = {
.name = "pacrunner",
.default_changed = default_service_changed,
.proxy_changed = proxy_changed,
diff --git a/plugins/vpn.c b/plugins/vpn.c
index 22d69a3..11bab15 100644
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -1947,7 +1947,7 @@ static void vpn_service_state_changed(struct connman_service *service,
vpn_disconnect_check();
}
-static struct connman_notifier vpn_notifier = {
+static const struct connman_notifier vpn_notifier = {
.name = "vpn",
.priority = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
.default_changed = vpn_service_list_changed,
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 951f2cb..2dc7340 100644
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -2912,13 +2912,13 @@ static void dnsproxy_default_changed(struct connman_service *service)
cache_refresh();
}
-static struct connman_notifier dnsproxy_notifier = {
+static const struct connman_notifier dnsproxy_notifier = {
.name = "dnsproxy",
.default_changed = dnsproxy_default_changed,
.offline_mode = dnsproxy_offline_mode,
};
-static unsigned char opt_edns0_type[2] = { 0x00, 0x29 };
+static const unsigned char opt_edns0_type[2] = { 0x00, 0x29 };
static int parse_request(unsigned char *buf, size_t len,
char *name, unsigned int size)
diff --git a/src/ipv6pd.c b/src/ipv6pd.c
index a70de3f..8cd2a33 100644
--- a/src/ipv6pd.c
+++ b/src/ipv6pd.c
@@ -295,7 +295,7 @@ static void update_ipconfig(struct connman_service *service,
}
}
-static struct connman_notifier pd_notifier = {
+static const struct connman_notifier pd_notifier = {
.name = "IPv6 prefix delegation",
.default_changed = update_default_interface,
.ipconfig_changed = update_ipconfig,
diff --git a/src/manager.c b/src/manager.c
index d15ce20..dc2e062 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -169,7 +169,7 @@ static void idle_state(bool idle)
return;
}
-static struct connman_notifier technology_notifier = {
+static const struct connman_notifier technology_notifier = {
.name = "manager",
.priority = CONNMAN_NOTIFIER_PRIORITY_HIGH,
.idle_state = idle_state,
diff --git a/src/nat.c b/src/nat.c
index 2aac60d..681acb2 100644
--- a/src/nat.c
+++ b/src/nat.c
@@ -203,7 +203,7 @@ static void cleanup_nat(gpointer data)
g_free(nat);
}
-static struct connman_notifier nat_notifier = {
+static const struct connman_notifier nat_notifier = {
.name = "nat",
.default_changed = update_default_interface,
};
diff --git a/src/notifier.c b/src/notifier.c
index 5ba5324..47eb72f 100644
--- a/src/notifier.c
+++ b/src/notifier.c
@@ -50,11 +50,11 @@ static gint compare_priority(gconstpointer a, gconstpointer b)
*
* Returns: %0 on success
*/
-int connman_notifier_register(struct connman_notifier *notifier)
+int connman_notifier_register(const struct connman_notifier *notifier)
{
DBG("notifier %p name %s", notifier, notifier->name);
- notifier_list = g_slist_insert_sorted(notifier_list, notifier,
+ notifier_list = g_slist_insert_sorted(notifier_list, (void*)notifier,
compare_priority);
return 0;
@@ -66,7 +66,7 @@ int connman_notifier_register(struct connman_notifier *notifier)
*
* Remove a previously registered notifier module
*/
-void connman_notifier_unregister(struct connman_notifier *notifier)
+void connman_notifier_unregister(const struct connman_notifier *notifier)
{
DBG("notifier %p name %s", notifier, notifier->name);
@@ -215,7 +215,7 @@ void __connman_notifier_default_changed(struct connman_service *service)
GSList *list;
for (list = notifier_list; list; list = list->next) {
- struct connman_notifier *notifier = list->data;
+ const struct connman_notifier *notifier = list->data;
if (notifier->default_changed)
notifier->default_changed(service);
@@ -228,7 +228,7 @@ void __connman_notifier_service_add(struct connman_service *service,
GSList *list;
for (list = notifier_list; list; list = list->next) {
- struct connman_notifier *notifier = list->data;
+ const struct connman_notifier *notifier = list->data;
if (notifier->service_add)
notifier->service_add(service, name);
@@ -251,7 +251,7 @@ void __connman_notifier_service_remove(struct connman_service *service)
}
for (list = notifier_list; list; list = list->next) {
- struct connman_notifier *notifier = list->data;
+ const struct connman_notifier *notifier = list->data;
if (notifier->service_remove)
notifier->service_remove(service);
@@ -263,7 +263,7 @@ void __connman_notifier_proxy_changed(struct connman_service *service)
GSList *list;
for (list = notifier_list; list; list = list->next) {
- struct connman_notifier *notifier = list->data;
+ const struct connman_notifier *notifier = list->data;
if (notifier->proxy_changed)
notifier->proxy_changed(service);
@@ -289,7 +289,7 @@ void __connman_notifier_offlinemode(bool enabled)
state_changed();
for (list = notifier_list; list; list = list->next) {
- struct connman_notifier *notifier = list->data;
+ const struct connman_notifier *notifier = list->data;
if (notifier->offline_mode)
notifier->offline_mode(enabled);
@@ -303,7 +303,7 @@ static void notify_idle_state(bool idle)
DBG("idle %d", idle);
for (list = notifier_list; list; list = list->next) {
- struct connman_notifier *notifier = list->data;
+ const struct connman_notifier *notifier = list->data;
if (notifier->idle_state)
notifier->idle_state(idle);
@@ -318,7 +318,7 @@ void __connman_notifier_service_state_changed(struct connman_service *service,
bool found;
for (list = notifier_list; list; list = list->next) {
- struct connman_notifier *notifier = list->data;
+ const struct connman_notifier *notifier = list->data;
if (notifier->service_state_changed)
notifier->service_state_changed(service, state);
@@ -361,7 +361,7 @@ void __connman_notifier_ipconfig_changed(struct connman_service *service,
GSList *list;
for (list = notifier_list; list; list = list->next) {
- struct connman_notifier *notifier = list->data;
+ const struct connman_notifier *notifier = list->data;
if (notifier->ipconfig_changed)
notifier->ipconfig_changed(service, ipconfig);
diff --git a/src/provider.c b/src/provider.c
index 5f57ba9..9d9741e 100644
--- a/src/provider.c
+++ b/src/provider.c
@@ -747,7 +747,7 @@ static void provider_service_changed(struct connman_service *service,
connman_provider_disconnect(provider);
}
-static struct connman_notifier provider_notifier = {
+static const struct connman_notifier provider_notifier = {
.name = "provider",
.offline_mode = provider_offline_mode,
.service_state_changed = provider_service_changed,
diff --git a/src/session.c b/src/session.c
index 3ef7bf5..2a1dd9a 100644
--- a/src/session.c
+++ b/src/session.c
@@ -2001,7 +2001,7 @@ static void ipconfig_changed(struct connman_service *service,
}
}
-static struct connman_notifier session_notifier = {
+static const struct connman_notifier session_notifier = {
.name = "session",
.service_state_changed = service_state_changed,
.ipconfig_changed = ipconfig_changed,
diff --git a/src/timeserver.c b/src/timeserver.c
index 48f026c..657b782 100644
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -500,7 +500,7 @@ static void default_changed(struct connman_service *default_service)
timeserver_stop();
}
-static struct connman_notifier timeserver_notifier = {
+static const struct connman_notifier timeserver_notifier = {
.name = "timeserver",
.default_changed = default_changed,
};
diff --git a/tools/iptables-unit.c b/tools/iptables-unit.c
index 426631a..0ab4249 100644
--- a/tools/iptables-unit.c
+++ b/tools/iptables-unit.c
@@ -318,7 +318,7 @@ static void test_iptables_target0(void)
assert_rule_not_exists("filter", "-A INPUT -m mark --mark 0x2");
}
-struct connman_notifier *nat_notifier;
+const struct connman_notifier *nat_notifier;
struct connman_service {
char *dummy;
@@ -329,14 +329,14 @@ char *connman_service_get_interface(struct connman_service *service)
return "eth0";
}
-int connman_notifier_register(struct connman_notifier *notifier)
+int connman_notifier_register(const struct connman_notifier *notifier)
{
nat_notifier = notifier;
return 0;
}
-void connman_notifier_unregister(struct connman_notifier *notifier)
+void connman_notifier_unregister(const struct connman_notifier *notifier)
{
nat_notifier = NULL;
}
--
1.9.1
2 years, 5 months
Does not create resolv.conf parent directories
by Nuno Gonçalves
Hi,
Connman does not create the parent directories before attempting to
create resolv.conf.
As a result on boot, if /var/run/connman does not exist, this error
message is printed:
Cannot create /var/run/connman/resolv.conf falling back to /etc/resolv.conf
I believe creating this directories, in temporary partitions, should
be a responsibility of connman.
Would like some confirmation because I submit a patch.
Thanks,
Nuno
2 years, 5 months
[PATCH] service: signal when services are moved
by Benoît Monin
When calling MoveBefore or MoveAfter on a service, no signal is emitted
by connman. This makes it impossible for a dbus client to maintain an
ordered list of services in sync with connman.
This patch schedules the emission of the signal ServicesChanged from the
function move_service, so the new list will get published over dbus.
---
src/service.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/service.c b/src/service.c
index eea82354..7dc32278 100644
--- a/src/service.c
+++ b/src/service.c
@@ -143,6 +143,7 @@ static struct connman_ipconfig *create_ip4config(struct connman_service *service
static struct connman_ipconfig *create_ip6config(struct connman_service *service,
int index);
static void dns_changed(struct connman_service *service);
+static void service_schedule_changed(void);
struct find_data {
const char *path;
@@ -4598,6 +4599,8 @@ static DBusMessage *move_service(DBusConnection *conn,
__connman_connection_update_gateway();
+ service_schedule_changed();
+
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
2 years, 5 months
Configuration for offline Ethernet connections
by Joe Rutledge
Hi All,
I'd like to know (and possibly set) the configuration for an Ethernet
connection when the connection is either down or physically not
connected. Is this possible to do via the DBUS API, or must I grind the
config file (in which case is there anything that can help me do that,
such that I don't get left behind when the format changes)?
Thanks,
Joe
2 years, 5 months
[PATCH 4/4] wps: add new WPS API for technology
by Natsuki.Itaya@sony.com
This implementation is follow the the original patch.
https://lists.01.org/pipermail/connman/2018-January/022367.html
Signed-off-by: n-itaya <Natsuki.Itaya(a)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
2 years, 6 months
[PATCHv3 5/6] wps: add new interface to communicate wpa_supplicant.
by Natsuki.Itaya@sony.com
Add new WPS start/cancel interface.
Add wpa_supplicant wps event callback for WPS state tracing.
Add wps credential callback to hand over into wifi plugin.
Signed-off-by: n-itaya <Natsuki.Itaya(a)sony.com>
---
gsupplicant/gsupplicant.h | 35 +++
gsupplicant/supplicant.c | 484 ++++++++++++++++++++++++++++++--------
2 files changed, 424 insertions(+), 95 deletions(-)
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index db61595b..e525d1c3 100644
--- a/gsupplicant/gsupplicant.h
+++ b/gsupplicant/gsupplicant.h
@@ -84,6 +84,18 @@ extern "C" {
#define G_SUPPLICANT_GROUP_ROLE_CLIENT (1 << 0)
#define G_SUPPLICANT_GROUP_ROLE_GO (1 << 1)
+#define G_SUPPLICANT_WPS_AUTH_OPEN (1 << 0)
+#define G_SUPPLICANT_WPS_AUTH_WPA_PSK (1 << 1)
+#define G_SUPPLICANT_WPS_AUTH_SHARED (1 << 2) /* Depricated */
+#define G_SUPPLICANT_WPS_AUTH_WPA_EAP (1 << 3)
+#define G_SUPPLICANT_WPS_AUTH_WPA2_EAP (1 << 4)
+#define G_SUPPLICANT_WPS_AUTH_WPA2_PSK (1 << 5)
+
+#define G_SUPPLICANT_WPS_ENCR_NONE (1 << 0)
+#define G_SUPPLICANT_WPS_ENCR_WEP (1 << 1)
+#define G_SUPPLICANT_WPS_ENCR_TKIP (1 << 2)
+#define G_SUPPLICANT_WPS_ENCR_AES (1 << 3)
+
typedef enum {
G_SUPPLICANT_MODE_UNKNOWN,
G_SUPPLICANT_MODE_INFRA,
@@ -159,6 +171,13 @@ struct _GSupplicantSSID {
typedef struct _GSupplicantSSID GSupplicantSSID;
+struct _GSupplicantWPSParams {
+ GSupplicantMode mode;
+ const char *pin;
+};
+
+typedef struct _GSupplicantWPSParams GSupplicantWPSParams;
+
struct scan_ssid {
unsigned char ssid[32];
uint8_t ssid_len;
@@ -259,6 +278,15 @@ int g_supplicant_set_widi_ies(GSupplicantP2PServiceParams *p2p_service_params,
GSupplicantInterfaceCallback callback,
void *user_data);
+int g_supplicant_interface_wps_cancel(GSupplicantInterface *interface,
+ GSupplicantInterfaceCallback callback,
+ void *user_data);
+
+int g_supplicant_interface_wps_start(GSupplicantInterface *interface,
+ GSupplicantWPSParams *wps,
+ GSupplicantInterfaceCallback callback,
+ void *user_data);
+
int g_supplicant_interface_connect(GSupplicantInterface *interface,
GSupplicantSSID *ssid,
GSupplicantInterfaceCallback callback,
@@ -292,6 +320,7 @@ int g_supplicant_interface_set_country(GSupplicantInterface *interface,
GSupplicantCountryCallback callback,
const char *alpha2,
void *user_data);
+bool g_supplicant_interface_support_wps(GSupplicantInterface *interface);
bool g_supplicant_interface_has_p2p(GSupplicantInterface *interface);
int g_supplicant_interface_set_p2p_device_config(GSupplicantInterface *interface,
const char *device_name,
@@ -299,6 +328,8 @@ int g_supplicant_interface_set_p2p_device_config(GSupplicantInterface *interface
GSupplicantPeer *g_supplicant_interface_peer_lookup(GSupplicantInterface *interface,
const char *identifier);
bool g_supplicant_interface_is_p2p_finding(GSupplicantInterface *interface);
+void g_supplicant_interface_flushBSS(GSupplicantInterface *interface,
+ unsigned int age);
/* Network and Peer API */
struct _GSupplicantNetwork;
@@ -352,6 +383,8 @@ struct _GSupplicantCallbacks {
void (*network_changed) (GSupplicantNetwork *network,
const char *property);
void (*network_associated) (GSupplicantNetwork *network);
+ void (*wps_event)(GSupplicantInterface *interface,
+ GSupplicantWpsState event, int error);
void (*peer_found) (GSupplicantPeer *peer);
void (*peer_lost) (GSupplicantPeer *peer);
void (*peer_changed) (GSupplicantPeer *peer,
@@ -362,6 +395,8 @@ struct _GSupplicantCallbacks {
int reasoncode);
void (*assoc_status_code)(GSupplicantInterface *interface,
int reasoncode);
+ void (*wps_credential)(GSupplicantInterface *interface,
+ const char *group);
};
typedef struct _GSupplicantCallbacks GSupplicantCallbacks;
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index 5246c80b..afeb1038 100644
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -138,6 +138,24 @@ static struct strvalmap mode_capa_map[] = {
{ }
};
+static struct strvalmap wps_auth_map[] = {
+ { "open", G_SUPPLICANT_WPS_AUTH_OPEN },
+ { "shared", G_SUPPLICANT_WPS_AUTH_SHARED },
+ { "wpa-psk", G_SUPPLICANT_WPS_AUTH_WPA_PSK },
+ { "wpa-eap", G_SUPPLICANT_WPS_AUTH_WPA_EAP },
+ { "wpa2-eap", G_SUPPLICANT_WPS_AUTH_WPA2_EAP },
+ { "wpa2-psk", G_SUPPLICANT_WPS_AUTH_WPA2_PSK },
+ { }
+};
+
+static struct strvalmap wps_encr_map[] = {
+ { "none", G_SUPPLICANT_WPS_ENCR_NONE },
+ { "wep", G_SUPPLICANT_WPS_ENCR_WEP },
+ { "tkip", G_SUPPLICANT_WPS_ENCR_TKIP },
+ { "aes", G_SUPPLICANT_WPS_ENCR_AES },
+ { }
+};
+
static GHashTable *interface_table;
static GHashTable *bss_mapping;
static GHashTable *peer_mapping;
@@ -146,9 +164,14 @@ static GHashTable *pending_peer_connection;
static GHashTable *config_file_table;
struct _GSupplicantWpsCredentials {
+ unsigned char bssid[6];
unsigned char ssid[32];
unsigned int ssid_len;
+
char *key;
+
+ unsigned int authtype;
+ unsigned int encrtype;
};
struct added_network_information {
@@ -181,6 +204,7 @@ struct _GSupplicantInterface {
char *ifname;
char *driver;
char *bridge;
+ bool wps_support;
struct _GSupplicantWpsCredentials wps_cred;
GSupplicantWpsState wps_state;
GHashTable *network_table;
@@ -287,6 +311,7 @@ struct interface_connect_data {
union {
GSupplicantSSID *ssid;
GSupplicantPeerParams *peer;
+ GSupplicantWPSParams *wps;
};
};
@@ -298,6 +323,12 @@ struct interface_scan_data {
void *user_data;
};
+struct wps_event_args {
+ int msg; /* enum wps_msg_type */
+ int config_error; /* enum wps_config_error */
+ int error_indication; /* enum wps_error_indication */
+};
+
static int network_remove(struct interface_data *data);
static inline void debug(const char *format, ...)
@@ -614,6 +645,19 @@ static void callback_network_associated(GSupplicantNetwork *network)
callbacks_pointer->network_associated(network);
}
+static void callback_wps_event(GSupplicantInterface *interface,
+ GSupplicantWpsState state, int error)
+{
+ SUPPLICANT_DBG("");
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->wps_event)
+ return;
+
+ callbacks_pointer->wps_event(interface, state, error);
+}
+
static void callback_peer_found(GSupplicantPeer *peer)
{
if (!callbacks_pointer)
@@ -688,6 +732,18 @@ static void callback_assoc_status_code(GSupplicantInterface *interface,
}
+static void callback_wps_credential(GSupplicantInterface *interface,
+ const char *group)
+{
+ if (!callbacks_pointer)
+ return;
+
+ if (!callbacks_pointer->assoc_status_code)
+ return;
+
+ callbacks_pointer->wps_credential(interface, group);
+}
+
static void remove_group(gpointer data)
{
GSupplicantGroup *group = data;
@@ -2209,6 +2265,15 @@ static void interface_bss_removed(DBusMessageIter *iter, void *user_data)
g_hash_table_remove(interface->network_table, network->group);
}
+static void wps_process_credentials(DBusMessageIter *iter, void *user_data)
+{
+ dbus_bool_t credentials = FALSE;
+
+ SUPPLICANT_DBG("");
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials);
+}
+
static void set_config_methods(DBusMessageIter *iter, void *user_data)
{
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, user_data);
@@ -2285,6 +2350,16 @@ static void interface_property(const char *key, DBusMessageIter *iter,
interface);
if (interface->mode_capa & G_SUPPLICANT_CAPABILITY_MODE_P2P)
interface->p2p_support = true;
+
+ if (interface->keymgmt_capa & G_SUPPLICANT_KEYMGMT_WPS) {
+ interface->wps_support = true;
+
+ supplicant_dbus_property_set(interface->path,
+ SUPPLICANT_INTERFACE ".Interface.WPS",
+ "ProcessCredentials",
+ DBUS_TYPE_BOOLEAN_AS_STRING,
+ wps_process_credentials, NULL, NULL, NULL);
+ }
} else if (g_strcmp0(key, "State") == 0) {
const char *str = NULL;
@@ -2846,6 +2921,42 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
callback_network_changed(network, "Signal");
}
+static void wps_credentials_encrtype(DBusMessageIter *iter, void *user_data)
+{
+ unsigned int *encrtype = user_data;
+ const char *str = NULL;
+ int i;
+
+ dbus_message_iter_get_basic(iter, &str);
+ if (!str)
+ return;
+
+ for (i = 0; wps_encr_map[i].str; i++) {
+ if (strcmp(str, wps_encr_map[i].str) == 0) {
+ *encrtype |= wps_encr_map[i].val;
+ break;
+ }
+ }
+}
+
+static void wps_credentials_authtype(DBusMessageIter *iter, void *user_data)
+{
+ unsigned int *authtype = user_data;
+ const char *str = NULL;
+ int i;
+
+ dbus_message_iter_get_basic(iter, &str);
+ if (!str)
+ return;
+
+ for (i = 0; wps_auth_map[i].str; i++) {
+ if (strcmp(str, wps_auth_map[i].str) == 0) {
+ *authtype |= wps_auth_map[i].val;
+ break;
+ }
+ }
+}
+
static void wps_credentials(const char *key, DBusMessageIter *iter,
void *user_data)
{
@@ -2890,12 +3001,34 @@ static void wps_credentials(const char *key, DBusMessageIter *iter,
memset(interface->wps_cred.ssid, 0, 32);
interface->wps_cred.ssid_len = 0;
}
+ SUPPLICANT_DBG("WPS SSID present : %s",
+ interface->wps_cred.ssid);
+ } else if (g_strcmp0(key, "AuthType") == 0) {
+ DBusMessageIter array;
+
+ dbus_message_iter_recurse(iter, &array);
+ supplicant_dbus_array_foreach(iter,
+ wps_credentials_authtype,
+ &interface->wps_cred.authtype);
+ SUPPLICANT_DBG("WPS AuthType=0x%04x",
+ interface->wps_cred.authtype);
+ } else if (g_strcmp0(key, "EncrType") == 0) {
+ DBusMessageIter array;
+
+ dbus_message_iter_recurse(iter, &array);
+ supplicant_dbus_array_foreach(iter,
+ wps_credentials_encrtype,
+ &interface->wps_cred.encrtype);
+ SUPPLICANT_DBG("WPS EncrType=0x%04x",
+ interface->wps_cred.encrtype);
}
}
static void signal_wps_credentials(const char *path, DBusMessageIter *iter)
{
GSupplicantInterface *interface;
+ struct g_supplicant_bss bss;
+ char *group;
SUPPLICANT_DBG("");
@@ -2904,23 +3037,59 @@ static void signal_wps_credentials(const char *path, DBusMessageIter *iter)
return;
supplicant_dbus_property_foreach(iter, wps_credentials, interface);
+
+ memset(&bss, 0, sizeof(struct g_supplicant_bss));
+ memcpy(bss.ssid, interface->wps_cred.ssid,
+ interface->wps_cred.ssid_len);
+ bss.ssid_len = interface->wps_cred.ssid_len;
+ bss.mode = G_SUPPLICANT_MODE_INFRA;
+ bss.security = G_SUPPLICANT_SECURITY_UNKNOWN;
+ if (interface->wps_cred.encrtype &
+ (G_SUPPLICANT_WPS_ENCR_AES | G_SUPPLICANT_WPS_ENCR_TKIP)) {
+ bss.security = G_SUPPLICANT_SECURITY_PSK;
+ } else if (interface->wps_cred.encrtype & G_SUPPLICANT_WPS_ENCR_WEP) {
+ bss.security = G_SUPPLICANT_SECURITY_WEP;
+ } else if (interface->wps_cred.encrtype & G_SUPPLICANT_WPS_ENCR_NONE) {
+ bss.security = G_SUPPLICANT_SECURITY_NONE;
+ }
+
+ group = create_group(&bss);
+ callback_wps_credential(interface, group);
+ g_free(group);
}
static void wps_event_args(const char *key, DBusMessageIter *iter,
void *user_data)
{
- GSupplicantInterface *interface = user_data;
+ struct wps_event_args *args = user_data;
- if (!key || !interface)
+ if (!key)
return;
SUPPLICANT_DBG("Arg Key %s", key);
+
+ if (g_strcmp0(key, "config_error") == 0) {
+ dbus_message_iter_get_basic(iter, &args->config_error);
+ SUPPLICANT_DBG("Configuration Error %d", args->config_error);
+ } else if (g_strcmp0(key, "msg") == 0) {
+ dbus_message_iter_get_basic(iter, &args->msg);
+ SUPPLICANT_DBG("Msg %d", args->msg);
+ } else if (g_strcmp0(key, "error_indication") == 0) {
+ dbus_message_iter_get_basic(iter, &args->error_indication);
+ SUPPLICANT_DBG("Error Indication %d", args->error_indication);
+ }
}
static void signal_wps_event(const char *path, DBusMessageIter *iter)
{
GSupplicantInterface *interface;
const char *name = NULL;
+ struct wps_event_args args;
+ int error;
+
+ static const int WPS_CFG_MSG_TIMEOUT = 16;
+ static const int WPS_CFG_DEV_PASSWORD_AUTH_FAILURE = 18;
+ static const int WPS_EI_SECURITY_WEP_PROHIBITED = 2;
SUPPLICANT_DBG("");
@@ -2932,19 +3101,43 @@ static void signal_wps_event(const char *path, DBusMessageIter *iter)
SUPPLICANT_DBG("Name: %s", name);
- if (g_strcmp0(name, "success") == 0)
- interface->wps_state = G_SUPPLICANT_WPS_STATE_SUCCESS;
- else if (g_strcmp0(name, "fail") == 0)
- interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
- else
- interface->wps_state = G_SUPPLICANT_WPS_STATE_UNKNOWN;
-
- if (!dbus_message_iter_has_next(iter))
+ if (dbus_message_iter_has_next(iter)) {
+ dbus_message_iter_next(iter);
+ memset(&args, 0, sizeof(args));
+ supplicant_dbus_property_foreach(iter, wps_event_args, &args);
+ } else {
return;
+ }
- dbus_message_iter_next(iter);
+ if (g_strcmp0(name, "success") == 0) {
+ interface->wps_state = G_SUPPLICANT_WPS_STATE_SUCCESS;
+ error = 0;
+ } else if (g_strcmp0(name, "fail") == 0) {
+ interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
+ SUPPLICANT_DBG("WPS: Failed. msg = %d config_error = %d"
+ " error_indication %d",
+ args.msg, args.config_error,
+ args.error_indication);
+
+ if (args.config_error == WPS_CFG_MSG_TIMEOUT)
+ error = -ETIMEDOUT;
+ else if (args.config_error == WPS_CFG_DEV_PASSWORD_AUTH_FAILURE)
+ error = -EKEYREJECTED;
+ else if (args.error_indication ==
+ WPS_EI_SECURITY_WEP_PROHIBITED)
+ error = -EACCES;
+ else
+ error = -ECONNREFUSED;
+ } else if (g_strcmp0(name, "pbc-overlap") == 0) {
+ interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
+ error = -EAGAIN;
+ } else {
+ // M2D Events are not forwarded
+ interface->wps_state = G_SUPPLICANT_WPS_STATE_FAIL;
+ error = -ECONNREFUSED;
+ }
- supplicant_dbus_property_foreach(iter, wps_event_args, interface);
+ callback_wps_event(interface, interface->wps_state, error);
}
static void create_peer_identifier(GSupplicantPeer *peer)
@@ -3661,6 +3854,14 @@ int g_supplicant_interface_set_country(GSupplicantInterface *interface,
return ret;
}
+bool g_supplicant_interface_support_wps(GSupplicantInterface *interface)
+{
+ if (!interface)
+ return false;
+
+ return interface->wps_support;
+}
+
bool g_supplicant_interface_has_p2p(GSupplicantInterface *interface)
{
if (!interface)
@@ -4887,6 +5088,61 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
supplicant_dbus_dict_close(iter, &dict);
}
+static void interface_wps_cancel_result(const char *error,
+ DBusMessageIter *iter, void *user_data)
+{
+ int err;
+ struct interface_connect_data *data = user_data;
+
+ SUPPLICANT_DBG("");
+
+ err = 0;
+ if (error) {
+ SUPPLICANT_DBG("WPS-Error: %s", error);
+
+ if (g_strcmp0(SUPPLICANT_INTERFACE ".InvalidArgs", error) == 0)
+ err = -EINVAL;
+ }
+
+ if (!data) {
+ SUPPLICANT_DBG("data is NULL");
+ return;
+ }
+
+ if (data->callback)
+ data->callback(err, data->interface, data->user_data);
+
+ g_free(data->path);
+ dbus_free(data);
+}
+
+int g_supplicant_interface_wps_cancel(GSupplicantInterface *interface,
+ GSupplicantInterfaceCallback callback,
+ void *user_data)
+{
+ struct interface_connect_data *data;
+ int ret;
+
+ data = dbus_malloc0(sizeof(*data));
+ data->interface = interface;
+ data->path = g_strdup(interface->path);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ ret = supplicant_dbus_method_call(data->path,
+ SUPPLICANT_INTERFACE ".Interface.WPS", "Cancel",
+ NULL, interface_wps_cancel_result, data, NULL);
+
+ if (ret < 0) {
+ SUPPLICANT_DBG("WPS-Error: %d", ret);
+ g_free(data->path);
+ dbus_free(data);
+ return ret;
+ }
+
+ return -EINPROGRESS;
+}
+
static void interface_wps_start_result(const char *error,
DBusMessageIter *iter, void *user_data)
{
@@ -4905,29 +5161,33 @@ static void interface_wps_start_result(const char *error,
data->callback(err, data->interface, data->user_data);
g_free(data->path);
- g_free(data->ssid);
+ g_free(data->wps);
dbus_free(data);
}
static void interface_add_wps_params(DBusMessageIter *iter, void *user_data)
{
struct interface_connect_data *data = user_data;
- GSupplicantSSID *ssid = data->ssid;
- const char *role = "enrollee", *type;
+ GSupplicantWPSParams *wps = data->wps;
+ const char *role, *type;
DBusMessageIter dict;
SUPPLICANT_DBG("");
supplicant_dbus_dict_open(iter, &dict);
+ role = "enrollee";
+ if (wps->mode == G_SUPPLICANT_MODE_MASTER)
+ role = "registrar";
+
supplicant_dbus_dict_append_basic(&dict, "Role",
DBUS_TYPE_STRING, &role);
type = "pbc";
- if (ssid->pin_wps) {
+ if (wps->pin) {
type = "pin";
supplicant_dbus_dict_append_basic(&dict, "Pin",
- DBUS_TYPE_STRING, &ssid->pin_wps);
+ DBUS_TYPE_STRING, &wps->pin);
}
supplicant_dbus_dict_append_basic(&dict, "Type",
@@ -4936,36 +5196,43 @@ static void interface_add_wps_params(DBusMessageIter *iter, void *user_data)
supplicant_dbus_dict_close(iter, &dict);
}
-static void wps_start(const char *error, DBusMessageIter *iter, void *user_data)
+int g_supplicant_interface_wps_start(GSupplicantInterface *interface,
+ GSupplicantWPSParams *wps,
+ GSupplicantInterfaceCallback callback,
+ void *user_data)
{
- struct interface_connect_data *data = user_data;
+ struct interface_connect_data *data;
+ int ret;
SUPPLICANT_DBG("");
- if (error) {
- SUPPLICANT_DBG("error: %s", error);
- g_free(data->path);
- g_free(data->ssid);
- dbus_free(data);
- return;
- }
+ data = dbus_malloc0(sizeof(*data));
+ data->interface = interface;
+ data->path = g_strdup(interface->path);
+ data->callback = callback;
+ data->wps = wps;
+ data->user_data = user_data;
- supplicant_dbus_method_call(data->interface->path,
+ g_free(interface->wps_cred.key);
+ memset(&interface->wps_cred, 0,
+ sizeof(struct _GSupplicantWpsCredentials));
+
+ ret = supplicant_dbus_method_call(data->interface->path,
SUPPLICANT_INTERFACE ".Interface.WPS", "Start",
interface_add_wps_params,
interface_wps_start_result, data, NULL);
-}
-
-static void wps_process_credentials(DBusMessageIter *iter, void *user_data)
-{
- dbus_bool_t credentials = TRUE;
- SUPPLICANT_DBG("");
+ if (ret < 0) {
+ SUPPLICANT_DBG("Error: WPS Session could not be started");
+ g_free(wps);
+ g_free(data->path);
+ dbus_free(data);
+ return ret;
+ }
- dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &credentials);
+ return -EINPROGRESS;
}
-
int g_supplicant_interface_connect(GSupplicantInterface *interface,
GSupplicantSSID *ssid,
GSupplicantInterfaceCallback callback,
@@ -4973,6 +5240,7 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
{
struct interface_connect_data *data;
struct interface_data *intf_data;
+ GSupplicantWPSParams *wps;
int ret = 0;
SUPPLICANT_DBG("");
@@ -4985,6 +5253,21 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
/* TODO: Check if we're already connected and switch */
+ if (ssid->use_wps) {
+ wps = g_try_malloc0(sizeof(GSupplicantWPSParams));
+ if (!wps)
+ return -ENOMEM;
+
+ memset(wps, 0, sizeof(*wps));
+ wps->mode = G_SUPPLICANT_MODE_INFRA;
+ wps->pin = ssid->pin_wps;
+
+ g_free(ssid);
+ return g_supplicant_interface_wps_start(interface,
+ wps, callback,
+ user_data);
+ }
+
data = dbus_malloc0(sizeof(*data));
if (!data)
return -ENOMEM;
@@ -4995,72 +5278,62 @@ int g_supplicant_interface_connect(GSupplicantInterface *interface,
data->ssid = ssid;
data->user_data = user_data;
- if (ssid->use_wps) {
- g_free(interface->wps_cred.key);
- memset(&interface->wps_cred, 0,
- sizeof(struct _GSupplicantWpsCredentials));
+ /*
+ * By the time there is a request for connect and the network
+ * path is not NULL it means that connman has not removed the
+ * previous network pointer. This can happen in the case AP
+ * deauthenticated client and connman does not remove the
+ * previously connected network pointer. This causes supplicant
+ * to reallocate the memory for struct wpa_ssid again even if it
+ * is the same SSID. This causes memory usage of wpa_supplicnat
+ * to go high. The idea here is that if the previously connected
+ * network is not removed at the time of next connection attempt
+ * check if the network path is not NULL. In case it is non-NULL
+ * first remove the network and then once removal is successful, add
+ * the network.
+ */
- ret = supplicant_dbus_property_set(interface->path,
- SUPPLICANT_INTERFACE ".Interface.WPS",
- "ProcessCredentials", DBUS_TYPE_BOOLEAN_AS_STRING,
- wps_process_credentials, wps_start, data, interface);
- } else {
- /* By the time there is a request for connect and the network
- * path is not NULL it means that connman has not removed the
- * previous network pointer. This can happen in the case AP
- * deauthenticated client and connman does not remove the
- * previously connected network pointer. This causes supplicant
- * to reallocate the memory for struct wpa_ssid again even if it
- * is the same SSID. This causes memory usage of wpa_supplicnat
- * to go high. The idea here is that if the previously connected
- * network is not removed at the time of next connection attempt
- * check if the network path is not NULL. In case it is non-NULL
- * first remove the network and then once removal is successful, add
- * the network.
+ if (interface->network_path != NULL) {
+ g_free(data->path);
+ dbus_free(data);
+
+ /*
+ * If this add network is for the same network for
+ * which wpa_supplicant already has a profile then do
+ * not need to add another profile. Only if the
+ * profile that needs to get added is different from
+ * what is there in wpa_s delete the current one. A
+ * network is identified by its SSID, security_type
+ * and passphrase (private passphrase in case security
+ * type is 802.11x).
*/
+ if (compare_network_parameters(interface, ssid))
+ return -EALREADY;
+
+ intf_data = dbus_malloc0(sizeof(*intf_data));
+ if (!intf_data)
+ return -ENOMEM;
+
+ intf_data->interface = interface;
+ intf_data->path = g_strdup(interface->path);
+ intf_data->callback = callback;
+ intf_data->ssid = ssid;
+ intf_data->user_data = user_data;
+ intf_data->network_remove_in_progress = TRUE;
+ network_remove(intf_data);
+ } else {
+ ret = supplicant_dbus_method_call(interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
+ interface_add_network_params,
+ interface_add_network_result, data,
+ interface);
- if (interface->network_path != NULL) {
+ if (ret < 0) {
g_free(data->path);
+ g_free(data->ssid);
dbus_free(data);
-
- /*
- * If this add network is for the same network for
- * which wpa_supplicant already has a profile then do
- * not need to add another profile. Only if the
- * profile that needs to get added is different from
- * what is there in wpa_s delete the current one. A
- * network is identified by its SSID, security_type
- * and passphrase (private passphrase in case security
- * type is 802.11x).
- */
- if (compare_network_parameters(interface, ssid)) {
- return -EALREADY;
- }
-
- intf_data = dbus_malloc0(sizeof(*intf_data));
- if (!intf_data)
- return -ENOMEM;
-
- intf_data->interface = interface;
- intf_data->path = g_strdup(interface->path);
- intf_data->callback = callback;
- intf_data->ssid = ssid;
- intf_data->user_data = user_data;
- intf_data->network_remove_in_progress = TRUE;
- network_remove(intf_data);
- } else {
- ret = supplicant_dbus_method_call(interface->path,
- SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
- interface_add_network_params,
- interface_add_network_result, data,
- interface);
+ return ret;
}
- }
-
- if (ret < 0) {
- g_free(data->path);
- dbus_free(data);
- return ret;
}
return -EINPROGRESS;
@@ -5847,3 +6120,24 @@ void g_supplicant_unregister(const GSupplicantCallbacks *callbacks)
callbacks_pointer = NULL;
eap_methods = 0;
}
+
+static void interface_flushBSS_params(DBusMessageIter *iter, void *user_data)
+{
+ unsigned int *age = user_data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, age);
+}
+
+void g_supplicant_interface_flushBSS(GSupplicantInterface *interface,
+ unsigned int age)
+{
+ if (!interface)
+ return;
+
+ SUPPLICANT_DBG("");
+
+ supplicant_dbus_method_call(interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "FlushBSS",
+ interface_flushBSS_params, NULL,
+ &age, interface);
+}
--
2.17.1
2 years, 6 months
[PATCHv3 2/6] wps: add new WPS command for connmanctl
by Natsuki.Itaya@sony.com
Add new WPS start/cancel command.
Add WPS success/fail event handler.
Signed-off-by: n-itaya <Natsuki.Itaya(a)sony.com>
---
client/commands.c | 126 ++++++++++++++++++++++++++++++++++++++++++
client/dbus_helpers.c | 2 +-
2 files changed, 127 insertions(+), 1 deletion(-)
diff --git a/client/commands.c b/client/commands.c
index 05b93162..07404ca8 100644
--- a/client/commands.c
+++ b/client/commands.c
@@ -639,6 +639,86 @@ static int cmd_tether(char *args[], int num, struct connman_option *options)
return tether_set(args[1], set_tethering);
}
+static int wps_cb(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ bool sta = GPOINTER_TO_UINT(user_data);
+
+ if (error) {
+ fprintf(stderr, "WPS Error: %s\n", error);
+ return 1;
+ }
+
+ if (sta) {
+ fprintf(stdout, "WPS: Success\n");
+ services_list(iter, NULL, NULL);
+ } else
+ fprintf(stdout, "WPS: Started\n");
+
+ return 0;
+}
+
+static void set_wps_authentication(DBusMessageIter *iter, void *user_data)
+{
+ const char *auth = user_data;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &auth);
+}
+
+static int cmd_wps_start(char *args[], int num, struct connman_option *options)
+{
+ char *auth = "";
+ char *method = "StartStaWPS";
+ bool sta = true;
+
+ if (num > 3)
+ return -E2BIG;
+
+ if (num < 3)
+ return -EINVAL;
+
+ if (g_strcmp0(args[2], "pbc") != 0)
+ auth = args[2];
+
+ if (g_strcmp0(args[1], "ap") == 0) {
+ method = "StartApWps";
+ sta = false;
+ } else if (g_strcmp0(args[1], "sta") != 0) {
+ fprintf(stdout,
+ "Incorrect mode %s. Correct options: ap or sta\n",
+ args[1]);
+ return -EINVAL;
+ }
+
+ return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+ "/net/connman/technology/wifi",
+ "net.connman.Technology",
+ method, wps_cb, GUINT_TO_POINTER(sta),
+ set_wps_authentication, auth);
+}
+
+static int wps_cancel_cb(DBusMessageIter *iter, const char *error,
+ void *user_data)
+{
+ if (!error)
+ fprintf(stdout, "Ongoing WPS session cancelled\n");
+ else
+ fprintf(stdout, "WPS Error: %s\n", error);
+
+ return 0;
+}
+
+static int cmd_wps_cancel(char *args[], int num, struct connman_option *options)
+{
+ if (num > 1)
+ return -E2BIG;
+
+ return __connmanctl_dbus_method_call(connection, CONNMAN_SERVICE,
+ "/net/connman/technology/wifi",
+ "net.connman.Technology", "CancelWps",
+ wps_cancel_cb, NULL, NULL, NULL);
+}
+
static int scan_return(DBusMessageIter *iter, const char *error,
void *user_data)
{
@@ -2332,6 +2412,46 @@ static char *lookup_tether(const char *text, int state)
return NULL;
}
+static char *lookup_wps_option(const char *text, int state, char **opt)
+{
+ static int idx;
+ static int len;
+ char *str;
+
+ if (!state) {
+ idx = 0;
+ len = strlen(text);
+ }
+
+ while (opt[idx]) {
+ str = opt[idx];
+ idx++;
+
+ if (!strncmp(text, str, len))
+ return strdup(str);
+ }
+
+ return NULL;
+}
+
+static char *lookup_wps(const char *text, int state)
+{
+ int level;
+ const char *action[] = { "ap", "sta", NULL };
+ const char *type[] = { "pbc", NULL };
+
+ level = __connmanctl_input_calc_level();
+
+ if (level == 1)
+ return lookup_wps_option(text, state, action);
+ if (level == 2)
+ return lookup_wps_option(text, state, type);
+
+ __connmanctl_input_lookup_end();
+
+ return NULL;
+}
+
static char *lookup_agent(const char *text, int state)
{
if (__connmanctl_input_calc_level() > 1) {
@@ -2736,6 +2856,12 @@ static const struct {
NULL, cmd_tether,
"Enable, disable tethering, set SSID and passphrase for wifi",
lookup_tether },
+ { "wps", "ap|sta <pbc/PIN>", NULL, cmd_wps_start,
+ "Start WPS in AP or STA mode with PBC or indicating the PIN to be used",
+ lookup_wps },
+ { "wps_cancel", NULL, NULL, cmd_wps_cancel,
+ "Cancel ongoing WPS Session",
+ lookup_wps },
{ "services", "[<service>]", service_options, cmd_services,
"Display services", lookup_service_arg },
{ "peers", "[peer]", NULL, cmd_peers,
diff --git a/client/dbus_helpers.c b/client/dbus_helpers.c
index 6ca407d4..1a8eea16 100644
--- a/client/dbus_helpers.c
+++ b/client/dbus_helpers.c
@@ -28,7 +28,7 @@
#include "input.h"
#include "dbus_helpers.h"
-#define TIMEOUT 120000
+#define TIMEOUT 125000
void __connmanctl_dbus_print(DBusMessageIter *iter, const char *pre,
const char *dict, const char *sep)
--
2.17.1
2 years, 6 months
[PATCH 0/3] Update session-test
by Daniel Wagner
session-test started to bit rot slightly.
Daniel Wagner (3):
session-test: Update callback function signature
session-test: Use callback from helper data structure
session-test: Update notification parser
tools/session-api.c | 42 +++++++++++++++++++++++++++++++-----------
tools/session-test.h | 3 +++
tools/session-utils.c | 18 ++++++++++++------
3 files changed, 46 insertions(+), 17 deletions(-)
--
2.14.4
2 years, 6 months
[PATCH] iwd: Remove device state property
by Daniel Wagner
iwd has moved parts of the Device API into the Station API. Among
those properties is the state of device. So far we haven't used this
property at all, therefore we can just remove it.
---
plugins/iwd.c | 52 +---------------------------------------------------
1 file changed, 1 insertion(+), 51 deletions(-)
diff --git a/plugins/iwd.c b/plugins/iwd.c
index 6a017b2e90d0..ddc9201d03bc 100644
--- a/plugins/iwd.c
+++ b/plugins/iwd.c
@@ -55,14 +55,6 @@ static bool agent_registered;
#define IWD_AGENT_ERROR_INTERFACE "net.connman.iwd.Agent.Error"
#define AGENT_PATH "/net/connman/iwd_agent"
-enum iwd_device_state {
- IWD_DEVICE_STATE_UNKNOWN,
- IWD_DEVICE_STATE_CONNECTED,
- IWD_DEVICE_STATE_DISCONNECTED,
- IWD_DEVICE_STATE_CONNECTING,
- IWD_DEVICE_STATE_DISCONNECTING,
-};
-
struct iwd_adapter {
GDBusProxy *proxy;
char *path;
@@ -77,7 +69,6 @@ struct iwd_device {
char *adapter;
char *name;
char *address;
- enum iwd_device_state state;
bool powered;
bool scanning;
@@ -96,38 +87,6 @@ struct iwd_network {
struct connman_network *network;
};
-static enum iwd_device_state string2state(const char *str)
-{
- if (!strcmp(str, "connected"))
- return IWD_DEVICE_STATE_CONNECTED;
- else if (!strcmp(str, "disconnected"))
- return IWD_DEVICE_STATE_DISCONNECTED;
- else if (!strcmp(str, "connecting"))
- return IWD_DEVICE_STATE_CONNECTING;
- else if (!strcmp(str, "disconnecting"))
- return IWD_DEVICE_STATE_DISCONNECTING;
-
- return IWD_DEVICE_STATE_UNKNOWN;
-}
-
-static const char *state2string(enum iwd_device_state state)
-{
- switch (state) {
- case IWD_DEVICE_STATE_CONNECTED:
- return "connected";
- case IWD_DEVICE_STATE_DISCONNECTED:
- return "disconnected";
- case IWD_DEVICE_STATE_CONNECTING:
- return "connecting";
- case IWD_DEVICE_STATE_DISCONNECTING:
- return "disconnecting";
- default:
- break;
- }
-
- return "unknown";
-}
-
static const char *proxy_get_string(GDBusProxy *proxy, const char *property)
{
DBusMessageIter iter;
@@ -664,13 +623,6 @@ static void device_property_change(GDBusProxy *proxy, const char *name,
iwdd->name = g_strdup(name);
DBG("%p name %s", path, iwdd->name);
- } else if (!strcmp(name, "State")) {
- const char *state;
-
- dbus_message_iter_get_basic(iter, &state);
- iwdd->state = string2state(state);
-
- DBG("%s state %s", path, state2string(iwdd->state));
} else if (!strcmp(name, "Powered")) {
dbus_bool_t powered;
@@ -829,13 +781,11 @@ static void create_device(GDBusProxy *proxy)
iwdd->adapter = g_strdup(proxy_get_string(proxy, "Adapter"));
iwdd->name = g_strdup(proxy_get_string(proxy, "Name"));
iwdd->address = g_strdup(proxy_get_string(proxy, "Address"));
- iwdd->state = string2state(proxy_get_string(proxy, "State"));
iwdd->powered = proxy_get_bool(proxy, "Powered");
iwdd->scanning = proxy_get_bool(proxy, "Scanning");
- DBG("adapter %s name %s address %s state %s powered %d scanning %d",
+ DBG("adapter %s name %s address %s powered %d scanning %d",
iwdd->adapter, iwdd->name, iwdd->address,
- state2string(iwdd->state),
iwdd->powered, iwdd->scanning);
g_dbus_proxy_set_property_watch(iwdd->proxy,
--
2.14.4
2 years, 6 months
[PATCH 01/11] Use AC_USE_SYSTEM_EXTENSIONS
by Ross Burton
Instead of using #define _GNU_SOURCE in some source files which causes problems
when building with musl as more files need the define, simply use
AC_USE_SYSTEM_EXTENSIONS in configure.ac to get it defined globally.
Signed-off-by: Ross Burton <ross.burton(a)intel.com>
---
configure.ac | 1 +
gdhcp/client.c | 1 -
plugins/tist.c | 1 -
src/backtrace.c | 1 -
src/inet.c | 1 -
src/log.c | 1 -
src/nostats.c | 5 ++++-
src/ntp.c | 1 -
src/resolver.c | 1 -
src/rfkill.c | 1 -
src/stats.c | 1 -
src/timezone.c | 1 -
tools/stats-tool.c | 1 -
tools/tap-test.c | 1 -
tools/wispr.c | 1 -
vpn/plugins/vpn.c | 1 -
16 files changed, 5 insertions(+), 15 deletions(-)
diff --git a/configure.ac b/configure.ac
index 39745f76..11e63e66 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,7 @@ AC_SUBST(abs_top_srcdir)
AC_SUBST(abs_top_builddir)
AC_LANG_C
+AC_USE_SYSTEM_EXTENSIONS
AC_PROG_CC
AM_PROG_CC_C_O
diff --git a/gdhcp/client.c b/gdhcp/client.c
index eb8ed5df..aab74378 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
diff --git a/plugins/tist.c b/plugins/tist.c
index ad5ef79e..cc2800a1 100644
--- a/plugins/tist.c
+++ b/plugins/tist.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
diff --git a/src/backtrace.c b/src/backtrace.c
index e8d7f432..bede6698 100644
--- a/src/backtrace.c
+++ b/src/backtrace.c
@@ -24,7 +24,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
diff --git a/src/inet.c b/src/inet.c
index 8337949d..0d3f0d21 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -25,7 +25,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
diff --git a/src/log.c b/src/log.c
index 5deaff83..dd48a45c 100644
--- a/src/log.c
+++ b/src/log.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
diff --git a/src/nostats.c b/src/nostats.c
index 3d0dc793..aedc2c06 100644
--- a/src/nostats.c
+++ b/src/nostats.c
@@ -19,7 +19,10 @@
*
*/
-#define _GNU_SOURCE
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <errno.h>
#include "connman.h"
diff --git a/src/ntp.c b/src/ntp.c
index db2ad01f..807431a4 100644
--- a/src/ntp.c
+++ b/src/ntp.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
diff --git a/src/resolver.c b/src/resolver.c
index 76f0a8e1..10121aa5 100644
--- a/src/resolver.c
+++ b/src/resolver.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
diff --git a/src/rfkill.c b/src/rfkill.c
index d9bed4d2..b2514c41 100644
--- a/src/rfkill.c
+++ b/src/rfkill.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
diff --git a/src/stats.c b/src/stats.c
index b9205a99..6f7ce208 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <errno.h>
#include <sys/mman.h>
#include <sys/types.h>
diff --git a/src/timezone.c b/src/timezone.c
index e346b11a..8e912670 100644
--- a/src/timezone.c
+++ b/src/timezone.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
diff --git a/tools/stats-tool.c b/tools/stats-tool.c
index efa39de2..5695048f 100644
--- a/tools/stats-tool.c
+++ b/tools/stats-tool.c
@@ -22,7 +22,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/tools/tap-test.c b/tools/tap-test.c
index fdc098aa..57917f51 100644
--- a/tools/tap-test.c
+++ b/tools/tap-test.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
diff --git a/tools/wispr.c b/tools/wispr.c
index d5f9341f..e56dfc16 100644
--- a/tools/wispr.c
+++ b/tools/wispr.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
diff --git a/vpn/plugins/vpn.c b/vpn/plugins/vpn.c
index 94272f53..acede747 100644
--- a/vpn/plugins/vpn.c
+++ b/vpn/plugins/vpn.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
--
2.11.0
2 years, 6 months