Send connman mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
https://lists.01.org/mailman/listinfo/connman
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."
Today's Topics:
1. [PATCH v2] timeserver: Filter out non working IP addresses
(Daniel Wagner)
2. Re: [PATCH] gsupplicant: Switch to different BSSID of same
SSID in case of signal bss removed (Daniel Wagner)
3. Re: [PATCH 1/1] service: Sanitize hostname and domainname
(Daniel Wagner)
4. [PATCH v3 0/4] Timeserver fixes (Daniel Wagner)
5. [PATCH v3 1/4] ntp: Set timeout value (Daniel Wagner)
6. [PATCH v3 2/4] timeserver: Only start once timeserver search
(Daniel Wagner)
7. [PATCH v3 3/4] ntp: Do not log errors if send request fails
(Daniel Wagner)
8. [PATCH v3 4/4] timeserver: Refactor select next time server
code (Daniel Wagner)
----------------------------------------------------------------------
Message: 1
Date: Sat, 16 Mar 2019 14:34:37 +0100
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Subject: [PATCH v2] timeserver: Filter out non working IP addresses
Message-ID: <[email protected]>
The DHCP server or the user might specify an IP address which can't be
reached via the current interface configuration. For example the
timeserver is only reachable via IPv6 but the interface is setup in
IPv4 only.
Whenever we select the next timeserver to probe we also check if
an IP is reachable.
The user is also able to provide timeserver as hostname. Therefore,
refactor timerserver_sync_start() and resolv_conf() to use
sync_next(). With this change we always select the next time server in
sync_next().
As side effect, we start to carefully check if a lookup is already
running, because __connman_timeserver_sync() could be called several
times for one service. For example once from the service state
machine (indicate state) and once from the DHCP code path.
This was reported by the libreelec community:
connmand[421]: Time request for server 2001:3a0:0:2006::87:123 failed
(101/Network is unreachable)
connmand[421]: Time request for server 2a02:2a50:6::123 failed (101/Network is
unreachable)
connmand[421]: Time request for server 2406:2000:e4:a1f::1000 failed
(101/Network is unreachable)
---
Hi,
With this change all the selection of the next server happens in one
place (sync_next()). Also this time I avoid dropping any entries in
timeserver_sync_start(). Instead, all entries will be processed in
sync_next(). That is far less aggressive then v1. Let's see if this helps.
@chewitt: let me know if this one works better.
Thanks,
Daniel
src/timeserver.c | 102 ++++++++++++++++++++++++-----------------------
1 file changed, 53 insertions(+), 49 deletions(-)
diff --git a/src/timeserver.c b/src/timeserver.c
index 657b782985f4..bfc3c1658977 100644
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -34,6 +34,7 @@
#define TS_RECHECK_INTERVAL 7200
+static struct connman_service *ts_service;
static GSList *timeservers_list = NULL;
static GSList *ts_list = NULL;
static char *ts_current = NULL;
@@ -94,6 +95,26 @@ static char **load_timeservers(void)
return servers;
}
+static bool is_timerserver_reachable(struct connman_service *service,
+ const char *host)
+{
+ bool connected;
+ int family;
+
+ family = connman_inet_check_ipaddress(host);
+ connected = __connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+ if (family == AF_INET && connected)
+ return true;
+
+ connected = __connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+ if (family == AF_INET6 && connected)
+ return true;
+
+ return false;
+}
+
static void resolv_result(GResolvResultStatus status, char **results,
gpointer user_data)
{
@@ -103,24 +124,21 @@ static void resolv_result(GResolvResultStatus status,
char **results,
if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
if (results) {
- for (i = 0; results[i]; i++) {
+ /* prepend the results in reverse order */
+
+ for (i = 0; results[i]; i++)
+ /* count */;
+ i--;
+
+ for (; i >= 0; i--) {
DBG("result[%d]: %s", i, results[i]);
- if (i == 0)
- continue;
ts_list = __connman_timeserver_add_list(
- ts_list, results[i]);
+ ts_list, results[i]);
}
-
- DBG("Using timeserver %s", results[0]);
-
- __connman_ntp_start(results[0], ntp_callback, NULL);
-
- return;
}
}
- /* If resolving fails, move to the next server */
sync_next();
}
@@ -142,23 +160,7 @@ static void timeserver_sync_start(void)
}
ts_list = g_slist_reverse(ts_list);
- ts_current = ts_list->data;
-
- ts_list = g_slist_delete_link(ts_list, ts_list);
-
- /* if it's an IP, directly query it. */
- if (connman_inet_check_ipaddress(ts_current) > 0) {
- DBG("Using timeserver %s", ts_current);
-
- __connman_ntp_start(ts_current, ntp_callback, NULL);
-
- return;
- }
-
- DBG("Resolving timeserver %s", ts_current);
-
- resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
- resolv_result, NULL);
+ sync_next();
}
static gboolean timeserver_sync_restart(gpointer user_data)
@@ -175,7 +177,7 @@ static gboolean timeserver_sync_restart(gpointer user_data)
* none of the server did work we start over with the first server
* with a backoff.
*/
-static void sync_next()
+static void sync_next(void)
{
if (ts_current) {
g_free(ts_current);
@@ -184,32 +186,28 @@ static void sync_next()
__connman_ntp_stop();
- /* Get the 1st server in the list */
- if (!ts_list) {
- DBG("No timeserver could be used, restart probing in 5
seconds");
-
- ts_backoff_id = g_timeout_add_seconds(5,
- timeserver_sync_restart, NULL);
- return;
- }
-
- ts_current = ts_list->data;
+ while (ts_list) {
+ ts_current = ts_list->data;
+ ts_list = g_slist_delete_link(ts_list, ts_list);
- ts_list = g_slist_delete_link(ts_list, ts_list);
+ /* if it's an IP, directly query it. */
+ if (connman_inet_check_ipaddress(ts_current) > 0) {
+ if (!is_timerserver_reachable(ts_service, ts_current))
+ continue;
- /* if it's an IP, directly query it. */
- if (connman_inet_check_ipaddress(ts_current) > 0) {
- DBG("Using timeserver %s", ts_current);
-
- __connman_ntp_start(ts_current, ntp_callback, NULL);
+ DBG("Using timeserver %s", ts_current);
+ __connman_ntp_start(ts_current, ntp_callback, NULL);
+ return;
+ }
+ DBG("Resolving timeserver %s", ts_current);
+ resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
+ resolv_result, NULL);
return;
}
- DBG("Resolving timeserver %s", ts_current);
-
- resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
- resolv_result, NULL);
+ DBG("No timeserver could be used, restart probing in 5 seconds");
+ ts_backoff_id = g_timeout_add_seconds(5, timeserver_sync_restart, NULL);
}
GSList *__connman_timeserver_add_list(GSList *server_list,
@@ -370,6 +368,9 @@ int __connman_timeserver_sync(struct connman_service
*default_service)
if (!service)
return -EINVAL;
+ if (service == ts_service)
+ return -EALREADY;
+
if (!resolv)
return 0;
/*
@@ -408,6 +409,7 @@ int __connman_timeserver_sync(struct connman_service
*default_service)
ts_recheck_enable();
+ ts_service = service;
timeserver_sync_start();
return 0;
@@ -459,6 +461,8 @@ static void timeserver_stop(void)
{
DBG(" ");
+ ts_service = NULL;
+
if (resolv) {
g_resolv_unref(resolv);
resolv = NULL;
--
2.20.1
------------------------------
Message: 2
Date: Sat, 16 Mar 2019 15:03:23 +0100
From: Daniel Wagner <[email protected]>
To: Rahul Jain <[email protected]>
Cc: "[email protected]" <[email protected]>, AMIT KUMAR JAISWAL
<[email protected]>
Subject: Re: [PATCH] gsupplicant: Switch to different BSSID of same
SSID in case of signal bss removed
Message-ID: <20190316140323.mqn5yg36terz7onf@beryllium>
Content-Type: text/plain; charset=iso-8859-1
Hi Rahul,
On Fri, Mar 15, 2019 at 03:05:21PM +0530, Rahul Jain wrote:
> [PATCH]?gsupplicant:?Switch?to?different?BSSID?of?same?SSID?in?case?of?
> signal?bss?removed
> ?
> [Cause]?2?AP?(same?name?&?security)?was?used?in?testing,?2.4?Ghz?and?5Ghz.
> TV?was?connected?with?2.4?Ghz?AP.?Now?Tester?switch?off(soft)?that
> AP?from?router?webpage.Now?supplicant?send?bss_removed?signal?to
> connman?for?that?AP?and?tester?switch?on?5GHz?AP?from?router?page.
> But?within?few?time,?supplicant?again?send?bss_removed?signal?to
> connman(as?AP?was?switch?of?from?router?web?page),?so?took?few?time
> to?go?down.?When?connman?get?bss_added?signal?for?2.4?AP,?then?make
> addNetwork?connection?request?to?supplicant,?but?that?time,?2.4?AP
> was?already?switched?off.So?supplicant?keeps?to?trying?to?find?that
> AP.?Meanwhile?supplicant?sent?bss_added?signal?for?5Ghz?AP?as?that
> was?switched?on.?Now?in?connman?under?same?AP?2?BSSID?is?there.?After
> few?retry?&?time?(~10?milisecond)?during?connection?retry?with?2.4,
> when?supplicant?did?not?found?that?2.4?AP,?then?send?bss_removed?signal
> to?connman?and?connman?remove?that?bSS?from?g_supplicant?network?hash
> table.?After?120?sec?connman?connect_timeout?hit?and?connection?with
> 2.4?AP?disconnected.?Now?connman?again?try?connection?with?2.4?AP?and
> send?addNetwork?for?2.4?though?supplicant?send?bss_removed.?This?is?an
> issue,?whereas?connman?should?try?connection?with?5ghz?there.
Nice catch!
Though the commit message is a bit hard to read. Also, I think you
could shorten it a bit.
"""
Teach ConnMan to select the next BSSID when two APs (e.g. 2.4 GHz
and 5 GHz) with the same SSID and securcity configuration are
available.
Currently when one AP disapears ConnMan will retry to connect to the
old AP point even though there is another matching BSSID available.
So when wpa_supplicant sends a remove signal we find a matching BSSID
and use it even when it's not from the same AP.
"""
Something like this should be okay.
> [Solution]
> After?few?retry?&?time?(~10?milisecond)?during?connection?retry?with
> 2.4,?when?supplicant?did?not?found?that?2.4?AP,?then?supplicant
> send?bss_removed?signal?to?connman?and?connman?remove?that?bSS?from
> g_supplicant?network?hash?table?and?should?update?next?available?BSS
> i.e.?5Ghz?as?best_bss?and?notify?wifi.c:network_change,?so?that
> same?will?be?upated?in?connman_network.
> So?when?next?request?for?addNetwork?will?go?to?supplicant?that?will?be?for
> 5Ghz.
> ?
> ---
> ?gsupplicant/supplicant.c?|?6?++++++
> ?1?file?changed,?6?insertions(+)
> ?
> diff?--git?a/gsupplicant/supplicant.c?b/gsupplicant/supplicant.c
> index?da8c52e..623e424?100644
> ---?a/gsupplicant/supplicant.c
> +++?b/gsupplicant/supplicant.c
> @@?-2206,6?+2206,7?@@?static?void?interface_bss_removed(DBusMessageIter?*iter,?void?*user_data)
> ?????????GSupplicantNetwork?*network;
> ?????????struct?g_supplicant_bss?*bss?=?NULL;
> ?????????const?char?*path?=?NULL;
> +????????bool?isCurrentNetworkBss=false;
Please no CamelCasing here. Also add spaces around the '='.
> ?
> ?????????dbus_message_iter_get_basic(iter,?&path);
> ?????????if?(!path)
> @@?-2219,6?+2220,7?@@?static?void?interface_bss_removed(DBusMessageIter?*iter,?void?*user_data)
> ?????????if?(network->best_bss?==?bss)?{
> ?????????????????network->best_bss?=?NULL;
> ?????????????????network->signal?=?BSS_UNKNOWN_STRENGTH;
> +????????????????isCurrentNetworkBss=true;
> ?????????}
> ?
> ?????????g_hash_table_remove(bss_mapping,?path);
> @@?-2230,6?+2232,10?@@?static?void?interface_bss_removed(DBusMessageIter?*iter,?void?*user_data)
> ?
> ?????????if?(g_hash_table_size(network->bss_table)?==?0)
> ?????????????????g_hash_table_remove(interface->network_table,?network->group);
> +????????else?{
> +?????????????????if(isCurrentNetworkBss?&&?network->best_bss)
Also here add space betweeen the if and (.
Thanks,
Daniel
------------------------------
Message: 3
Date: Sat, 16 Mar 2019 15:14:51 +0100
From: Daniel Wagner <[email protected]>
To: Henrik Persson <[email protected]>
Cc: "[email protected]" <[email protected]>, Konrad Beckmann
<[email protected]>
Subject: Re: [PATCH 1/1] service: Sanitize hostname and domainname
Message-ID: <20190316141451.n44ja57kt2upo53m@beryllium>
Content-Type: text/plain; charset=us-ascii
Hi Henrik,
On Fri, Mar 15, 2019 at 01:57:10PM +0000, Henrik Persson wrote:
> From: Henrik Persson <[email protected]>
>
> If a DHCP ACK is received with non-UTF-8 data set as hostname or
> domain-name option connman will crash on a D-Bus assert.
Who is doing something like this? Everyone knows, ASCII only! :)
Nice catch!
> + if (g_str_is_ascii(hostname))
I am fine with the patch. In order to use g_str_is_ascii() glib 2.40
is needed. ConnMan requests only 2.28 at this point which was released
around 2011. I think it's save to assume no one still uses this really
old version of glib.
Glib 2.40 is not too young either (released in March 2014), so we
don't force everyone to update to a very recent version.
Please add this update to this patch as well. So we have documented
why we update the dependency.
Thanks,
Daniel
------------------------------
Message: 4
Date: Sat, 16 Mar 2019 16:11:32 +0100
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Subject: [PATCH v3 0/4] Timeserver fixes
Message-ID: <[email protected]>
v2 revealed some more issues with the retry logic. This version is now
getting closer to a working time server selection code.
Happy testing!
Daniel Wagner (4):
ntp: Set timeout value
timeserver: Only start once timeserver search
ntp: Do not log errors if send request fails
timeserver: Refactor select next time server code
src/ntp.c | 19 +++---------
src/timeserver.c | 81 ++++++++++++++++++------------------------------
2 files changed, 35 insertions(+), 65 deletions(-)
--
2.20.1
------------------------------
Message: 5
Date: Sat, 16 Mar 2019 16:11:33 +0100
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Subject: [PATCH v3 1/4] ntp: Set timeout value
Message-ID: <[email protected]>
Commit b1e8230f19cf ("ntp: Move variables into data struct") forgot to
store the current timeout value.
connmand[428]: ../src/ntp.c:start_ntp() server 5.32.10.108 family 2
connmand[428]: ../src/ntp.c:send_timeout() send timeout 0 (retries 0)
connmand[428]: ../src/ntp.c:send_timeout() send timeout 0 (retries 1)
connmand[428]: ../src/ntp.c:send_timeout() send timeout 0 (retries 2)
connmand[428]: ../src/ntp.c:send_timeout() send timeout 0 (retries 3)
---
src/ntp.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/ntp.c b/src/ntp.c
index 807431a4754d..89e3b8db114f 100644
--- a/src/ntp.c
+++ b/src/ntp.c
@@ -231,6 +231,7 @@ static void send_packet(struct ntp_data *nd, struct
sockaddr *server,
* trying another server.
*/
+ nd->timeout = timeout;
nd->timeout_id = g_timeout_add_seconds(timeout, send_timeout, nd);
}
--
2.20.1
------------------------------
Message: 6
Date: Sat, 16 Mar 2019 16:11:34 +0100
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Subject: [PATCH v3 2/4] timeserver: Only start once timeserver search
Message-ID: <[email protected]>
Check if a lookup is already running and avoid NTP races.
__connman_timeserver_sync() could be called several times for one
service. For example once from the service state machine (indicate
state) and once from the DHCP code path.
---
src/timeserver.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/timeserver.c b/src/timeserver.c
index 657b782985f4..c2bfa47bca95 100644
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -370,6 +370,9 @@ int __connman_timeserver_sync(struct connman_service
*default_service)
if (!service)
return -EINVAL;
+ if (service == ts_service)
+ return -EALREADY;
+
if (!resolv)
return 0;
/*
@@ -408,6 +411,7 @@ int __connman_timeserver_sync(struct connman_service
*default_service)
ts_recheck_enable();
+ ts_service = service;
timeserver_sync_start();
return 0;
@@ -459,6 +463,8 @@ static void timeserver_stop(void)
{
DBG(" ");
+ ts_service = NULL;
+
if (resolv) {
g_resolv_unref(resolv);
resolv = NULL;
--
2.20.1
------------------------------
Message: 7
Date: Sat, 16 Mar 2019 16:11:35 +0100
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Subject: [PATCH v3 3/4] ntp: Do not log errors if send request fails
Message-ID: <[email protected]>
These are not hard failures and the higher level logic just moves one
to try next entry. So there is little point in being loud here.
This was reported by the libreelec community:
connmand[421]: Time request for server 2001:3a0:0:2006::87:123 failed (101/
connmand[421]: Time request for server 2a02:2a50:6::123 failed (101/Network
connmand[421]: Time request for server 2406:2000:e4:a1f::1000 failed (101/N
---
src/ntp.c | 18 +++---------------
1 file changed, 3 insertions(+), 15 deletions(-)
diff --git a/src/ntp.c b/src/ntp.c
index 89e3b8db114f..e7fee22a9d5d 100644
--- a/src/ntp.c
+++ b/src/ntp.c
@@ -193,7 +193,7 @@ static void send_packet(struct ntp_data *nd, struct
sockaddr *server,
size = sizeof(struct sockaddr_in6);
addr = (void *)&nd->timeserver_addr.sin6_addr;
} else {
- connman_error("Family is neither ipv4 nor ipv6");
+ DBG("Family is neither ipv4 nor ipv6");
nd->cb(false, nd->user_data);
return;
}
@@ -206,20 +206,8 @@ static void send_packet(struct ntp_data *nd, struct
sockaddr *server,
len = sendto(nd->transmit_fd, &msg, sizeof(msg), MSG_DONTWAIT,
server, size);
-
- if (len < 0) {
- connman_error("Time request for server %s failed (%d/%s)",
- inet_ntop(server->sa_family, addr, ipaddrstring,
sizeof(ipaddrstring)),
- errno, strerror(errno));
-
- if (errno == ENETUNREACH || errno == EPERM)
- nd->cb(false, nd->user_data);
-
- return;
- }
-
- if (len != sizeof(msg)) {
- connman_error("Broken time request for server %s",
+ if (len < 0 || len != sizeof(msg)) {
+ DBG("Time request for server %s failed",
inet_ntop(server->sa_family, addr, ipaddrstring,
sizeof(ipaddrstring)));
nd->cb(false, nd->user_data);
return;
--
2.20.1
------------------------------
Message: 8
Date: Sat, 16 Mar 2019 16:11:36 +0100
From: Daniel Wagner <[email protected]>
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Subject: [PATCH v3 4/4] timeserver: Refactor select next time server
code
Message-ID: <[email protected]>
Instead having the select next code distributed over several function
move it to sync_next().
---
src/timeserver.c | 75 ++++++++++++++++--------------------------------
1 file changed, 25 insertions(+), 50 deletions(-)
diff --git a/src/timeserver.c b/src/timeserver.c
index c2bfa47bca95..9832c2a5e5db 100644
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -34,6 +34,7 @@
#define TS_RECHECK_INTERVAL 7200
+static struct connman_service *ts_service;
static GSList *timeservers_list = NULL;
static GSList *ts_list = NULL;
static char *ts_current = NULL;
@@ -103,24 +104,21 @@ static void resolv_result(GResolvResultStatus status,
char **results,
if (status == G_RESOLV_RESULT_STATUS_SUCCESS) {
if (results) {
- for (i = 0; results[i]; i++) {
+ /* prepend the results in reverse order */
+
+ for (i = 0; results[i]; i++)
+ /* count */;
+ i--;
+
+ for (; i >= 0; i--) {
DBG("result[%d]: %s", i, results[i]);
- if (i == 0)
- continue;
ts_list = __connman_timeserver_add_list(
- ts_list, results[i]);
+ ts_list, results[i]);
}
-
- DBG("Using timeserver %s", results[0]);
-
- __connman_ntp_start(results[0], ntp_callback, NULL);
-
- return;
}
}
- /* If resolving fails, move to the next server */
sync_next();
}
@@ -142,23 +140,7 @@ static void timeserver_sync_start(void)
}
ts_list = g_slist_reverse(ts_list);
- ts_current = ts_list->data;
-
- ts_list = g_slist_delete_link(ts_list, ts_list);
-
- /* if it's an IP, directly query it. */
- if (connman_inet_check_ipaddress(ts_current) > 0) {
- DBG("Using timeserver %s", ts_current);
-
- __connman_ntp_start(ts_current, ntp_callback, NULL);
-
- return;
- }
-
- DBG("Resolving timeserver %s", ts_current);
-
- resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
- resolv_result, NULL);
+ sync_next();
}
static gboolean timeserver_sync_restart(gpointer user_data)
@@ -175,7 +157,7 @@ static gboolean timeserver_sync_restart(gpointer user_data)
* none of the server did work we start over with the first server
* with a backoff.
*/
-static void sync_next()
+static void sync_next(void)
{
if (ts_current) {
g_free(ts_current);
@@ -184,32 +166,25 @@ static void sync_next()
__connman_ntp_stop();
- /* Get the 1st server in the list */
- if (!ts_list) {
- DBG("No timeserver could be used, restart probing in 5
seconds");
-
- ts_backoff_id = g_timeout_add_seconds(5,
- timeserver_sync_restart, NULL);
- return;
- }
-
- ts_current = ts_list->data;
-
- ts_list = g_slist_delete_link(ts_list, ts_list);
+ while (ts_list) {
+ ts_current = ts_list->data;
+ ts_list = g_slist_delete_link(ts_list, ts_list);
- /* if it's an IP, directly query it. */
- if (connman_inet_check_ipaddress(ts_current) > 0) {
- DBG("Using timeserver %s", ts_current);
-
- __connman_ntp_start(ts_current, ntp_callback, NULL);
+ /* if it's an IP, directly query it. */
+ if (connman_inet_check_ipaddress(ts_current) > 0) {
+ DBG("Using timeserver %s", ts_current);
+ __connman_ntp_start(ts_current, ntp_callback, NULL);
+ return;
+ }
+ DBG("Resolving timeserver %s", ts_current);
+ resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
+ resolv_result, NULL);
return;
}
- DBG("Resolving timeserver %s", ts_current);
-
- resolv_id = g_resolv_lookup_hostname(resolv, ts_current,
- resolv_result, NULL);
+ DBG("No timeserver could be used, restart probing in 5 seconds");
+ ts_backoff_id = g_timeout_add_seconds(5, timeserver_sync_restart, NULL);
}
GSList *__connman_timeserver_add_list(GSList *server_list,
--
2.20.1
------------------------------
Subject: Digest Footer
_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman
------------------------------
End of connman Digest, Vol 41, Issue 18
***************************************