Re: Re: [PATCH] dhcp: Fixed Crash on Switching Network
Hi, Please do not send patches as attachments as the formatting gets mangled when I reply to your patch. On Mon, 2014-08-04 at 11:16 +, Saurav Babu wrote: diff --git a/src/dhcp.c b/src/dhcp.c index 132b787..a3dd3c4 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -587,6 +587,7 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig, { const char *last_addr = NULL; struct connman_dhcp *dhcp; + int err; DBG(); @@ -615,9 +616,12 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig, connman_network_ref(network); } - g_hash_table_insert(ipconfig_table, ipconfig, dhcp); + err = dhcp_initialize(dhcp); - dhcp_initialize(dhcp); + if(err != 0) + return err; + + g_hash_table_insert(ipconfig_table, ipconfig, dhcp); } dhcp-callback = callback; First of all, check err for 0 as 0 and bigger signal some variants of success. There is a memory leak here, the dhcp structure is allocated but not freed on error. Also the network is referenced, but not unreferenced on error. Cheers, Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH] dhcp: Fixed Crash on Switching Network
Sometimes while switching network dhcp_initialize() fails because interface is not up and hence dhcp-dhcp_client remains NULL. Here we don't check return type of dhcp_initialize() and go on to call function g_dhcp_client_start() and crash occurs. Below trace is obtained when connman crashes: connmand[19034]: Aborting (signal 11) [/usr/local/sbin/connmand] connmand[19034]: backtrace connmand[19034]: #0 0xb7630f38 in /lib/i386-linux-gnu/libpthread.so.0 connmand[19034]: #1 0x8055a22 in debug() at client.c:0 connmand[19034]: #2 0x8058837 in g_dhcp_client_start() at polkit.c:0 connmand[19034]: #3 0x80a4772 in __connman_dhcp_start() at polkit.c:0 connmand[19034]: #4 0x8082a80 in set_connected.part.8() at network.c:0 connmand[19034]: #5 0x8082f7f in connman_network_set_connected() at ??:0 connmand[19034]: #6 0x805f921 in eth_network_connect() at ethernet.c:0 connmand[19034]: #7 0x8082dc3 in __connman_network_connect() at polkit.c:0 connmand[19034]: #8 0x808e7e4 in __connman_service_connect() at polkit.c:0 connmand[19034]: #9 0x808eef0 in auto_connect_service() at service.c:0 connmand[19034]: #10 0x808efde in run_auto_connect() at service.c:0 connmand[19034]: #11 0xb76cea3f in /lib/i386-linux-gnu/libglib-2.0.so.0 connmand[19034]: #12 0xb76cdd46 in /lib/i386-linux-gnu/libglib-2.0.so.0 connmand[19034]: #13 0xb76ce0e5 in /lib/i386-linux-gnu/libglib-2.0.so.0 connmand[19034]: #14 0xb76ce52b in /lib/i386-linux-gnu/libglib-2.0.so.0 connmand[19034]: #15 0x80544cd in main() at polkit.c:0 connmand[19034]: #16 0xb739b4d3 in /lib/i386-linux-gnu/libc.so.6 connmand[19034]: +++ --- src/dhcp.c | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/dhcp.c b/src/dhcp.c index d714f99..3e6ca3b 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -590,6 +590,7 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig, { const char *last_addr = NULL; struct connman_dhcp *dhcp; + int err; DBG(); @@ -618,9 +619,15 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig, connman_network_ref(network); } - g_hash_table_insert(ipconfig_table, ipconfig, dhcp); + err = dhcp_initialize(dhcp); - dhcp_initialize(dhcp); + if(err 0) { + connman_network_unref(network); + g_free(dhcp); + return err; + } + + g_hash_table_insert(ipconfig_table, ipconfig, dhcp); } dhcp-callback = callback; -- 1.9.1 Incorporated Patrik's Comments Thanks, Saurav ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: Re: [PATCH] dhcp: Fixed Crash on Switching Network
On Mon, 2014-08-04 at 11:16 +, Saurav Babu wrote: Sometimes while switching network dhcp_initialize() fails because interface is not up and hence dhcp-dhcp_client remains NULL. Here we don't check return type of dhcp_initialize() and go on to call function g_dhcp_client_start() and crash occurs. Could you actually post the logs when this happens? The log from just before the start of the switch until the crash happens would be very much more informative. The fix proposed does work and it will be applied, but the root cause remains unknown with only the backtrace. Just checking, but is this a regular desktop/laptop and a standard ethernet card? Cheers, Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 0/2] P2P GC/GO mitigation fix
Hi, Last patch set messed up the GC/GO mitigation in gsupplicant/wifi, ending up in a context where connman thinks it is always the GO. Thanks to Guoqiang Liu and Eduardo Abinader for reporting and testing this. Tomasz Bursztyka (2): gsupplicant: Catch Peer and Group related signals wifi: Handle group changed notification properly gsupplicant/supplicant.c | 8 plugins/wifi.c | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 1/2] gsupplicant: Catch Peer and Group related signals
Catching those signals is useful for 2 cases: - finalizing an on-going peer-group relation (Peer connection) - handling one-to-many context (when src/peer.c will be able to do so) --- gsupplicant/supplicant.c | 8 1 file changed, 8 insertions(+) diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 6337650..99a8d06 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -4794,6 +4794,10 @@ static const char *g_supplicant_rule5 = type=signal, interface= SUPPLICANT_INTERFACE .Network; static const char *g_supplicant_rule6 = type=signal, interface= SUPPLICANT_INTERFACE .Interface.P2PDevice; +static const char *g_supplicant_rule7 = type=signal, + interface= SUPPLICANT_INTERFACE .Peer; +static const char *g_supplicant_rule8 = type=signal, + interface= SUPPLICANT_INTERFACE .Group; static void invoke_introspect_method(void) { @@ -4847,6 +4851,8 @@ int g_supplicant_register(const GSupplicantCallbacks *callbacks) dbus_bus_add_match(connection, g_supplicant_rule4, NULL); dbus_bus_add_match(connection, g_supplicant_rule5, NULL); dbus_bus_add_match(connection, g_supplicant_rule6, NULL); + dbus_bus_add_match(connection, g_supplicant_rule7, NULL); + dbus_bus_add_match(connection, g_supplicant_rule8, NULL); dbus_connection_flush(connection); if (dbus_bus_name_has_owner(connection, @@ -4888,6 +4894,8 @@ void g_supplicant_unregister(const GSupplicantCallbacks *callbacks) SUPPLICANT_DBG(); if (connection) { + dbus_bus_remove_match(connection, g_supplicant_rule8, NULL); + dbus_bus_remove_match(connection, g_supplicant_rule7, NULL); dbus_bus_remove_match(connection, g_supplicant_rule6, NULL); dbus_bus_remove_match(connection, g_supplicant_rule5, NULL); dbus_bus_remove_match(connection, g_supplicant_rule4, NULL); -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 2/2] wifi: Handle group changed notification properly
Let's switch to configuration state. If the wifi device is currently connecting this will be handled properly, or will be discarded. --- plugins/wifi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/wifi.c b/plugins/wifi.c index 98d9532..4f7150d 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -2339,9 +2339,10 @@ static void peer_changed(GSupplicantPeer *peer, case G_SUPPLICANT_PEER_GROUP_CHANGED: if (!g_supplicant_peer_is_in_a_group(peer)) p_state = CONNMAN_PEER_STATE_IDLE; + else + p_state = CONNMAN_PEER_STATE_CONFIGURATION; break; case G_SUPPLICANT_PEER_GROUP_STARTED: - p_state = CONNMAN_PEER_STATE_CONFIGURATION; break; case G_SUPPLICANT_PEER_GROUP_FINISHED: p_state = CONNMAN_PEER_STATE_IDLE; -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH] agent: The reply of the error callback might be NULL
This fixes a crash when calling connman_agent_cancel(), where agent_finalize_pending() is called with a NULL reply which is then used in the callback. --- src/agent.c | 4 1 file changed, 4 insertions(+) diff --git a/src/agent.c b/src/agent.c index 37cf524..90ff670 100644 --- a/src/agent.c +++ b/src/agent.c @@ -350,6 +350,9 @@ static void report_error_reply(DBusMessage *reply, void *user_data) bool retry = false; const char *dbus_err; + if (!reply) + goto out; + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { dbus_err = dbus_message_get_error_name(reply); if (dbus_err @@ -360,6 +363,7 @@ static void report_error_reply(DBusMessage *reply, void *user_data) report_error-callback(report_error-user_context, retry, report_error-user_data); +out: g_free(report_error); } -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 01/16] doc: Add RequestPeerInput method to agent API
This method will be used to handle extra input which might be requested when connecting to a peer or in case a peer wants to connect to us. --- doc/agent-api.txt | 49 + 1 file changed, 49 insertions(+) diff --git a/doc/agent-api.txt b/doc/agent-api.txt index a98343f..2ddd19a 100644 --- a/doc/agent-api.txt +++ b/doc/agent-api.txt @@ -23,6 +23,16 @@ Methods void Release() Possible Errors: net.connman.Agent.Error.Retry + void ReportPeerError(object peer, string error) + + This method gets called when an error has to be + reported to the user about a peer connection. + + A special return value can be used to trigger a + retry of the failed transaction. + + Possible Errors: net.connman.Agent.Error.Retry + void RequestBrowser(object service, string url) This method gets called when it is required @@ -58,6 +68,25 @@ Methods void Release() Possible Errors: net.connman.Agent.Error.Canceled net.connman.Agent.Error.LaunchBrowser + dict RequestPeerAuthorization(object peer, dict fields) [experimental] + + This method gets called when trying to connect to a + peer or when an incoming peer connection is requested, + for which some extra input is required. In this case, + it will only deal with WPS input as well as accepting + or rejecting an incoming connection. + + The return value should be a dictionary where the + keys are the field names and the values are the + actual fields. Alternatively an error indicating that + the request got canceled or rejected can be returned. + + The dictionary arguments contains field names with + their input parameters. + + Possible Errors: net.connman.Agent.Error.Canceled +net.connman.Agent.Error.Rejected + void Cancel() This method gets called to indicate that the agent @@ -107,6 +136,9 @@ Fields string Name method, or a pin code if user wants to use the pin method. + In case of a RequestPeerAuthorization, this field will + be set as mandatory. + string Username Username for WISPr authentication. This field will be @@ -254,3 +286,20 @@ Examples Requesting a passphrase for WPA2 network } == { Username : foo, Password: secret } + + Requesting a answer about an inconming peer connection: + + RequestPeerAuthorization(/peer3, {}) + + == { } + + Requesting the WPS details when connecting to a peer: + + RequestPeerAuthorization(/peer4, + { WPS: + { Type: wpspin, + Requirement : mandatory + } + } + + == { WPS : } -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 03/16] agent: Add a specific function to call ReportPeerError agent method
This will be exclusively used by peer core code to report an error. --- src/agent-connman.c | 10 ++ src/connman.h | 8 2 files changed, 18 insertions(+) diff --git a/src/agent-connman.c b/src/agent-connman.c index ab538f3..7502f0f 100644 --- a/src/agent-connman.c +++ b/src/agent-connman.c @@ -644,3 +644,13 @@ int __connman_agent_request_browser(struct connman_service *service, return -EINPROGRESS; } + +int __connman_agent_report_peer_error(struct connman_peer *peer, + const char *path, const char *error, + report_error_cb_t callback, + const char *dbus_sender, + void *user_data) +{ + return connman_agent_report_error_full(peer, path, ReportPeerError, + error, callback, dbus_sender, user_data); +} diff --git a/src/connman.h b/src/connman.h index 5cff513..068e36f 100644 --- a/src/connman.h +++ b/src/connman.h @@ -88,7 +88,10 @@ int __connman_counter_unregister(const char *owner, const char *path); int __connman_counter_init(void); void __connman_counter_cleanup(void); +#include connman/agent.h + struct connman_service; +struct connman_peer; void __connman_agent_cancel(struct connman_service *service); @@ -111,6 +114,11 @@ int __connman_agent_request_login_input(struct connman_service *service, int __connman_agent_request_browser(struct connman_service *service, browser_authentication_cb_t callback, const char *url, void *user_data); +int __connman_agent_report_peer_error(struct connman_peer *peer, + const char *path, const char *error, + report_error_cb_t callback, + const char *dbus_sender, + void *user_data); #include connman/log.h -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 02/16] agent: Refactor the error reporting method to be more generic
Thus it will be possible afterwards to implement RequestPeerError very simply. --- include/agent.h | 4 src/agent.c | 17 + 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/include/agent.h b/include/agent.h index 05462df..6961f7a 100644 --- a/include/agent.h +++ b/include/agent.h @@ -52,6 +52,10 @@ void connman_agent_driver_unregister(struct connman_agent_driver *driver); typedef void (* report_error_cb_t) (void *user_context, bool retry, void *user_data); +int connman_agent_report_error_full(void *user_context, const char *path, + const char *method, const char *error, + report_error_cb_t callback, + const char *dbus_sender, void *user_data); int connman_agent_report_error(void *user_context, const char *path, const char *error, report_error_cb_t callback, diff --git a/src/agent.c b/src/agent.c index 90ff670..a340026 100644 --- a/src/agent.c +++ b/src/agent.c @@ -367,8 +367,8 @@ out: g_free(report_error); } -int connman_agent_report_error(void *user_context, const char *path, - const char *error, +int connman_agent_report_error_full(void *user_context, const char *path, + const char *method, const char *error, report_error_cb_t callback, const char *dbus_sender, void *user_data) { @@ -387,8 +387,7 @@ int connman_agent_report_error(void *user_context, const char *path, return -ESRCH; message = dbus_message_new_method_call(agent-owner, agent-path, - CONNMAN_AGENT_INTERFACE, - ReportError); + CONNMAN_AGENT_INTERFACE, method); if (!message) return -ENOMEM; @@ -425,6 +424,16 @@ int connman_agent_report_error(void *user_context, const char *path, return -EINPROGRESS; } +int connman_agent_report_error(void *user_context, const char *path, + const char *error, + report_error_cb_t callback, + const char *dbus_sender, void *user_data) +{ + return connman_agent_report_error_full(user_context, path, + ReportError, error, callback, dbus_sender, + user_data); +} + static gint compare_priority(gconstpointer a, gconstpointer b) { const struct connman_agent_driver *driver1 = a; -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH v2 00/16] Peer's Agent API support
v2: fixed an issue around wps pin handling This patch-set add the Peer's Agent API documentation and implementation. However, this only works in the context when ConnMan initiates the connection and not the other way round (which requires quite a bit of work to get it) Tomasz Bursztyka (16): doc: Add RequestPeerInput method to agent API agent: Refactor the error reporting method to be more generic agent: Add a specific function to call ReportPeerError agent method peer: Provide a utility function to get peer's path in the core agent: Provide a function for the Peer RequestPeerAuthorization call peer: Modify connect driver's signature to handle WPS properly peer: Manage peer connection properly through an Agent report peer: Call Agent RequestPeerAuthorization on WPS needs gsupplicant: WPS PIN and Peer's path parameters are copied value gsupplicant: Add an helper to find a peer via its identifier gsupplicant: Add an helper to get the supplicant peer's object path wifi: Handle properly WPS parameters while connecting a peer wifi: Find and use peer's path do disconnect gsupplicant: Do not use and remove identifier parameter for peer client: Add Agent ReportPeerError method support client: Add support for RequestPeerAuthorization on WPS client/agent.c| 144 + doc/agent-api.txt | 49 + gsupplicant/gsupplicant.h | 8 ++- gsupplicant/supplicant.c | 61 +--- include/agent.h | 4 ++ include/peer.h| 10 ++- plugins/wifi.c| 48 +++-- src/agent-connman.c | 177 +- src/agent.c | 17 +++-- src/connman.h | 17 + src/peer.c| 141 11 files changed, 578 insertions(+), 98 deletions(-) -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 05/16] agent: Provide a function for the Peer RequestPeerAuthorization call
This will be used by peer.c when there will be a need to choose between WPS PBC or PIN. This choice will be raised to the user via an agent RequestPeerAuthorization call. --- src/agent-connman.c | 167 ++-- src/connman.h | 8 +++ 2 files changed, 158 insertions(+), 17 deletions(-) diff --git a/src/agent-connman.c b/src/agent-connman.c index 7502f0f..f7a7f3a 100644 --- a/src/agent-connman.c +++ b/src/agent-connman.c @@ -55,8 +55,15 @@ static bool check_reply_has_dict(DBusMessage *reply) } struct request_input_reply { - struct connman_service *service; - authentication_cb_t callback; + union { + struct connman_service *service; + struct connman_peer *peer; + }; + union { + authentication_cb_t service_callback; + peer_wps_cb_t peer_callback; + }; + bool wps_requested; void *user_data; }; @@ -151,12 +158,10 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data) } done: - passphrase_reply-callback(passphrase_reply-service, values_received, - name, name_len, - identity, passphrase, - wps, wpspin, error, - passphrase_reply-user_data); - + passphrase_reply-service_callback(passphrase_reply-service, + values_received, name, name_len, + identity, passphrase, wps, wpspin, + error, passphrase_reply-user_data); out: g_free(passphrase_reply); } @@ -236,13 +241,21 @@ static void request_input_append_passphrase(DBusMessageIter *iter, } } +struct request_wps_data { + bool peer; +}; + static void request_input_append_wps(DBusMessageIter *iter, void *user_data) { + struct request_wps_data *wps = user_data; const char *str = wpspin; connman_dbus_dict_append_basic(iter, Type, DBUS_TYPE_STRING, str); - str = alternate; + if (wps wps-peer) + str = mandatory; + else + str = alternate; connman_dbus_dict_append_basic(iter, Requirement, DBUS_TYPE_STRING, str); } @@ -399,12 +412,10 @@ static void request_input_login_reply(DBusMessage *reply, void *user_data) } done: - username_password_reply-callback(username_password_reply-service, - values_received, NULL, 0, - username, password, - FALSE, NULL, error, - username_password_reply-user_data); - + username_password_reply-service_callback( + username_password_reply-service, values_received, + NULL, 0, username, password, FALSE, NULL, error, + username_password_reply-user_data); out: g_free(username_password_reply); } @@ -477,7 +488,7 @@ int __connman_agent_request_passphrase_input(struct connman_service *service, } passphrase_reply-service = service; - passphrase_reply-callback = callback; + passphrase_reply-service_callback = callback; passphrase_reply-user_data = user_data; err = connman_agent_queue_message(service, message, @@ -542,7 +553,7 @@ int __connman_agent_request_login_input(struct connman_service *service, } username_password_reply-service = service; - username_password_reply-callback = callback; + username_password_reply-service_callback = callback; username_password_reply-user_data = user_data; err = connman_agent_queue_message(service, message, @@ -654,3 +665,125 @@ int __connman_agent_report_peer_error(struct connman_peer *peer, return connman_agent_report_error_full(peer, path, ReportPeerError, error, callback, dbus_sender, user_data); } + +static void request_peer_authorization_reply(DBusMessage *reply, + void *user_data) +{ + struct request_input_reply *auth_reply = user_data; + DBusMessageIter iter, dict; + const char *error = NULL; + bool choice_done = false; + char *wpspin = NULL; + char *key; + + if (!reply) + goto out; + + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + error = dbus_message_get_error_name(reply); + goto done; + } + + if (!check_reply_has_dict(reply)) + goto done; + + dbus_message_iter_init(reply, iter); + dbus_message_iter_recurse(iter, dict); + while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) { +
[PATCH 09/16] gsupplicant: WPS PIN and Peer's path parameters are copied value
These are no longer constants, this is necessary for the future changes. --- gsupplicant/gsupplicant.h | 4 ++-- gsupplicant/supplicant.c | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 344459b..6c22aa4 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -171,8 +171,8 @@ typedef struct _GSupplicantScanParams GSupplicantScanParams; struct _GSupplicantPeerParams { const char *identifier; - const char *wps_pin; - const char *path; + char *wps_pin; + char *path; }; typedef struct _GSupplicantPeerParams GSupplicantPeerParams; diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 99a8d06..a371a88 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -4641,6 +4641,8 @@ static void interface_p2p_connect_result(const char *error, data-callback(err, data-interface, data-user_data); g_free(data-path); + g_free(data-peer-wps_pin); + g_free(data-peer-path); g_free(data-peer); g_free(data); } @@ -4708,7 +4710,7 @@ int g_supplicant_interface_p2p_connect(GSupplicantInterface *interface, if (!peer) return -ENODEV; - peer_params-path = peer-path; + peer_params-path = g_strdup(peer-path); } data = dbus_malloc0(sizeof(*data)); -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 11/16] gsupplicant: Add an helper to get the supplicant peer's object path
Since wifi plugin will be looking up for the peer while connecting, it will be the right place to get such information for the connection parameters. --- gsupplicant/gsupplicant.h | 1 + gsupplicant/supplicant.c | 8 2 files changed, 9 insertions(+) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 90752d3..e20d6fd 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -292,6 +292,7 @@ dbus_bool_t g_supplicant_network_is_wps_pbc(GSupplicantNetwork *network); dbus_bool_t g_supplicant_network_is_wps_advertizing(GSupplicantNetwork *network); GSupplicantInterface *g_supplicant_peer_get_interface(GSupplicantPeer *peer); +const char *g_supplicant_peer_get_path(GSupplicantPeer *peer); const char *g_supplicant_peer_get_identifier(GSupplicantPeer *peer); const void *g_supplicant_peer_get_device_address(GSupplicantPeer *peer); const char *g_supplicant_peer_get_name(GSupplicantPeer *peer); diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 178b4da..ce0740d 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -1037,6 +1037,14 @@ GSupplicantInterface *g_supplicant_peer_get_interface(GSupplicantPeer *peer) return peer-interface; } +const char *g_supplicant_peer_get_path(GSupplicantPeer *peer) +{ + if (!peer) + return NULL; + + return peer-path; +} + const char *g_supplicant_peer_get_identifier(GSupplicantPeer *peer) { if (!peer) -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 06/16] peer: Modify connect driver's signature to handle WPS properly
It will be possible to tell the WPS method which is wanted to connect to the peer. --- include/peer.h | 10 +- plugins/wifi.c | 4 +++- src/peer.c | 3 ++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/include/peer.h b/include/peer.h index 720d65b..dd118cd 100644 --- a/include/peer.h +++ b/include/peer.h @@ -36,6 +36,12 @@ enum connman_peer_state { CONNMAN_PEER_STATE_FAILURE = 6, }; +enum connman_peer_wps_method { + CONNMAN_PEER_WPS_UNKNOWN = 0, + CONNMAN_PEER_WPS_PBC = 1, + CONNMAN_PEER_WPS_PIN = 2, +}; + struct connman_peer; struct connman_peer *connman_peer_create(const char *identifier); @@ -69,7 +75,9 @@ struct connman_peer *connman_peer_get(struct connman_device *device, const char *identifier); struct connman_peer_driver { - int (*connect) (struct connman_peer *peer); + int (*connect) (struct connman_peer *peer, + enum connman_peer_wps_method wps_method, + const char *wps_pin); int (*disconnect) (struct connman_peer *peer); }; diff --git a/plugins/wifi.c b/plugins/wifi.c index 4f7150d..24fd844 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -236,7 +236,9 @@ static void peer_connect_callback(int result, GSupplicantInterface *interface, peer_connect_timeout, wifi); } -static int peer_connect(struct connman_peer *peer) +static int peer_connect(struct connman_peer *peer, + enum connman_peer_wps_method wps_method, + const char *wps_pin) { struct connman_device *device = connman_peer_get_device(peer); GSupplicantPeerParams *peer_params; diff --git a/src/peer.c b/src/peer.c index 2d40dc4..50df50e 100644 --- a/src/peer.c +++ b/src/peer.c @@ -454,7 +454,8 @@ static int peer_connect(struct connman_peer *peer) int err = -ENOTSUP; if (peer_driver-connect) - err = peer_driver-connect(peer); + err = peer_driver-connect(peer, + CONNMAN_PEER_WPS_UNKNOWN, NULL); return err; } -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 04/16] peer: Provide a utility function to get peer's path in the core
This will be useful in agent-connman code afterwards. --- src/connman.h | 1 + src/peer.c| 8 2 files changed, 9 insertions(+) diff --git a/src/connman.h b/src/connman.h index 068e36f..c16526e 100644 --- a/src/connman.h +++ b/src/connman.h @@ -788,6 +788,7 @@ int __connman_peer_init(void); void __connman_peer_cleanup(void); void __connman_peer_list_struct(DBusMessageIter *array); +const char *__connman_peer_get_path(struct connman_peer *peer); #include connman/session.h diff --git a/src/peer.c b/src/peer.c index 1d802e1..2d40dc4 100644 --- a/src/peer.c +++ b/src/peer.c @@ -894,6 +894,14 @@ void __connman_peer_list_struct(DBusMessageIter *array) g_hash_table_foreach(peers_table, append_peer_struct, array); } +const char *__connman_peer_get_path(struct connman_peer *peer) +{ + if (!peer || !peer-registered) + return NULL; + + return peer-path; +} + int __connman_peer_init(void) { DBG(); -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 08/16] peer: Call Agent RequestPeerAuthorization on WPS needs
This call will be raised if only a peer support both WPS pbc and pin method and is not currently advertizing for pbc, thus the need for the user to tell which method is necessary to proceed with the connection. --- src/peer.c | 78 +++--- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/src/peer.c b/src/peer.c index feb8e75..7716f67 100644 --- a/src/peer.c +++ b/src/peer.c @@ -24,6 +24,7 @@ #endif #include errno.h +#include ctype.h #include gdbus.h #include gdhcp/gdhcp.h @@ -451,6 +452,69 @@ static void peer_removed(struct connman_peer *peer) peer_schedule_changed(); } +static const char *get_dbus_sender(struct connman_peer *peer) +{ + if (!peer-pending) + return NULL; + + return dbus_message_get_sender(peer-pending); +} + +static enum connman_peer_wps_method check_wpspin(struct connman_peer *peer, + const char *wpspin) +{ + int len, i; + + if (!wpspin) + return CONNMAN_PEER_WPS_PBC; + + len = strlen(wpspin); + if (len == 0) + return CONNMAN_PEER_WPS_PBC; + + if (len != 8) + return CONNMAN_PEER_WPS_UNKNOWN; + for (i = 0; i 8; i++) { + if (!isdigit((unsigned char) wpspin[i])) + return CONNMAN_PEER_WPS_UNKNOWN; + } + + return CONNMAN_PEER_WPS_PIN; +} + +static void request_authorization_cb(struct connman_peer *peer, + bool choice_done, const char *wpspin, + const char *error, void *user_data) +{ + enum connman_peer_wps_method wps_method; + int err; + + DBG(RequestInput return, %p, peer); + + if (error) { + if (g_strcmp0(error, + net.connman.Agent.Error.Canceled) == 0) { + err = -EINVAL; + goto out; + } + } + + if (!choice_done || !peer_driver-connect) { + err = -EINVAL; + goto out; + } + + wps_method = check_wpspin(peer, wpspin); + + err = peer_driver-connect(peer, wps_method, wpspin); + if (err == -EINPROGRESS) + return; + +out: + reply_pending(peer, EIO); + connman_peer_set_state(peer, CONNMAN_PEER_STATE_IDLE); +} + static int peer_connect(struct connman_peer *peer) { int err = -ENOTSUP; @@ -459,6 +523,12 @@ static int peer_connect(struct connman_peer *peer) err = peer_driver-connect(peer, CONNMAN_PEER_WPS_UNKNOWN, NULL); + if (err == -ENOKEY) { + err = __connman_agent_request_peer_authorization(peer, + request_authorization_cb, true, + get_dbus_sender(peer), NULL); + } + return err; } @@ -689,14 +759,6 @@ static void report_error_cb(void *user_context, bool retry, void *user_data) peer-sub_device = NULL; } -static const char *get_dbus_sender(struct connman_peer *peer) -{ - if (!peer-pending) - return NULL; - - return dbus_message_get_sender(peer-pending); -} - static int manage_peer_error(struct connman_peer *peer) { int err; -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 12/16] wifi: Handle properly WPS parameters while connecting a peer
It checks whether the peer has proper WPS method requested. It can return ENOKEY in case of none can be decided (thus peer core code will request it through an agent call). --- plugins/wifi.c | 30 +- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/plugins/wifi.c b/plugins/wifi.c index 24fd844..140e684 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -242,7 +242,9 @@ static int peer_connect(struct connman_peer *peer, { struct connman_device *device = connman_peer_get_device(peer); GSupplicantPeerParams *peer_params; + GSupplicantPeer *gs_peer; struct wifi_data *wifi; + bool pbc, pin; int ret; DBG(peer %p, peer); @@ -257,11 +259,37 @@ static int peer_connect(struct connman_peer *peer, if (wifi-p2p_connecting) return -EBUSY; + gs_peer = g_supplicant_interface_peer_lookup(wifi-interface, + connman_peer_get_identifier(peer)); + if (!gs_peer) + return -EINVAL; + + pbc = g_supplicant_peer_is_wps_pbc(gs_peer); + pin = g_supplicant_peer_is_wps_pin(gs_peer); + + switch (wps_method) { + case CONNMAN_PEER_WPS_UNKNOWN: + if ((pbc pin) || pin) + return -ENOKEY; + break; + case CONNMAN_PEER_WPS_PBC: + if (!pbc) + return -EINVAL; + wps_pin = NULL; + break; + case CONNMAN_PEER_WPS_PIN: + if (!pin || !wps_pin) + return -EINVAL; + break; + } + peer_params = g_try_malloc0(sizeof(GSupplicantPeerParams)); if (!peer_params) return -ENOMEM; - peer_params-identifier = connman_peer_get_identifier(peer); + peer_params-path = g_strdup(g_supplicant_peer_get_path(gs_peer)); + if (wps_pin) + peer_params-wps_pin = g_strdup(wps_pin); ret = g_supplicant_interface_p2p_connect(wifi-interface, peer_params, peer_connect_callback, wifi); -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 07/16] peer: Manage peer connection properly through an Agent report
Thus the upper layer, if providing an agent, will get a report from connman and it will be possible at this point to ask for a proper retry. --- src/peer.c | 68 ++ 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/src/peer.c b/src/peer.c index 50df50e..feb8e75 100644 --- a/src/peer.c +++ b/src/peer.c @@ -27,6 +27,8 @@ #include gdbus.h #include gdhcp/gdhcp.h +#include connman/agent.h + #include connman.h static DBusConnection *connection = NULL; @@ -464,6 +466,7 @@ static int peer_disconnect(struct connman_peer *peer) { int err = -ENOTSUP; + connman_agent_cancel(peer); reply_pending(peer, ECONNABORTED); if (peer-connection_master) @@ -660,6 +663,55 @@ static int start_dhcp_client(struct connman_peer *peer) return __connman_dhcp_start(peer-ipconfig, NULL, dhcp_callback, peer); } +static void report_error_cb(void *user_context, bool retry, void *user_data) +{ + struct connman_peer *peer = user_context; + + if (retry) { + int err; + err = peer_connect(peer); + + if (err == 0 || err == -EINPROGRESS) + return; + } + + reply_pending(peer, ENOTCONN); + + peer_disconnect(peer); + + if (!peer-connection_master) { + __connman_dhcp_stop(peer-ipconfig); + __connman_ipconfig_disable(peer-ipconfig); + } else + stop_dhcp_server(peer); + + peer-connection_master = false; + peer-sub_device = NULL; +} + +static const char *get_dbus_sender(struct connman_peer *peer) +{ + if (!peer-pending) + return NULL; + + return dbus_message_get_sender(peer-pending); +} + +static int manage_peer_error(struct connman_peer *peer) +{ + int err; + + err = __connman_agent_report_peer_error(peer, peer-path, + connect-failed, report_error_cb, + get_dbus_sender(peer), NULL); + if (err != -EINPROGRESS) { + report_error_cb(peer, false, NULL); + return err; + } + + return 0; +} + int connman_peer_set_state(struct connman_peer *peer, enum connman_peer_state new_state) { @@ -697,19 +749,8 @@ int connman_peer_set_state(struct connman_peer *peer, break; case CONNMAN_PEER_STATE_FAILURE: - reply_pending(peer, ENOTCONN); - - peer_disconnect(peer); - - if (!peer-connection_master) { - __connman_dhcp_stop(peer-ipconfig); - __connman_ipconfig_disable(peer-ipconfig); - } else - stop_dhcp_server(peer); - - peer-connection_master = false; - peer-sub_device = NULL; - + if (manage_peer_error(peer) == 0) + return 0; break; }; @@ -852,6 +893,7 @@ void connman_peer_unregister(struct connman_peer *peer) if (!peer-path || !peer-registered) return; + connman_agent_cancel(peer); reply_pending(peer, EIO); g_dbus_unregister_interface(connection, peer-path, -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 13/16] wifi: Find and use peer's path do disconnect
Peer's lookup is done in wifi plugin and not anymore in gsupplicant part. --- plugins/wifi.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/wifi.c b/plugins/wifi.c index 140e684..70eb661 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -306,7 +306,9 @@ static int peer_disconnect(struct connman_peer *peer) { struct connman_device *device = connman_peer_get_device(peer); GSupplicantPeerParams peer_params = {}; + GSupplicantPeer *gs_peer; struct wifi_data *wifi; + int ret; DBG(peer %p, peer); @@ -317,10 +319,18 @@ static int peer_disconnect(struct connman_peer *peer) if (!wifi) return -ENODEV; - peer_params.identifier = connman_peer_get_identifier(peer); + gs_peer = g_supplicant_interface_peer_lookup(wifi-interface, + connman_peer_get_identifier(peer)); + if (!gs_peer) + return -EINVAL; + + peer_params.path = g_strdup(g_supplicant_peer_get_path(gs_peer)); - return g_supplicant_interface_p2p_disconnect(wifi-interface, + ret = g_supplicant_interface_p2p_disconnect(wifi-interface, peer_params); + g_free(peer_params.path); + + return ret; } static struct connman_peer_driver peer_driver = { -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 10/16] gsupplicant: Add an helper to find a peer via its identifier
Wifi plugin will need to find the peer to check whether it supports WPS PBC or PIN method while connectin, and action upon it. --- gsupplicant/gsupplicant.h | 2 ++ gsupplicant/supplicant.c | 45 +++-- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index 6c22aa4..90752d3 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -266,6 +266,8 @@ int g_supplicant_interface_set_country(GSupplicantInterface *interface, bool g_supplicant_interface_has_p2p(GSupplicantInterface *interface); int g_supplicant_interface_set_p2p_device_config(GSupplicantInterface *interface, const char *device_name); +GSupplicantPeer *g_supplicant_interface_peer_lookup(GSupplicantInterface *interface, + const char *identifier); /* Network and Peer API */ struct _GSupplicantNetwork; diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index a371a88..178b4da 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -3159,6 +3159,29 @@ int g_supplicant_interface_set_p2p_device_config(GSupplicantInterface *interface return ret; } +static gboolean peer_lookup_by_identifier(gpointer key, gpointer value, + gpointer user_data) +{ + const GSupplicantPeer *peer = value; + const char *identifier = user_data; + + if (!g_strcmp0(identifier, peer-identifier)) + return TRUE; + + return FALSE; +} + +GSupplicantPeer *g_supplicant_interface_peer_lookup(GSupplicantInterface *interface, + const char *identifier) +{ + GSupplicantPeer *peer; + + peer = g_hash_table_find(interface-peer_table, + peer_lookup_by_identifier, + (void *) identifier); + return peer; +} + struct interface_data { GSupplicantInterface *interface; char *path; /* Interface path cannot be taken from interface (above) as @@ -4676,18 +4699,6 @@ static void interface_p2p_connect_params(DBusMessageIter *iter, void *user_data) supplicant_dbus_dict_close(iter, dict); } -static gboolean peer_lookup_by_identifier(gpointer key, gpointer value, - gpointer user_data) -{ - const GSupplicantPeer *peer = value; - const char *identifier = user_data; - - if (!g_strcmp0(identifier, peer-identifier)) - return TRUE; - - return FALSE; -} - int g_supplicant_interface_p2p_connect(GSupplicantInterface *interface, GSupplicantPeerParams *peer_params, GSupplicantInterfaceCallback callback, @@ -4704,9 +4715,8 @@ int g_supplicant_interface_p2p_connect(GSupplicantInterface *interface, if (!peer_params-path) { GSupplicantPeer *peer; - peer = g_hash_table_find(interface-peer_table, - peer_lookup_by_identifier, - (void *) peer_params-identifier); + peer = g_supplicant_interface_peer_lookup(interface, + peer_params-identifier); if (!peer) return -ENODEV; @@ -4745,9 +4755,8 @@ int g_supplicant_interface_p2p_disconnect(GSupplicantInterface *interface, if (!interface-p2p_support) return -ENOTSUP; - peer = g_hash_table_find(interface-peer_table, - peer_lookup_by_identifier, - (void *) peer_params-identifier); + peer = g_supplicant_interface_peer_lookup(interface, + peer_params-identifier); if (!peer) return -ENODEV; -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 16/16] client: Add support for RequestPeerAuthorization on WPS
This method will be requested by ConnMan when it will need to know whether to use WPS PIN or WPS PBC when connecting a peer. --- client/agent.c | 110 ++--- 1 file changed, 82 insertions(+), 28 deletions(-) diff --git a/client/agent.c b/client/agent.c index 64c84da..5a1b944 100644 --- a/client/agent.c +++ b/client/agent.c @@ -492,37 +492,16 @@ static void request_input_string_return(char *input, void *user_data) request_input_next(request); } -static DBusMessage *agent_request_input(DBusConnection *connection, - DBusMessage *message, void *user_data) +static void parse_agent_request(struct agent_data *request, + DBusMessageIter *iter) { - struct agent_data *request = user_data; - DBusMessageIter iter, dict, entry, variant; - char *service, *str, *field; - DBusMessageIter dict_entry, field_entry, field_value; - char *argument, *value, *attr_type = NULL; - + DBusMessageIter dict, entry, variant, dict_entry; + DBusMessageIter field_entry, field_value; + char *field, *argument, *value; + char *attr_type = NULL; int i; - if (handle_message(message, request, agent_request_input) == false) - return NULL; - - dbus_message_iter_init(message, iter); - - dbus_message_iter_get_basic(iter, str); - service = strip_path(str); - - dbus_message_iter_next(iter); - dbus_message_iter_recurse(iter, dict); - - __connmanctl_save_rl(); - if (strcmp(request-interface, AGENT_INTERFACE) == 0) - fprintf(stdout, Agent RequestInput %s\n, service); - else - fprintf(stdout, VPN Agent RequestInput %s\n, service); - __connmanctl_dbus_print(dict, , = , \n); - fprintf(stdout, \n); - - dbus_message_iter_recurse(iter, dict); + dbus_message_iter_recurse(iter, dict); while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) { @@ -566,6 +545,76 @@ static DBusMessage *agent_request_input(DBusConnection *connection, dbus_message_iter_next(dict); } +} + +static DBusMessage *agent_request_input(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + struct agent_data *request = user_data; + DBusMessageIter iter, dict; + char *service, *str; + + if (handle_message(message, request, agent_request_input) == false) + return NULL; + + dbus_message_iter_init(message, iter); + + dbus_message_iter_get_basic(iter, str); + service = strip_path(str); + + dbus_message_iter_next(iter); + dbus_message_iter_recurse(iter, dict); + + __connmanctl_save_rl(); + if (strcmp(request-interface, AGENT_INTERFACE) == 0) + fprintf(stdout, Agent RequestInput %s\n, service); + else + fprintf(stdout, VPN Agent RequestInput %s\n, service); + __connmanctl_dbus_print(dict, , = , \n); + fprintf(stdout, \n); + + parse_agent_request(request, iter); + + request-reply = dbus_message_new_method_return(message); + dbus_message_iter_init_append(request-reply, request-iter); + + dbus_message_iter_open_container(request-iter, DBUS_TYPE_ARRAY, +DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING +DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING +DBUS_DICT_ENTRY_END_CHAR_AS_STRING, + request-dict); + + request_input_next(request); + + return NULL; +} + +static DBusMessage * +agent_request_peer_authorization(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + struct agent_data *request = user_data; + DBusMessageIter iter, dict; + char *peer, *str; + + if (handle_message(message, request, agent_request_peer_authorization) + == false) + return NULL; + + dbus_message_iter_init(message, iter); + + dbus_message_iter_get_basic(iter, str); + peer = strip_path(str); + + dbus_message_iter_next(iter); + dbus_message_iter_recurse(iter, dict); + + __connmanctl_save_rl(); + fprintf(stdout, Agent RequestPeerAuthorization %s\n, peer); + __connmanctl_dbus_print(dict, , = , \n); + fprintf(stdout, \n); + + parse_agent_request(request, iter); request-reply = dbus_message_new_method_return(message); dbus_message_iter_init_append(request-reply, request-iter); @@ -601,6 +650,11 @@ static const GDBusMethodTable agent_methods[] = { { fields, a{sv} }), GDBUS_ARGS({ fields, a{sv} }), agent_request_input) }, + {
[PATCH 15/16] client: Add Agent ReportPeerError method support
This will be used to report error from ConnMan. --- client/agent.c | 34 ++ 1 file changed, 34 insertions(+) diff --git a/client/agent.c b/client/agent.c index baa0a87..64c84da 100644 --- a/client/agent.c +++ b/client/agent.c @@ -368,6 +368,36 @@ static DBusMessage *agent_report_error(DBusConnection *connection, return NULL; } +static DBusMessage *agent_report_peer_error(DBusConnection *connection, + DBusMessage *message, void *user_data) +{ + struct agent_data *request = user_data; + char *path, *peer, *error; + DBusMessageIter iter; + + if (handle_message(message, request, + agent_report_peer_error) == false) + return NULL; + + dbus_message_iter_init(message, iter); + + dbus_message_iter_get_basic(iter, path); + peer = strip_path(path); + + dbus_message_iter_next(iter); + dbus_message_iter_get_basic(iter, error); + + __connmanctl_save_rl(); + fprintf(stdout, Agent ReportPeerError %s\n, peer); + fprintf(stdout, %s\n, error); + __connmanctl_redraw_rl(); + + request-message = dbus_message_ref(message); + __connmanctl_agent_mode(Retry (yes/no)? , + report_error_return, request); + return NULL; +} + static void request_input_next(struct agent_data *request) { int i; @@ -562,6 +592,10 @@ static const GDBusMethodTable agent_methods[] = { GDBUS_ARGS({ service, o }, { error, s }), NULL, agent_report_error) }, + { GDBUS_ASYNC_METHOD(ReportPeerError, + GDBUS_ARGS({ peer, o }, + { error, s }), + NULL, agent_report_peer_error) }, { GDBUS_ASYNC_METHOD(RequestInput, GDBUS_ARGS({ service, o }, { fields, a{sv} }), -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH 14/16] gsupplicant: Do not use and remove identifier parameter for peer
Wifi plugins is now using path as the only way to identify the peer while connecting or disconnecting. --- gsupplicant/gsupplicant.h | 1 - gsupplicant/supplicant.c | 14 +- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h index e20d6fd..207e281 100644 --- a/gsupplicant/gsupplicant.h +++ b/gsupplicant/gsupplicant.h @@ -170,7 +170,6 @@ struct _GSupplicantScanParams { typedef struct _GSupplicantScanParams GSupplicantScanParams; struct _GSupplicantPeerParams { - const char *identifier; char *wps_pin; char *path; }; diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index ce0740d..b8ad5a2 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -4720,17 +4720,6 @@ int g_supplicant_interface_p2p_connect(GSupplicantInterface *interface, if (!interface-p2p_support) return -ENOTSUP; - if (!peer_params-path) { - GSupplicantPeer *peer; - - peer = g_supplicant_interface_peer_lookup(interface, - peer_params-identifier); - if (!peer) - return -ENODEV; - - peer_params-path = g_strdup(peer-path); - } - data = dbus_malloc0(sizeof(*data)); data-interface = interface; data-path = g_strdup(interface-path); @@ -4763,8 +4752,7 @@ int g_supplicant_interface_p2p_disconnect(GSupplicantInterface *interface, if (!interface-p2p_support) return -ENOTSUP; - peer = g_supplicant_interface_peer_lookup(interface, - peer_params-identifier); + peer = g_hash_table_lookup(interface-peer_table, peer_params-path); if (!peer) return -ENODEV; -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH] peer: Switch to relevant states when disconnecting
Let's announce first we are disconnecting and, once done, that we are idling again. --- src/peer.c | 4 1 file changed, 4 insertions(+) diff --git a/src/peer.c b/src/peer.c index 7716f67..d314c01 100644 --- a/src/peer.c +++ b/src/peer.c @@ -539,6 +539,8 @@ static int peer_disconnect(struct connman_peer *peer) connman_agent_cancel(peer); reply_pending(peer, ECONNABORTED); + connman_peer_set_state(peer, CONNMAN_PEER_STATE_DISCONNECT); + if (peer-connection_master) stop_dhcp_server(peer); else @@ -547,6 +549,8 @@ static int peer_disconnect(struct connman_peer *peer) if (peer_driver-disconnect) err = peer_driver-disconnect(peer); + connman_peer_set_state(peer, CONNMAN_PEER_STATE_IDLE); + return err; } -- 1.8.5.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH 0/2] Two DHCPv6 fixes
On Mon, 2014-08-04 at 15:58 +0300, Patrik Flykt wrote: Hi, Here are two patches fixing DHCPv6 T1 and T2 timer calculations. With this default timer values should be used and proper timeouts calculated. Both patches applied. Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH] service: Fix service disconnection when using the same index
On Tue, 2014-08-05 at 13:12 +0300, Patrik Flykt wrote: When a service is to be connected, other service(s) using the same interface will be disconnected. Fix the already connected or connecting situation by ignoring the service in question when seen in the list. Simplify the index detection and signal a timeout when disconnect needs to happen first in order to indicate to the caller that the connect action needs to be redone. Thanks to Chengyi Zhao for finding the issue. Applied. Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH] dhcp: Fixed Crash on Switching Network
On Wed, 2014-08-06 at 14:29 +0530, Saurav Babu wrote: Sometimes while switching network dhcp_initialize() fails because interface is not up and hence dhcp-dhcp_client remains NULL. Here we don't check return type of dhcp_initialize() and go on to call function g_dhcp_client_start() and crash occurs. Applied, thanks! Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH 0/2] P2P GC/GO mitigation fix
On Wed, 2014-08-06 at 13:10 +0300, Tomasz Bursztyka wrote: Hi, Last patch set messed up the GC/GO mitigation in gsupplicant/wifi, ending up in a context where connman thinks it is always the GO. Thanks to Guoqiang Liu and Eduardo Abinader for reporting and testing this. Applied, thanks guys! Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH] agent: The reply of the error callback might be NULL
On Wed, 2014-08-06 at 13:11 +0300, Tomasz Bursztyka wrote: This fixes a crash when calling connman_agent_cancel(), where agent_finalize_pending() is called with a NULL reply which is then used in the callback. Applied, thanks! Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH 05/16] agent: Provide a function for the Peer RequestPeerAuthorization call
Hi, On Wed, 2014-08-06 at 13:29 +0300, Tomasz Bursztyka wrote: This will be used by peer.c when there will be a need to choose between WPS PBC or PIN. This choice will be raised to the user via an agent RequestPeerAuthorization call. --- src/agent-connman.c | 167 ++-- src/connman.h | 8 +++ 2 files changed, 158 insertions(+), 17 deletions(-) diff --git a/src/agent-connman.c b/src/agent-connman.c index 7502f0f..f7a7f3a 100644 --- a/src/agent-connman.c +++ b/src/agent-connman.c @@ -55,8 +55,15 @@ static bool check_reply_has_dict(DBusMessage *reply) } struct request_input_reply { - struct connman_service *service; - authentication_cb_t callback; + union { + struct connman_service *service; + struct connman_peer *peer; + }; + union { + authentication_cb_t service_callback; + peer_wps_cb_t peer_callback; + }; + bool wps_requested; void *user_data; }; @@ -151,12 +158,10 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data) } done: - passphrase_reply-callback(passphrase_reply-service, values_received, - name, name_len, - identity, passphrase, - wps, wpspin, error, - passphrase_reply-user_data); - + passphrase_reply-service_callback(passphrase_reply-service, + values_received, name, name_len, + identity, passphrase, wps, wpspin, + error, passphrase_reply-user_data); out: g_free(passphrase_reply); } @@ -236,13 +241,21 @@ static void request_input_append_passphrase(DBusMessageIter *iter, } } +struct request_wps_data { + bool peer; +}; + static void request_input_append_wps(DBusMessageIter *iter, void *user_data) { + struct request_wps_data *wps = user_data; const char *str = wpspin; connman_dbus_dict_append_basic(iter, Type, DBUS_TYPE_STRING, str); - str = alternate; + if (wps wps-peer) Since the peer and service pointers are grouped together in a union and therefore share the same space in the struct, won't WPS always become mandatory also for every service? + str = mandatory; + else + str = alternate; connman_dbus_dict_append_basic(iter, Requirement, DBUS_TYPE_STRING, str); } Cheers, Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH 05/16] agent: Provide a function for the Peer RequestPeerAuthorization call
Hi Patrik, +struct request_wps_data { + bool peer; +}; + static void request_input_append_wps(DBusMessageIter *iter, void *user_data) { + struct request_wps_data *wps = user_data; const char *str = wpspin; connman_dbus_dict_append_basic(iter, Type, DBUS_TYPE_STRING, str); - str = alternate; + if (wps wps-peer) Since the peer and service pointers are grouped together in a union and therefore share the same space in the struct, won't WPS always become mandatory also for every service? Indeed. Attached the new version of this patch (my git send-email fails currently, for whatever reason). Tomasz From 111e93054497a2e86cdc79fa63b89dc5e25fb6bf Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka tomasz.burszt...@linux.intel.com Date: Fri, 25 Jul 2014 14:43:54 +0300 Subject: [PATCH 05/16] agent: Provide a function for the Peer RequestPeerAuthorization call This will be used by peer.c when there will be a need to choose between WPS PBC or PIN. This choice will be raised to the user via an agent RequestPeerAuthorization call. --- Removed the union on peer/service src/agent-connman.c | 163 ++-- src/connman.h | 8 +++ 2 files changed, 155 insertions(+), 16 deletions(-) diff --git a/src/agent-connman.c b/src/agent-connman.c index 7502f0f..f3d1bc4 100644 --- a/src/agent-connman.c +++ b/src/agent-connman.c @@ -56,7 +56,12 @@ static bool check_reply_has_dict(DBusMessage *reply) struct request_input_reply { struct connman_service *service; - authentication_cb_t callback; + struct connman_peer *peer; + union { + authentication_cb_t service_callback; + peer_wps_cb_t peer_callback; + }; + bool wps_requested; void *user_data; }; @@ -151,12 +156,10 @@ static void request_input_passphrase_reply(DBusMessage *reply, void *user_data) } done: - passphrase_reply-callback(passphrase_reply-service, values_received, -name, name_len, -identity, passphrase, -wps, wpspin, error, -passphrase_reply-user_data); - + passphrase_reply-service_callback(passphrase_reply-service, + values_received, name, name_len, + identity, passphrase, wps, wpspin, + error, passphrase_reply-user_data); out: g_free(passphrase_reply); } @@ -236,13 +239,21 @@ static void request_input_append_passphrase(DBusMessageIter *iter, } } +struct request_wps_data { + bool peer; +}; + static void request_input_append_wps(DBusMessageIter *iter, void *user_data) { + struct request_wps_data *wps = user_data; const char *str = wpspin; connman_dbus_dict_append_basic(iter, Type, DBUS_TYPE_STRING, str); - str = alternate; + if (wps wps-peer) + str = mandatory; + else + str = alternate; connman_dbus_dict_append_basic(iter, Requirement, DBUS_TYPE_STRING, str); } @@ -399,12 +410,10 @@ static void request_input_login_reply(DBusMessage *reply, void *user_data) } done: - username_password_reply-callback(username_password_reply-service, - values_received, NULL, 0, - username, password, - FALSE, NULL, error, - username_password_reply-user_data); - + username_password_reply-service_callback( + username_password_reply-service, values_received, + NULL, 0, username, password, FALSE, NULL, error, + username_password_reply-user_data); out: g_free(username_password_reply); } @@ -477,7 +486,7 @@ int __connman_agent_request_passphrase_input(struct connman_service *service, } passphrase_reply-service = service; - passphrase_reply-callback = callback; + passphrase_reply-service_callback = callback; passphrase_reply-user_data = user_data; err = connman_agent_queue_message(service, message, @@ -542,7 +551,7 @@ int __connman_agent_request_login_input(struct connman_service *service, } username_password_reply-service = service; - username_password_reply-callback = callback; + username_password_reply-service_callback = callback; username_password_reply-user_data = user_data; err = connman_agent_queue_message(service, message, @@ -654,3 +663,125 @@ int __connman_agent_report_peer_error(struct connman_peer *peer, return connman_agent_report_error_full(peer, path, ReportPeerError, error, callback, dbus_sender, user_data); } + +static void request_peer_authorization_reply(DBusMessage *reply, + void *user_data) +{ + struct request_input_reply *auth_reply = user_data; + DBusMessageIter iter, dict; + const char *error = NULL; + bool choice_done = false; + char *wpspin = NULL; + char *key; + + if (!reply) + goto out; + + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + error = dbus_message_get_error_name(reply); + goto done; + } + + if (!check_reply_has_dict(reply)) + goto done; + + dbus_message_iter_init(reply, iter); + dbus_message_iter_recurse(iter, dict); + while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry, value; + + dbus_message_iter_recurse(dict, entry); +
Issue while recovering
Hi, I mentioned this briefly on the mailinglist. If connman dies of some reason (crash or I kill it), my init system will restart connman. But connman fails to connect again (well it works if I also make sure wpa_supplicant is restarted). When connman dies I'm connected to wifi, which I expect to be reconnected to when connman is restarted. A while after the restart my application gets tired and issues a scan, then connman returns NoCarrier, then the application start to toggle power on wifi... Before connman gets killed rfkill output looks like this: # rfkill list 0: phy0: wlan Soft blocked: no Hard blocked: no Afterwards: # rfkill list 0: phy0: wlan Soft blocked: yes Hard blocked: no And the log output: http://pastebin.com/ecyTPitc Since wpa_supplicant and connman runs in different processes I'm not completely sure if the order is correct if events happens in the two processes at the same second. Thanks, Richard ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH v2 00/16] Peer's Agent API support
On Wed, 2014-08-06 at 13:29 +0300, Tomasz Bursztyka wrote: v2: fixed an issue around wps pin handling This patch-set add the Peer's Agent API documentation and implementation. However, this only works in the context when ConnMan initiates the connection and not the other way round (which requires quite a bit of work to get it) All patches applied, v2 for 05/16. Thanks! Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: [PATCH] peer: Switch to relevant states when disconnecting
On Wed, 2014-08-06 at 13:30 +0300, Tomasz Bursztyka wrote: Let's announce first we are disconnecting and, once done, that we are idling again. Applied, thanks! Patrik ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: Background scan issues?
Hi again, I've tested the issue thoroughly, and it still persists when using connman. I get wifi network disconnects and delays with or without bgs enabled. Here's the log for connman and wpa_supplicant: http://pastebin.com/PTfixCF8 http://pastebin.com/NgWsLap6 The timestamps of the wpa_suplicant log seem wrong. Apparently all the info is dumped just when wpa_supplicant is stopped. In contrast, with the following wpa_supplicant configuration instantiated by netctl I don't have any issues: http://pastebin.com/p4xsS5ri Several Arch Linux users seem to be having the same issue. Thanks, A. On Tue, Aug 5, 2014 at 12:00 PM, Gammel Holte gammel.ho...@gmail.com wrote: OK, thanks, I will let you know the outcome of this. -A. On Tue, Aug 5, 2014 at 10:50 AM, Tomasz Bursztyka tomasz.burszt...@linux.intel.com wrote: Hi, Thanks, what's the exact syntax for this? I had tried it before posting but nothing got fixed. Is it like this? [General] BackgroundScanning=false Looks like it. Don't know if it affects the parsing having spaces on both sides of the =. Get the connman+wpa_supplicant logs if the problem still exists. Tomasz ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
ieee8021x connection issue
All, I am trying to establish a connection with an AP that identifies as a ieee8021x access point. When I issue the connect call to it, it does not make a request to my agent for the username/passphrase (ie, it doesn't call the RequestInput method), and returns with a GError of {domain = 78, code = 32, message = 0x41002360 Invalid arguments}. Now I can make a connection to an access point utilizing an AP that is a managed_psk access point, and it also makes the correct call to the RequestInput agent method. Why would it not make the connect call correctly for the ieee801x but correctly for the managed_psk AP? I'm running an unpatched version of 1.21 Tom ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
Re: Issue while recovering
Hi again, I did a new log dump with some more debug. Also I fixed my application, it was hammering connman a bit too much. Actually connman returns already powered WHILE powering on, so my app believed in connman and started to scan. Now it only listens to property changes, so it wont start to scan too early, which makes the log much cleaner The issue remains, the interface get stuck disabled... power off and on cures the situation. This new paste shows this: http://pastebin.com/qAH0mHjR Until it was powered off rfkill was like this: rfkill list 0: phy0: wlan Soft blocked: no Hard blocked: no ifconfig only showed the lo interface, so the interface was down After I powered off: # rfkill list 0: phy0: wlan Soft blocked: yes Hard blocked: no ifconfig still considered the interface down After power on again: # rfkill list 0: phy0: wlan Soft blocked: no Hard blocked: no And ifconfig considered the interface up. //Richard On Wed, Aug 6, 2014 at 2:50 PM, Richard Röjfors richard.rojf...@gmail.com wrote: Hi, I mentioned this briefly on the mailinglist. If connman dies of some reason (crash or I kill it), my init system will restart connman. But connman fails to connect again (well it works if I also make sure wpa_supplicant is restarted). When connman dies I'm connected to wifi, which I expect to be reconnected to when connman is restarted. A while after the restart my application gets tired and issues a scan, then connman returns NoCarrier, then the application start to toggle power on wifi... Before connman gets killed rfkill output looks like this: # rfkill list 0: phy0: wlan Soft blocked: no Hard blocked: no Afterwards: # rfkill list 0: phy0: wlan Soft blocked: yes Hard blocked: no And the log output: http://pastebin.com/ecyTPitc Since wpa_supplicant and connman runs in different processes I'm not completely sure if the order is correct if events happens in the two processes at the same second. Thanks, Richard ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
RE: ieee8021x connection issue
Hate to reply to my own mail stupid mistake on my part. Hadn't set up the configuration file for the ieee8021x connection. Sorry for the distraction. Tom -Original Message- From: connman [mailto:connman-boun...@connman.net] On Behalf Of Thomas Green Sent: Wednesday, August 06, 2014 9:31 AM To: connman@connman.net Subject: ieee8021x connection issue All, I am trying to establish a connection with an AP that identifies as a ieee8021x access point. When I issue the connect call to it, it does not make a request to my agent for the username/passphrase (ie, it doesn't call the RequestInput method), and returns with a GError of {domain = 78, code = 32, message = 0x41002360 Invalid arguments}. Now I can make a connection to an access point utilizing an AP that is a managed_psk access point, and it also makes the correct call to the RequestInput agent method. Why would it not make the connect call correctly for the ieee801x but correctly for the managed_psk AP? I'm running an unpatched version of 1.21 Tom ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH] Properly parse uncompressed DNS names
Hi, When parsing uncompressed DNS names the end pointer only must be updated when encountering a compressed label, or after parsing all uncompressed labels. Otherwise parse_rr() will interpret the second uncompressed label as resource record header instead of the bits behind the name terminating NUL byte. The attached patch addresses that issue. Thank you, Mathias -- Join us at Qt Developer Days 2014 - October 6 - 8 at BCC, Berlin Mathias Hasselmann | mathias.hasselm...@kdab.com | Software Engineer KDAB (Deutschland) GmbHCo KG, a KDAB Group company Tel. Germany +49-30-521325470, Sweden (HQ) +46-563-540090 KDAB - Qt Experts - Platform-independent software solutions From ce2bede8c2de445e99262bb66b9effedbf186ced Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann mathias.hasselm...@kdab.com Date: Wed, 6 Aug 2014 21:47:37 +0200 Subject: [PATCH] Properly parse uncompressed DNS names When parsing uncompressed DNS names the end pointer only must be updated when encountering a compressed label, or after parsing all uncompressed labels. Otherwise parse_rr() will interpret the second uncompressed label as resource record header instead of the bits behind the name terminating NUL byte. --- src/dnsproxy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dnsproxy.c b/src/dnsproxy.c index 7232b98..2de8bdc 100644 --- a/src/dnsproxy.c +++ b/src/dnsproxy.c @@ -880,14 +880,14 @@ static int get_name(int counter, p += label_len + 1; - if (!*end) -*end = p; - if (p = max) return -ENOBUFS; } } + if (!*end) + *end = p + 1; + return 0; } -- 1.9.1 smime.p7s Description: S/MIME Cryptographic Signature ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH] gsupplicant: Fix the issue about get an invalid group structure
From: Guoqiang Liu guoqiang@archermind.com peer-groups store group's path, not GSupplicantGroup, so get it from group_mapping --- gsupplicant/supplicant.c |6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index 94bf611..a76ee2e 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -1116,7 +1116,11 @@ bool g_supplicant_peer_is_client(GSupplicantPeer *peer) return false; for (list = peer-groups; list; list = list-next) { - group = list-data; + const char *path = list-data; + + group = g_hash_table_lookup(group_mapping, path); + if (!group) + continue; if (group-role != G_SUPPLICANT_GROUP_ROLE_CLIENT || group-orig_interface != peer-interface) -- 1.7.9.5 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH] wifi: Remove useless return statement in interface_added
Just code cleaning a meaningless return on the last line of a void function. --- plugins/wifi.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/wifi.c b/plugins/wifi.c index 70eb661..861304b 100644 --- a/plugins/wifi.c +++ b/plugins/wifi.c @@ -1828,9 +1828,6 @@ static void interface_added(GSupplicantInterface *interface) } connman_device_set_powered(wifi-device, true); - - if (wifi-tethering) - return; } static bool is_idle(struct wifi_data *wifi) -- 1.9.1 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH] gsupplicant: Do P2P detection after interface property load
When interface was already created in wpa_supplicant, p2p detection was failing. Thus, calling p2p detection after interface property has been signaled fixes this detection failure. --- gsupplicant/supplicant.c | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index b8ad5a2..715bac2 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -1874,6 +1874,15 @@ static void interface_bss_removed(DBusMessageIter *iter, void *user_data) g_hash_table_remove(interface-network_table, network-group); } +static void interface_detect_p2p_support(GSupplicantInterface *interface) +{ + SUPPLICANT_DBG(p2p detect); + if (interface-mode_capa G_SUPPLICANT_CAPABILITY_MODE_P2P) { + interface-p2p_support = true; + callback_p2p_support(interface); + } +} + static void interface_property(const char *key, DBusMessageIter *iter, void *user_data) { @@ -1909,6 +1918,7 @@ static void interface_property(const char *key, DBusMessageIter *iter, if (g_strcmp0(key, Capabilities) == 0) { supplicant_dbus_property_foreach(iter, interface_capability, interface); + interface_detect_p2p_support(interface); } else if (g_strcmp0(key, State) == 0) { const char *str = NULL; @@ -2075,22 +2085,13 @@ static void interface_added(DBusMessageIter *iter, void *user_data) supplicant_dbus_property_foreach(iter, interface_property, interface); interface_property(NULL, NULL, interface); - goto p2p_detection; + return; } supplicant_dbus_property_get_all(path, SUPPLICANT_INTERFACE .Interface, interface_property, interface, interface); - -p2p_detection: - - if (interface-mode_capa G_SUPPLICANT_CAPABILITY_MODE_P2P) { - interface-p2p_support = true; - callback_p2p_support(interface); - } - - return; } static void interface_removed(DBusMessageIter *iter, void *user_data) -- 1.9.1 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman
[PATCH] gsupplicant: Remove duplicated interface assignment on GroupStarted
Removing a previous interface assignment, although the correct value was assigned at last. --- gsupplicant/supplicant.c | 1 - 1 file changed, 1 deletion(-) diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c index b8ad5a2..61cbd93 100644 --- a/gsupplicant/supplicant.c +++ b/gsupplicant/supplicant.c @@ -2844,7 +2844,6 @@ static void signal_group_started(const char *path, DBusMessageIter *iter) if (!group) return; - group-interface = interface; group-interface = g_interface; group-orig_interface = interface; group-path = g_strdup(data.group_obj_path); -- 1.9.1 ___ connman mailing list connman@connman.net https://lists.connman.net/mailman/listinfo/connman