summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xAUTHORS7
-rw-r--r--ChangeLog8
-rw-r--r--Makefile.am7
-rwxr-xr-xREADME13
-rwxr-xr-xacinclude.m44
-rwxr-xr-xclient/agent.c2
-rwxr-xr-xclient/commands.c82
-rwxr-xr-xclient/ins.c22
-rw-r--r--configure.ac113
-rw-r--r--doc/connman.conf.5.in13
-rwxr-xr-xdoc/technology-api.txt7
-rw-r--r--doc/vpn-agent-api.txt13
-rwxr-xr-xdoc/vpn-connection-api.txt13
-rwxr-xr-xgdhcp/client.c15
-rwxr-xr-xgdhcp/gdhcp.h1
-rwxr-xr-xgsupplicant/dbus.c5
-rwxr-xr-xgsupplicant/gsupplicant.h44
-rwxr-xr-xgsupplicant/supplicant.c478
-rwxr-xr-xinclude/device.h3
-rwxr-xr-xinclude/network.h11
-rwxr-xr-xinclude/service.h3
-rwxr-xr-xinclude/setting.h12
-rwxr-xr-xinclude/technology.h9
-rw-r--r--isu/isu.cfg8
-rw-r--r--isu/system-services/connman.service24
-rw-r--r--packaging/connman.spec17
-rwxr-xr-xplugins/bluetooth.c1
-rw-r--r--plugins/ethernet.c6
-rwxr-xr-xplugins/gadget.c1
-rw-r--r--plugins/iwd.c85
-rwxr-xr-xplugins/loopback.c4
-rwxr-xr-xplugins/neard.c4
-rwxr-xr-xplugins/vpn.c17
-rwxr-xr-xplugins/wifi.c651
-rw-r--r--resources/var/lib/connman/settings1
-rwxr-xr-xsrc/agent.c2
-rwxr-xr-xsrc/clock.c26
-rw-r--r--src/config.c6
-rw-r--r--src/connman-robot.conf3
-rw-r--r--src/connman.conf6
-rwxr-xr-xsrc/connman.h17
-rwxr-xr-xsrc/dbus.c2
-rwxr-xr-xsrc/device.c30
-rw-r--r--src/dhcp.c57
-rwxr-xr-xsrc/dnsproxy.c64
-rw-r--r--src/inet.c15
-rwxr-xr-xsrc/ipconfig.c6
-rwxr-xr-xsrc/main.c187
-rwxr-xr-xsrc/main.conf30
-rwxr-xr-xsrc/main_robot.conf16
-rwxr-xr-xsrc/main_tv.conf7
-rwxr-xr-xsrc/manager.c39
-rwxr-xr-xsrc/network.c145
-rwxr-xr-xsrc/ntp.c10
-rw-r--r--src/rtnl.c125
-rwxr-xr-xsrc/service.c815
-rwxr-xr-xsrc/storage.c8
-rw-r--r--src/technology.c111
-rwxr-xr-xsrc/timeserver.c7
-rwxr-xr-xsrc/wispr.c33
-rw-r--r--tools/ip6tables-test.c2
-rwxr-xr-xtools/iptables-test.c2
-rw-r--r--unit/test-iptables.c4
-rwxr-xr-xvpn/plugins/l2tp.c133
-rwxr-xr-xvpn/plugins/openconnect.c85
-rwxr-xr-xvpn/plugins/openvpn.c129
-rwxr-xr-xvpn/plugins/pptp.c127
-rwxr-xr-xvpn/vpn-provider.c488
-rwxr-xr-xvpn/vpn-provider.h4
-rwxr-xr-xvpn/vpn-rtnl.c125
70 files changed, 3434 insertions, 1136 deletions
diff --git a/AUTHORS b/AUTHORS
index 438d45f3..3ed09850 100755
--- a/AUTHORS
+++ b/AUTHORS
@@ -145,7 +145,7 @@ André Draszik <andre.draszik@jci.com>
Chris Novakovic <chris@chrisn.me.uk>
Ryan Schaefer <ryan.schaefer@flukenetworks.com>
Nicolas Cornu <n.cornu@overkiz.com>
-Rahul Jain <rahul.jain@samsung.com
+Rahul Jain <rahul.jain@samsung.com>
Benoît Monin <benoit.monin@gmx.fr>
Jussi Laakkonen <jussi.laakkonen@jolla.com>
Vivien Henriet <v.henriet@overkiz.com>
@@ -171,3 +171,8 @@ Gabriel FORTE <gforte@wyplay.com>
Colin Wee <cwee@tesla.com>
Valery Kashcheev <v.kascheev@omp.ru>
Alyssa Ross <hi@alyssa.is>
+Ariel D'Alessandro <ariel.dalessandro@collabora.com>
+Lukáš Karas <lukas.karas@centrum.cz>
+Michael Nazzareno Trimarchi <michael@amarulasolutions.com>
+Christian Taedcke <christian.taedcke@lemonbeat.com>
+Matthias Gerstner <mgerstner@suse.de>
diff --git a/ChangeLog b/ChangeLog
index 69207d2a..11566a53 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+ver 1.41:
+ Fix issue with RTNL netlink message alignment.
+ Fix issue with dnsproxy and timeout for TCP feature.
+ Fix issue with dnsproxy and busy loop in TCP server.
+ Fix issue with WiFi connection with no passphrase.
+ Add support for wpa_supplicant and WPA3-SAE functionality.
+ Add support for D-Bus ObjectManager interface.
+
ver 1.40:
Fix issue with handling WiFi disconnecting status.
Fix issue with handling WiFi auto-connect and iwd backend.
diff --git a/Makefile.am b/Makefile.am
index e8662e48..9a756a49 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -373,9 +373,7 @@ if TIZEN_EXT_WIFI_MESH
client_connmanctl_SOURCES += client/mesh.c client/mesh.h
endif
-if TIZEN_EXT_INS
client_connmanctl_SOURCES += client/ins.c client/ins.h
-endif
client_connmanctl_LDADD = gdbus/libgdbus-internal.la @DBUS_LIBS@ @GLIB_LIBS@ @DLOG_LIBS@ \
-lreadline -ldl -lncurses
@@ -633,5 +631,10 @@ include/connman/%.h: $(abs_top_srcdir)/include/%.h
$(AM_V_at)$(MKDIR_P) include/connman
$(AM_V_GEN)$(LN_S) $< $@
+isudir = /etc/isu/connman
+isu_DATA = isu/isu.cfg
+isusystemservicedir = /etc/isu/connman/system-services/
+isusystemservice_DATA = isu/system-services/connman.service
+
clean-local:
@$(RM) -rf include/connman $(MANUAL_PAGES)
diff --git a/README b/README
index b8154e67..e3268c82 100755
--- a/README
+++ b/README
@@ -408,8 +408,17 @@ from ipv4.connman.net (for IPv4 connectivity) and ipv6.connman.net
(for IPv6 connectivity). The used URL looks like this
http://ipv{4|6}.connman.net/online/status.html
+When an online check request fails, another one is triggered after a
+longer interval. The intervals follow the square series of numbers
+in a specific range, by default [1, 12], corresponding to the following
+intervals, in seconds: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121 and 144.
+
See connman.conf(5) for the EnableOnlineCheck option, if you need to
disable the feature.
+It is also possible to specify other URLs via OnlineCheckIPv4URL and
+OnlineCheckIPv6URL options.
+The range of intervals between two online check requests can be fine-tuned
+via OnlineCheckInitialInterval and OnlineCheckMaxInterval options.
During the online check procedure, ConnMan will temporarily install
a host route to both the ipv4.connman.net and ipv6.connman.net so that
@@ -453,3 +462,7 @@ send a (empty) message from your email account to
Mailing list archive:
https://lore.kernel.org/connman
+
+IRC:
+ ircs://irc.oftc.net:6697/#connman (for SSL)
+ irc://irc.oftc.net:6667/#connman (for non-SSL)
diff --git a/acinclude.m4 b/acinclude.m4
index 9e8e0dc5..262465d8 100755
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -21,7 +21,9 @@ AC_DEFUN([COMPILER_FLAGS], [
CFLAGS+=" -Wdeclaration-after-statement"
CFLAGS+=" -Wmissing-declarations"
CFLAGS+=" -Wredundant-decls"
- CFLAGS+=" -Wcast-align"
+ if ( $CC -v 2>/dev/null | grep "gcc version" ); then
+ CFLAGS+=" -Wcast-align"
+ fi
CFLAGS="$CFLAGS -DG_DISABLE_DEPRECATED"
fi
])
diff --git a/client/agent.c b/client/agent.c
index 1cad3e03..94ace7cd 100755
--- a/client/agent.c
+++ b/client/agent.c
@@ -100,6 +100,8 @@ static struct agent_input_data vpnagent_input_handler[] = {
request_input_string_return },
{ "OpenConnect.VPNHost", false, "OpenConnect VPN server? ",
request_input_string_return },
+ { "OpenConnect.SecondPassword", false, "VPN one-time password? ",
+ request_input_string_return },
{ "Username", false, "VPN username? ", request_input_string_return },
{ "Password", false, "VPN password? ", request_input_string_return },
{ },
diff --git a/client/commands.c b/client/commands.c
index dab62099..2fd8af54 100755
--- a/client/commands.c
+++ b/client/commands.c
@@ -39,7 +39,7 @@
#include "dbus_helpers.h"
#include "input.h"
#include "services.h"
-#if defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
#include "ins.h"
#endif
#include "tethering.h"
@@ -331,9 +331,9 @@ static int services_list(DBusMessageIter *iter, int errnum, const char *error,
return 0;
}
-#if defined TIZEN_EXT_INS
-static int ins_list(DBusMessageIter *iter, const char *error,
- void *user_data)
+#if defined TIZEN_EXT
+static int ins_list(DBusMessageIter *iter, int errnum,
+ const char *error, void *user_data)
{
char *filter = user_data;
@@ -445,7 +445,7 @@ static int cmd_services(char *args[], int num, struct connman_option *options)
object_properties, path, NULL, NULL);
}
-#if defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
static int cmd_ins(char *args[], int num, struct connman_option *options)
{
char *filter = NULL;
@@ -593,20 +593,23 @@ struct tether_properties {
int ssid_result;
int passphrase_result;
int set_tethering;
+ int freq_result;
};
static int tether_update(struct tether_properties *tether)
{
int ret;
- if (tether->ssid_result == 0 && tether->passphrase_result == 0) {
+ if (tether->ssid_result == 0 && tether->passphrase_result == 0 &&
+ tether->freq_result == 0) {
ret = tether_set("wifi", tether->set_tethering);
g_free(tether);
return ret;
}
if (tether->ssid_result != -EINPROGRESS &&
- tether->passphrase_result != -EINPROGRESS) {
+ tether->passphrase_result != -EINPROGRESS &&
+ tether->freq_result != -EINPROGRESS) {
g_free(tether);
return 0;
}
@@ -646,9 +649,25 @@ static int tether_set_passphrase_return(DBusMessageIter *iter, int errnum,
return tether_update(tether);
}
-static int tether_set_ssid(char *ssid, char *passphrase, int set_tethering)
+static int tether_set_freq_return(DBusMessageIter *iter, int errnum,
+ const char *error, void *user_data)
+{
+ struct tether_properties *tether = user_data;
+
+ if (!error) {
+ fprintf(stdout, "Wifi access point frequency set\n");
+ tether->freq_result = 0;
+ } else {
+ fprintf(stderr, "Error setting wifi frequency: %s\n", error);
+ tether->freq_result = -EINVAL;
+ }
+
+ return tether_update(tether);
+}
+
+static int tether_set_ssid(char *ssid, char *passphrase, int set_tethering, int freq)
{
- struct tether_properties *tether = g_new(struct tether_properties, 1);
+ struct tether_properties *tether = g_new0(struct tether_properties, 1);
tether->set_tethering = set_tethering;
@@ -664,12 +683,24 @@ static int tether_set_ssid(char *ssid, char *passphrase, int set_tethering)
tether_set_passphrase_return, tether,
"TetheringPassphrase", DBUS_TYPE_STRING, &passphrase);
+ if (freq > 0) {
+ tether->freq_result =__connmanctl_dbus_set_property(connection,
+ "/net/connman/technology/wifi",
+ "net.connman.Technology",
+ tether_set_freq_return, tether,
+ "TetheringFreq", DBUS_TYPE_INT32, &freq);
+ }
+
if (tether->ssid_result != -EINPROGRESS &&
- tether->passphrase_result != -EINPROGRESS) {
+ tether->passphrase_result != -EINPROGRESS &&
+ tether->freq_result != -EINPROGRESS) {
g_free(tether);
return -ENXIO;
}
+#if defined TIZEN_EXT
+ g_free(tether);
+#endif
return -EINPROGRESS;
}
@@ -1253,24 +1284,30 @@ static int cmd_tether(char *args[], int num, struct connman_option *options)
if (num < 3)
return -EINVAL;
- passphrase = args[num - 1];
- ssid = args[num - 2];
-
set_tethering = parse_boolean(args[2]);
if (strcmp(args[1], "wifi") == 0) {
+ int freq = 0;
- if (num > 5)
+ if (num > 6)
return -E2BIG;
- if (num == 5 && set_tethering == -1)
+ if (num >= 5 && set_tethering == -1)
return -EINVAL;
if (num == 4)
set_tethering = -1;
+ if (num == 6) {
+ freq = atoi(args[num - 1]);
+ num --;
+ }
+
+ passphrase = args[num - 1];
+ ssid = args[num - 2];
+
if (num > 3)
- return tether_set_ssid(ssid, passphrase, set_tethering);
+ return tether_set_ssid(ssid, passphrase, set_tethering, freq);
}
if (num > 3)
@@ -2040,7 +2077,6 @@ static void monitor_del(char *interface)
int i;
char *rule;
-
for (i = 0; monitor[i].interface; i++) {
if (g_strcmp0(interface, monitor[i].interface) == 0) {
if (monitor[i].enabled == false)
@@ -2426,7 +2462,6 @@ static int session_connect_cb(DBusMessageIter *iter, int errnum,
return -EINPROGRESS;
}
-
static int session_connect(void)
{
return __connmanctl_dbus_method_call(connection, "net.connman",
@@ -3008,7 +3043,7 @@ static struct connman_option service_options[] = {
{ NULL, }
};
-#if defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
static struct connman_option ins_options[] = {
{"all", 'a', ""},
{"filter-ssid", 's', "ssid"},
@@ -3018,7 +3053,12 @@ static struct connman_option ins_options[] = {
#endif
static struct connman_option config_options[] = {
+#if defined TIZEN_EXT
+ {"nameservers", 'n', "ipv4.manual|ipv4.dhcp|ipv6.manual|ipv6.dhcp\n"
+ "\t\t\t<dns1> [<dns2>] [<dns3>]"},
+#else
{"nameservers", 'n', "<dns1> [<dns2>] [<dns3>]"},
+#endif
{"timeservers", 't', "<ntp1> [<ntp2>] [...]"},
{"domains", 'd', "<domain1> [<domain2>] [...]"},
{"mdns", 'm', "yes|no"},
@@ -3459,7 +3499,7 @@ static const struct {
lookup_mesh },
#endif
{ "tether", "<technology> on|off\n"
- " wifi [on|off] <ssid> <passphrase> ",
+ " wifi [on|off] <ssid> <passphrase> [<freq>] ",
NULL, cmd_tether,
"Enable, disable tethering, set SSID and passphrase for wifi",
lookup_tether },
@@ -3467,7 +3507,7 @@ static const struct {
"Display tethering clients", NULL },
{ "services", "[<service>]", service_options, cmd_services,
"Display services", lookup_service_arg },
-#if defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
{ "ins", NULL, ins_options, cmd_ins,
"Display intelligent network selection", NULL },
#endif
diff --git a/client/ins.c b/client/ins.c
index 6403f610..929c6a93 100755
--- a/client/ins.c
+++ b/client/ins.c
@@ -95,7 +95,7 @@ static GSList *get_bssid_list(DBusMessageIter *iter, struct ins_info_s *ins_info
if (strcmp(property, "BSSID") == 0) {
bssid_info = g_try_new0(struct bssid_info_s, 1);
if (!bssid_info)
- continue;
+ break;
dbus_message_iter_next(&entry);
dbus_message_iter_recurse(&entry, &val);
@@ -157,19 +157,19 @@ static void print_ins_info(int *rank, struct ins_info_s *ins_info,
char *path, char *filter, DBusMessageIter *iter)
{
char *name = "";
- char *security;
+ char *security = "";
char *str = NULL;
int count = 0;
char *property;
- unsigned char strength;
- unsigned int frequency;
- int score_INS;
- int score_last_user_selection;
- int score_last_connected;
- int score_frequency;
- int score_security_priority;
- int score_internet_connection;
- int score_strength;
+ unsigned char strength = 0;
+ unsigned int frequency = 0;
+ int score_INS = 0;
+ int score_last_user_selection = 0;
+ int score_last_connected = 0;
+ int score_frequency = 0;
+ int score_security_priority = 0;
+ int score_internet_connection = 0;
+ int score_strength = 0;
GSList *bssid_list = NULL;
DBusMessageIter entry, val, dict;
diff --git a/configure.ac b/configure.ac
index 220d62b8..9a2f65d5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
AC_PREREQ(2.60)
-AC_INIT(connman, 1.40)
+AC_INIT(connman, 1.41)
AC_CONFIG_MACRO_DIR([m4])
@@ -36,14 +36,14 @@ AC_PROG_LIBTOOL
gl_CONFIGMAKE_PREP
-AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization],
+AC_ARG_ENABLE(optimization, AS_HELP_STRING([--disable-optimization],
[disable code optimization through compiler]), [
if (test "${enableval}" = "no"); then
CFLAGS="$CFLAGS -O0 -U_FORTIFY_SOURCE"
fi
])
-AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],
+AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],
[enable compiling with debugging information]), [
if (test "${enableval}" = "yes" &&
test "${ac_cv_prog_cc_g}" = "yes"); then
@@ -51,7 +51,7 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],
fi
])
-AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie],
+AC_ARG_ENABLE(pie, AS_HELP_STRING([--enable-pie],
[enable position independent executables flag]), [
if (test "${enableval}" = "yes" &&
test "${ac_cv_prog_cc_pie}" = "yes"); then
@@ -61,54 +61,47 @@ AC_ARG_ENABLE(pie, AC_HELP_STRING([--enable-pie],
])
AC_ARG_ENABLE(hh2serial-gps,
- AC_HELP_STRING([--enable-hh2serial-gps], [enable hh2serial GPS support]),
+ AS_HELP_STRING([--enable-hh2serial-gps], [enable hh2serial GPS support]),
[enable_hh2serial_gps=${enableval}], [enable_hh2serial_gps="no"])
AM_CONDITIONAL(HH2SERIAL_GPS, test "${enable_hh2serial_gps}" != "no")
AM_CONDITIONAL(HH2SERIAL_GPS_BUILTIN, test "${enable_hh2serial_gps}" = "builtin")
AC_ARG_ENABLE(telephony,
- AC_HELP_STRING([--enable-telephony], [enable Telephony support]),
+ AS_HELP_STRING([--enable-telephony], [enable Telephony support]),
[enable_telephony=${enableval}], [enable_telephony="yes"])
AM_CONDITIONAL(TELEPHONY, test "${enable_telephony}" != "no")
AM_CONDITIONAL(TELEPHONY_BUILTIN, test "${enable_telephony}" = "builtin")
AC_ARG_ENABLE(tizen-ext,
- AC_HELP_STRING([--enable-tizen-ext], [enable TIZEN extensions]),
+ AS_HELP_STRING([--enable-tizen-ext], [enable TIZEN extensions]),
[if (test "${enableval}" = "yes"); then
CFLAGS="$CFLAGS -DTIZEN_EXT"
LIBS="$LIBS -lsmack"
fi])
AM_CONDITIONAL(TIZEN_EXT, test "${enable-tizen-ext}" != "no")
-AC_ARG_ENABLE(tizen-ext-ins,
- AC_HELP_STRING([--enable-tizen-ext-ins], [enable TIZEN extensions for INS]),
- [if (test "${enableval}" = "yes"); then
- CFLAGS="$CFLAGS -DTIZEN_EXT_INS"
- fi])
-AM_CONDITIONAL(TIZEN_EXT_INS, test "${enable_tizen_ext_ins}" != "no")
-
AC_ARG_ENABLE(tizen-ext-wifi-mesh,
- AC_HELP_STRING([--enable-tizen-ext-wifi-mesh], [enable TIZEN extensions for Wi-Fi Mesh]),
+ AS_HELP_STRING([--enable-tizen-ext-wifi-mesh], [enable TIZEN extensions for Wi-Fi Mesh]),
[CFLAGS="$CFLAGS -DTIZEN_EXT_WIFI_MESH"], [enable_tizen_ext_wifi_mesh="no"])
AM_CONDITIONAL(TIZEN_EXT_WIFI_MESH, test "${enable_tizen_ext_wifi_mesh}" != "no")
AC_ARG_ENABLE(tizen-ext-eap-on-ethernet,
- AC_HELP_STRING([--enable-tizen-ext-eap-on-ethernet], [enable TIZEN extensions for EAP on Ethernet]),
+ AS_HELP_STRING([--enable-tizen-ext-eap-on-ethernet], [enable TIZEN extensions for EAP on Ethernet]),
[CFLAGS="$CFLAGS -DTIZEN_EXT_EAP_ON_ETHERNET"], [enable_tizen_ext_eap_on_ethernet="no"])
AM_CONDITIONAL(TIZEN_EXT_EAP_ON_ETHERNET, test "${enable_tizen_ext_eap_on_ethernet}" != "no")
AC_ARG_ENABLE(tizen-maintain-online,
- AC_HELP_STRING([--enable-tizen-maintain-online], [enable TIZEN extensions]),
+ AS_HELP_STRING([--enable-tizen-maintain-online], [enable TIZEN extensions]),
[if (test "${enableval}" = "yes"); then
CFLAGS="$CFLAGS -DTIZEN_MAINTAIN_ONLINE"
LIBS="$LIBS -lsmack"
fi])
-AC_ARG_WITH(openconnect, AC_HELP_STRING([--with-openconnect=PROGRAM],
+AC_ARG_WITH(openconnect, AS_HELP_STRING([--with-openconnect=PROGRAM],
[specify location of openconnect binary]), [path_openconnect=${withval}])
AC_ARG_ENABLE(openconnect,
- AC_HELP_STRING([--enable-openconnect], [enable openconnect support]),
+ AS_HELP_STRING([--enable-openconnect], [enable openconnect support]),
[enable_openconnect=${enableval}], [enable_openconnect="no"])
if (test "${enable_openconnect}" != "no"); then
if (test -z "${path_openconnect}"); then
@@ -126,11 +119,11 @@ fi
AM_CONDITIONAL(OPENCONNECT, test "${enable_openconnect}" != "no")
AM_CONDITIONAL(OPENCONNECT_BUILTIN, test "${enable_openconnect}" = "builtin")
-AC_ARG_WITH(openvpn, AC_HELP_STRING([--with-openvpn=PROGRAM],
+AC_ARG_WITH(openvpn, AS_HELP_STRING([--with-openvpn=PROGRAM],
[specify location of openvpn binary]), [path_openvpn=${withval}])
AC_ARG_ENABLE(openvpn,
- AC_HELP_STRING([--enable-openvpn], [enable openvpn support]),
+ AS_HELP_STRING([--enable-openvpn], [enable openvpn support]),
[enable_openvpn=${enableval}], [enable_openvpn="no"])
if (test "${enable_openvpn}" != "no"); then
if (test -z "${path_openvpn}"); then
@@ -146,11 +139,11 @@ fi
AM_CONDITIONAL(OPENVPN, test "${enable_openvpn}" != "no")
AM_CONDITIONAL(OPENVPN_BUILTIN, test "${enable_openvpn}" = "builtin")
-AC_ARG_WITH(ipsec, AC_HELP_STRING([--with-ipsec=PROGRAM],
+AC_ARG_WITH(ipsec, AS_HELP_STRING([--with-ipsec=PROGRAM],
[specify location of ipsec binary]), [path_ipsec=${withval}])
AC_ARG_ENABLE(ipsec,
- AC_HELP_STRING([--enable-ipsec], [enable ipsec support]),
+ AS_HELP_STRING([--enable-ipsec], [enable ipsec support]),
[enable_ipsec=${enableval}], [enable_ipsec="no"])
if (test "${enable_ipsec}" != "no"); then
PKG_CHECK_MODULES(GIO, gio-2.0 >= 2.28, dummy=yes,
@@ -170,11 +163,11 @@ fi
AM_CONDITIONAL(IPSEC, test "${enable_ipsec}" != "no")
AM_CONDITIONAL(IPSEC_BUILTIN, test "${enable_ipsec}" = "builtin")
-AC_ARG_WITH(vpnc, AC_HELP_STRING([--with-vpnc=PROGRAM],
+AC_ARG_WITH(vpnc, AS_HELP_STRING([--with-vpnc=PROGRAM],
[specify location of vpnc binary]), [path_vpnc=${withval}])
AC_ARG_ENABLE(vpnc,
- AC_HELP_STRING([--enable-vpnc], [enable vpnc support]),
+ AS_HELP_STRING([--enable-vpnc], [enable vpnc support]),
[enable_vpnc=${enableval}], [enable_vpnc="no"])
if (test "${enable_vpnc}" != "no"); then
if (test -z "${path_vpnc}"); then
@@ -190,11 +183,11 @@ fi
AM_CONDITIONAL(VPNC, test "${enable_vpnc}" != "no")
AM_CONDITIONAL(VPNC_BUILTIN, test "${enable_vpnc}" = "builtin")
-AC_ARG_WITH(l2tp, AC_HELP_STRING([--with-l2tp=PROGRAM],
+AC_ARG_WITH(l2tp, AS_HELP_STRING([--with-l2tp=PROGRAM],
[specify location of l2tp binary]), [path_l2tp=${withval}])
AC_ARG_ENABLE(l2tp,
- AC_HELP_STRING([--enable-l2tp], [enable l2tp support]),
+ AS_HELP_STRING([--enable-l2tp], [enable l2tp support]),
[enable_l2tp=${enableval}], [enable_l2tp="no"])
if (test "${enable_l2tp}" != "no"); then
if (test -z "${path_pppd}"); then
@@ -215,11 +208,11 @@ fi
AM_CONDITIONAL(L2TP, test "${enable_l2tp}" != "no")
AM_CONDITIONAL(L2TP_BUILTIN, test "${enable_l2tp}" = "builtin")
-AC_ARG_WITH(pptp, AC_HELP_STRING([--with-pptp=PROGRAM],
+AC_ARG_WITH(pptp, AS_HELP_STRING([--with-pptp=PROGRAM],
[specify location of pptp binary]), [path_pptp=${withval}])
AC_ARG_ENABLE(pptp,
- AC_HELP_STRING([--enable-pptp], [enable pptp support]),
+ AS_HELP_STRING([--enable-pptp], [enable pptp support]),
[enable_pptp=${enableval}], [enable_pptp="no"])
if (test "${enable_pptp}" != "no"); then
if (test -z "${path_pppd}"); then
@@ -258,23 +251,23 @@ AC_CHECK_FUNC(signalfd, dummy=yes,
AC_CHECK_LIB(dl, dlopen, dummy=yes,
AC_MSG_ERROR(dynamic linking loader is required))
-AC_ARG_ENABLE(iospm, AC_HELP_STRING([--enable-iospm],
+AC_ARG_ENABLE(iospm, AS_HELP_STRING([--enable-iospm],
[enable Intel OSPM support]), [enable_iospm=${enableval}])
AM_CONDITIONAL(IOSPM, test "${enable_iospm}" = "yes")
AC_ARG_ENABLE(tist,
- AC_HELP_STRING([--enable-tist], [enable TI Shared Transport support]),
+ AS_HELP_STRING([--enable-tist], [enable TI Shared Transport support]),
[enable_tist=${enableval}], [enable_tist="no"])
AM_CONDITIONAL(TIST, test "${enable_tist}" != "no")
AM_CONDITIONAL(TIST_BUILTIN, test "${enable_tist}" = "builtin")
AC_ARG_ENABLE(session-policy-local,
- AC_HELP_STRING([--enable-session-policy-local], [enable local file Session policy configuration support]),
+ AS_HELP_STRING([--enable-session-policy-local], [enable local file Session policy configuration support]),
[enable_session_policy_local=${enableval}], [enable_session_policy_local="no"])
AM_CONDITIONAL(SESSION_POLICY_LOCAL, test "${enable_session_policy_local}" != "no")
AM_CONDITIONAL(SESSION_POLICY_LOCAL_BUILTIN, test "${enable_session_policy_local}" = "builtin")
-AC_ARG_WITH(stats-max-file-size, AC_HELP_STRING([--with-stats-max-file-size=SIZE],
+AC_ARG_WITH(stats-max-file-size, AS_HELP_STRING([--with-stats-max-file-size=SIZE],
[Maximal size of a statistics round robin file]),
[stats_max_file_size=${withval}])
@@ -315,7 +308,7 @@ PKG_CHECK_MODULES(DLOG, dlog, dummy=yes,
AC_SUBST(DLOG_CFLAGS)
AC_SUBST(DLOG_LIBS)
-AC_ARG_WITH(dbusconfdir, AC_HELP_STRING([--with-dbusconfdir=PATH],
+AC_ARG_WITH(dbusconfdir, AS_HELP_STRING([--with-dbusconfdir=PATH],
[path to D-Bus config directory]), [path_dbusconf=${withval}],
[path_dbusconf="`$PKG_CONFIG --variable=sysconfdir dbus-1`"])
if (test -z "${path_dbusconf}"); then
@@ -325,7 +318,7 @@ else
fi
AC_SUBST(DBUS_CONFDIR)
-AC_ARG_WITH(dbusdatadir, AC_HELP_STRING([--with-dbusdatadir=PATH],
+AC_ARG_WITH(dbusdatadir, AS_HELP_STRING([--with-dbusdatadir=PATH],
[path to D-Bus data directory]), [path_dbusdata=${withval}],
[path_dbusdata="`$PKG_CONFIG --variable=datadir dbus-1`"])
if (test -z "${path_dbusdata}"); then
@@ -335,7 +328,7 @@ else
fi
AC_SUBST(DBUS_DATADIR)
-AC_ARG_WITH([systemdunitdir], AC_HELP_STRING([--with-systemdunitdir=DIR],
+AC_ARG_WITH([systemdunitdir], AS_HELP_STRING([--with-systemdunitdir=DIR],
[path to systemd service directory]), [path_systemdunit=${withval}],
[path_systemdunit="`$PKG_CONFIG --variable=systemdsystemunitdir systemd`"])
if (test -n "${path_systemdunit}"); then
@@ -344,7 +337,7 @@ if (test -n "${path_systemdunit}"); then
fi
AM_CONDITIONAL(SYSTEMD, test -n "${path_systemdunit}")
-AC_ARG_WITH([tmpfilesdir], AC_HELP_STRING([--with-tmpfilesdir=DIR],
+AC_ARG_WITH([tmpfilesdir], AS_HELP_STRING([--with-tmpfilesdir=DIR],
[path to systemd tmpfiles.d directory]), [path_tmpfiles=${withval}],
[path_tmpfiles="`$PKG_CONFIG --variable=tmpfilesdir systemd`"])
if (test -n "${path_tmpfiles}"); then
@@ -352,7 +345,7 @@ if (test -n "${path_tmpfiles}"); then
AC_SUBST(SYSTEMD_TMPFILESDIR)
fi
-AC_ARG_WITH(firewall, AC_HELP_STRING([--with-firewall=TYPE],
+AC_ARG_WITH(firewall, AS_HELP_STRING([--with-firewall=TYPE],
[specify which firewall type is used iptables or nftables [default=iptables]]),
[firewall_type=${withval}],
[firewall_type="iptables"])
@@ -390,16 +383,16 @@ if (test "${firewall_type}" = "nftables"); then
fi
AM_CONDITIONAL(NFTABLES, test "${found_nftables}" != "no")
-AC_ARG_ENABLE(test, AC_HELP_STRING([--enable-test],
+AC_ARG_ENABLE(test, AS_HELP_STRING([--enable-test],
[enable test/example scripts]), [enable_test=${enableval}])
AM_CONDITIONAL(TEST, test "${enable_test}" = "yes")
-AC_ARG_ENABLE(nmcompat, AC_HELP_STRING([--enable-nmcompat],
+AC_ARG_ENABLE(nmcompat, AS_HELP_STRING([--enable-nmcompat],
[enable Network Manager support]),
[enable_nmcompat=${enableval}], [enable_nmcompat="no"])
AM_CONDITIONAL(NMCOMPAT, test "${enable_nmcompat}" != "no")
-AC_ARG_ENABLE(polkit, AC_HELP_STRING([--enable-polkit],
+AC_ARG_ENABLE(polkit, AS_HELP_STRING([--enable-polkit],
[enable PolicyKit support]),
[enable_polkit=${enableval}], [enable_polkit="no"])
if (test "${enable_polkit}" != "no"); then
@@ -412,83 +405,83 @@ if (test "${enable_polkit}" != "no"); then
fi
AM_CONDITIONAL(POLKIT, test "${enable_polkit}" != "no")
-AC_ARG_ENABLE(selinux, AC_HELP_STRING([--enable-selinux],
+AC_ARG_ENABLE(selinux, AS_HELP_STRING([--enable-selinux],
[enable selinux support]),
[enable_selinux=${enableval}], [enable_selinux="no"])
AM_CONDITIONAL(SELINUX, test "${enable_selinux}" != "no")
-AC_ARG_ENABLE(loopback, AC_HELP_STRING([--disable-loopback],
+AC_ARG_ENABLE(loopback, AS_HELP_STRING([--disable-loopback],
[disable loopback support]),
[enable_loopback=${enableval}])
AM_CONDITIONAL(LOOPBACK, test "${enable_loopback}" != "no")
-AC_ARG_ENABLE(ethernet, AC_HELP_STRING([--disable-ethernet],
+AC_ARG_ENABLE(ethernet, AS_HELP_STRING([--disable-ethernet],
[disable Ethernet support]),
[enable_ethernet=${enableval}])
AM_CONDITIONAL(ETHERNET, test "${enable_ethernet}" != "no")
-AC_ARG_ENABLE(wireguard, AC_HELP_STRING([--disable-wireguard],
+AC_ARG_ENABLE(wireguard, AS_HELP_STRING([--disable-wireguard],
[disable Wireguard support]),
[enable_wireguard=${enableval}])
AM_CONDITIONAL(WIREGUARD, test "${enable_wireguard}" != "no")
AM_CONDITIONAL(WIREGUARD_BUILTIN, test "${enable_wireguard}" = "builtin")
-AC_ARG_ENABLE(gadget, AC_HELP_STRING([--disable-gadget],
+AC_ARG_ENABLE(gadget, AS_HELP_STRING([--disable-gadget],
[disable USB Gadget support]),
[enable_gadget=${enableval}])
AM_CONDITIONAL(GADGET, test "${enable_gadget}" != "no")
-AC_ARG_ENABLE(wifi, AC_HELP_STRING([--disable-wifi],
+AC_ARG_ENABLE(wifi, AS_HELP_STRING([--disable-wifi],
[disable WiFi support]),
[enable_wifi=${enableval}])
AM_CONDITIONAL(WIFI, test "${enable_wifi}" != "no")
-AC_ARG_ENABLE(iwd, AC_HELP_STRING([--enable-iwd],
+AC_ARG_ENABLE(iwd, AS_HELP_STRING([--enable-iwd],
[enable iwd support]),
[enable_iwd=${enableval}])
AM_CONDITIONAL(IWD, test "${enable_iwd}" = "yes")
-AC_ARG_ENABLE(bluetooth, AC_HELP_STRING([--disable-bluetooth],
+AC_ARG_ENABLE(bluetooth, AS_HELP_STRING([--disable-bluetooth],
[disable Bluetooth support]),
[enable_bluetooth=${enableval}])
AM_CONDITIONAL(BLUETOOTH, test "${enable_bluetooth}" != "no")
-AC_ARG_ENABLE(ofono, AC_HELP_STRING([--disable-ofono],
+AC_ARG_ENABLE(ofono, AS_HELP_STRING([--disable-ofono],
[disable oFono support]),
[enable_ofono=${enableval}])
AM_CONDITIONAL(OFONO, test "${enable_ofono}" != "no")
-AC_ARG_ENABLE(dundee, AC_HELP_STRING([--disable-dundee],
+AC_ARG_ENABLE(dundee, AS_HELP_STRING([--disable-dundee],
[disable dundee support (Bluetooth DUN)]),
[enable_dundee=${enableval}])
AM_CONDITIONAL(DUNDEE, test "${enable_dundee}" != "no")
-AC_ARG_ENABLE(pacrunner, AC_HELP_STRING([--disable-pacrunner],
+AC_ARG_ENABLE(pacrunner, AS_HELP_STRING([--disable-pacrunner],
[disable PACrunner support]),
[enable_pacrunner=${enableval}])
AM_CONDITIONAL(PACRUNNER, test "${enable_pacrunner}" != "no")
-AC_ARG_ENABLE(neard, AC_HELP_STRING([--disable-neard],
+AC_ARG_ENABLE(neard, AS_HELP_STRING([--disable-neard],
[disable Neard support]),
[enable_neard=${enableval}])
AM_CONDITIONAL(NEARD, test "${enable_neard}" != "no")
-AC_ARG_ENABLE(wispr, AC_HELP_STRING([--disable-wispr],
+AC_ARG_ENABLE(wispr, AS_HELP_STRING([--disable-wispr],
[disable WISPr support]),
[enable_wispr=${enableval}])
AM_CONDITIONAL(WISPR, test "${enable_wispr}" != "no")
-AC_ARG_ENABLE(backtrace, AC_HELP_STRING([--disable-backtrace],
+AC_ARG_ENABLE(backtrace, AS_HELP_STRING([--disable-backtrace],
[disable backtrace support]),
[enable_backtrace=${enableval}])
AM_CONDITIONAL(BACKTRACE, test "${enable_backtrace}" != "no")
-AC_ARG_ENABLE(tools, AC_HELP_STRING([--disable-tools],
+AC_ARG_ENABLE(tools, AS_HELP_STRING([--disable-tools],
[disable testing tools]),
[enable_tools=${enableval}])
AM_CONDITIONAL(TOOLS, test "${enable_tools}" != "no")
-AC_ARG_ENABLE(stats, AC_HELP_STRING([--disable-stats],
+AC_ARG_ENABLE(stats, AS_HELP_STRING([--disable-stats],
[disable statistics round robin file generation]),
[enable_stats=${enableval}])
AM_CONDITIONAL(STATS, test "${enable_stats}" != "no")
@@ -507,7 +500,7 @@ fi
AC_SUBST(IPTABLES_SAVE)
AC_SUBST(IP6TABLES_SAVE)
-AC_ARG_ENABLE(client, AC_HELP_STRING([--disable-client],
+AC_ARG_ENABLE(client, AS_HELP_STRING([--disable-client],
[disable command line client]),
[enable_client=${enableval}])
AM_CONDITIONAL(CLIENT, test "${enable_client}" != "no")
@@ -535,7 +528,7 @@ if (test "${enable_wifi}" != "no"); then
$PATH:/bin:/usr/bin)
fi
-AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--disable-datafiles],
+AC_ARG_ENABLE(datafiles, AS_HELP_STRING([--disable-datafiles],
[don't install configuration and data files]),
[enable_datafiles=${enableval}])
AM_CONDITIONAL(DATAFILES, test "${enable_datafiles}" != "no")
@@ -554,7 +547,7 @@ AM_CONDITIONAL(VPN, test "${enable_openconnect}" != "no" -o \
"${enable_wireguard}" != "no")
AC_MSG_CHECKING(which DNS backend to use)
-AC_ARG_WITH(dns-backend, AC_HELP_STRING([--with-dns-backend=TYPE],
+AC_ARG_WITH(dns-backend, AS_HELP_STRING([--with-dns-backend=TYPE],
[specify which DNS backend to use: internal or systemd-resolved [default=internal]]),
[dns_backend=${withval}],
[dns_backend="internal"])
diff --git a/doc/connman.conf.5.in b/doc/connman.conf.5.in
index 2e06b3ef..82cceb72 100644
--- a/doc/connman.conf.5.in
+++ b/doc/connman.conf.5.in
@@ -167,13 +167,16 @@ transitioned to ONLINE state.
If this setting is false, the default service will remain in READY state.
Default value is true.
.TP
+.BI OnlineCheckIPv4URL= url, OnlineCheckIPv6URL= url
+Urls (IPv4 and IPv6 respectively) used during the online status check.
+Please refer to the README for more detailed information.
+Default values are http://ipv4.connman.net/online/status.html and
+http://ipv6.connman.net/online/status.html respectively.
+.TP
.BI OnlineCheckInitialInterval= secs, OnlineCheckMaxInterval= secs
Range of intervals between two online check requests.
-When an online check request fails, another one is triggered after a
-longer interval. The intervals follow the power of two series of numbers
-between OnlineCheckInitialInterval and OnlineCheckMaxInterval.
-Default range is [1, 12], corresponding to the following intervals, in
-seconds: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121 and 144.
+Please refer to the README for more detailed information.
+Default values are 1 and 12 respectively.
.TP
.BI EnableOnlineToReadyTransition=true\ \fR|\fB\ false
WARNING: Experimental feature!!!
diff --git a/doc/technology-api.txt b/doc/technology-api.txt
index f22e9b29..cdf30396 100755
--- a/doc/technology-api.txt
+++ b/doc/technology-api.txt
@@ -100,3 +100,10 @@ Properties boolean Powered [readwrite]
This property is only valid for the WiFi technology,
and is then mapped to the WPA pre-shared key clients
will have to use in order to establish a connection.
+
+ int TetheringFreq [readwrite]
+
+ The tethering access point frequency
+
+ This property is only valid for the WiFi technology and it's
+ optional. Default frequency is 2412 Mhz.
diff --git a/doc/vpn-agent-api.txt b/doc/vpn-agent-api.txt
index ffa6fadd..ecc8faaa 100644
--- a/doc/vpn-agent-api.txt
+++ b/doc/vpn-agent-api.txt
@@ -85,6 +85,10 @@ Fields string Username
Return the OpenConnect cookie value that is used for
authenticating the VPN session.
+ string OpenConnect.Group
+
+ Choose authentication login group.
+
string OpenConnect.PKCSClientCert
Informational field containing a PKCS#1/PKCS#8/PKCS#12
@@ -96,12 +100,21 @@ Fields string Username
Password for decrypting PKCS#8/PKCS#12 client
certificate.
+ string OpenConnect.SecondPassword
+
+ Second factor password for authentication.
+
string OpenConnect.ServerCert
Return the OpenConnect server hash used to identify
the final server after possible web authentication
logins, selections and redirections.
+ boolean OpenConnect.UseSecondPassword
+
+ Indicates that second factor password is used
+ for selected authentication group.
+
string OpenConnect.VPNHost
Return the final VPN server to use after possible
diff --git a/doc/vpn-connection-api.txt b/doc/vpn-connection-api.txt
index 6e6293e4..2d3e0078 100755
--- a/doc/vpn-connection-api.txt
+++ b/doc/vpn-connection-api.txt
@@ -235,6 +235,19 @@ Properties string State [readonly]
The VPN server activated route. These routes
are pushed to connman by VPN server.
+ string AuthErrorLimit
+
+ This value defines the amount of authentication errors
+ that are allowed before informing VPN agent to clear
+ the credentials in case there was a previous successful
+ VPN connection made within one hour. This is to be used
+ with providers that allow only one login from one
+ account at a time to prevent clearing of credentials
+ when networks are rapidly changed. This value is used
+ as an integer and if unset this default to "1" for all
+ except OpenVPN that uses value "10". Setting value "0"
+ disables the feature for the provider.
+
There can be other properties also but as the VPN
technologies are so different, they have different
kind of options that they need, so not all options
diff --git a/gdhcp/client.c b/gdhcp/client.c
index cc0379ec..905cecf2 100755
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -52,10 +52,11 @@
#if defined TIZEN_EXT
#define REQUEST_TIMEOUT 1
+#define REQUEST_RETRIES 14
#else
#define REQUEST_TIMEOUT 5
-#endif
#define REQUEST_RETRIES 3
+#endif
#if defined TIZEN_EXT
#define DISCOVER_TIMEOUT_WIFI 1
@@ -2432,6 +2433,9 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
dhcp_client->retry_times = 0;
option = dhcp_get_option(&packet, pkt_len, DHCP_SERVER_ID);
+ if (!option)
+ return TRUE;
+
dhcp_client->server_ip = get_be32(option);
dhcp_client->requested_ip = ntohl(packet.yiaddr);
@@ -2497,6 +2501,8 @@ static gboolean listener_event(GIOChannel *channel, GIOCondition condition,
if (dhcp_client->state == REBOOTING) {
option = dhcp_get_option(&packet, pkt_len,
DHCP_SERVER_ID);
+ if (!option)
+ return TRUE;
dhcp_client->server_ip = get_be32(option);
}
@@ -3130,6 +3136,13 @@ int g_dhcp_client_get_index(GDHCPClient *dhcp_client)
return dhcp_client->ifindex;
}
+#if defined TIZEN_EXT
+char *g_dhcp_client_get_interface(GDHCPClient *dhcp_client)
+{
+ return dhcp_client->interface;
+}
+#endif
+
char *g_dhcp_client_get_server_address(GDHCPClient *dhcp_client)
{
if (!dhcp_client)
diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h
index d9944882..041ae81b 100755
--- a/gdhcp/gdhcp.h
+++ b/gdhcp/gdhcp.h
@@ -157,6 +157,7 @@ char *g_dhcp_client_get_server_address(GDHCPClient *client);
#if defined TIZEN_EXT
int g_dhcp_client_get_dhcp_lease_duration(GDHCPClient *client);
+char *g_dhcp_client_get_interface(GDHCPClient *dhcp_client);
#endif
char *g_dhcp_client_get_address(GDHCPClient *client);
diff --git a/gsupplicant/dbus.c b/gsupplicant/dbus.c
index 9ad8e080..73c9acec 100755
--- a/gsupplicant/dbus.c
+++ b/gsupplicant/dbus.c
@@ -497,7 +497,10 @@ int supplicant_dbus_method_call(const char *path,
if (!path || !interface || !method)
return -EINVAL;
-
+#if defined TIZEN_EXT
+ if (strlen(path) == 0)
+ return -EINVAL;
+#endif
method_call = g_try_new0(struct method_call_data, 1);
if (!method_call)
return -ENOMEM;
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h
index 0823a394..61b63dd6 100755
--- a/gsupplicant/gsupplicant.h
+++ b/gsupplicant/gsupplicant.h
@@ -71,6 +71,7 @@ extern "C" {
#define G_SUPPLICANT_KEYMGMT_WPS (1 << 9)
#if defined TIZEN_EXT
#define G_SUPPLICANT_KEYMGMT_SAE (1 << 10)
+#define G_SUPPLICANT_KEYMGMT_FT_SAE (1 << 11)
#define G_SUPPLICANT_KEYMGMT_OWE (1 << 22)
#define G_SUPPLICANT_KEYMGMT_DPP (1 << 23)
#endif
@@ -127,6 +128,7 @@ typedef enum {
G_SUPPLICANT_SECURITY_SAE,
G_SUPPLICANT_SECURITY_OWE,
G_SUPPLICANT_SECURITY_DPP,
+ G_SUPPLICANT_SECURITY_PSK_SHA256,
#endif
} GSupplicantSecurity;
@@ -187,6 +189,12 @@ typedef enum {
} GSupplicantINSPreferredFreq;
#endif
+typedef enum {
+ G_SUPPLICANT_MFP_NONE,
+ G_SUPPLICANT_MFP_OPTIONAL,
+ G_SUPPLICANT_MFP_REQUIRED,
+} GSupplicantMfpOptions;
+
struct _GSupplicantSSID {
#if defined TIZEN_EXT
void *ssid;
@@ -224,12 +232,16 @@ struct _GSupplicantSSID {
GSupplicantEapKeymgmt eap_keymgmt;
const char *phase1;
const char *pac_file;
- uint16_t ieee80211w;
unsigned int keymgmt;
const char *connector;
const char *c_sign_key;
const char *net_access_key;
+ bool is_passphrase_alloc;
+ bool is_connector_alloc;
+ bool is_c_sign_key_alloc;
+ bool is_net_access_key_alloc;
#endif
+ GSupplicantMfpOptions ieee80211w;
};
typedef struct _GSupplicantSSID GSupplicantSSID;
@@ -281,6 +293,10 @@ struct _GSupplicantP2PServiceParams {
typedef struct _GSupplicantP2PServiceParams GSupplicantP2PServiceParams;
#if defined TIZEN_EXT
+#define WIFI_BSSID_STR_LEN 18
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
#define WIFI_BSSID_LEN_MAX 6
struct g_connman_bssids {
@@ -289,14 +305,13 @@ struct g_connman_bssids {
uint16_t frequency;
uint16_t assoc_reject_cnt;
bool is_last_connected;
+ unsigned int est_throughput;
int score_snr;
-#if defined TIZEN_EXT_INS
int score_last_connected_bssid;
int score_assoc_reject;
int score_frequency;
int score_strength;
int score_est_throughput;
-#endif
int ins_score;
};
#endif
@@ -326,7 +341,8 @@ typedef void (*GSupplicantInterfaceCallback) (int result,
#if defined TIZEN_EXT
typedef void (*GSupplicantMaxSpeedCallback) (int result, int maxspeed,
- int strength, int snr, void *user_data);
+ int strength, int snr, void *user_data,
+ unsigned int est_throughput);
#endif
void g_supplicant_interface_cancel(GSupplicantInterface *interface);
@@ -395,6 +411,11 @@ int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
int g_supplicant_interface_set_bss_expiration_age(GSupplicantInterface *interface,
unsigned int bss_expiration_age);
+#if defined TIZEN_EXT
+void g_supplicant_interface_remove_network(GSupplicantInterface *interface,
+ GSupplicantSSID *ssid);
+#endif
+
int g_supplicant_interface_set_apscan(GSupplicantInterface *interface,
unsigned int ap_scan);
@@ -404,6 +425,7 @@ void *g_supplicant_interface_get_data(GSupplicantInterface *interface);
const char *g_supplicant_interface_get_ifname(GSupplicantInterface *interface);
#if defined TIZEN_EXT
bool g_supplicant_interface_get_is_5_0_ghz_supported(GSupplicantInterface *interface);
+bool g_supplicant_interface_get_is_6_0_ghz_supported(GSupplicantInterface *interface);
unsigned char *g_supplicant_interface_get_add_network_bssid(GSupplicantInterface *interface);
typedef void (*GSupplicantMacPolicyCallback) (int result, unsigned int policy, void *user_data);
@@ -530,16 +552,18 @@ dbus_bool_t g_supplicant_network_get_transition_mode(GSupplicantNetwork *network
const unsigned char *g_supplicant_network_get_transition_mode_bssid(GSupplicantNetwork *network);
const void *g_supplicant_network_get_transition_mode_ssid(GSupplicantNetwork *network,
unsigned int *transition_mode_ssid_len);
+void g_supplicant_network_set_signal(GSupplicantNetwork *network, int signal);
+void g_supplicant_network_set_bss_signal(GSupplicantNetwork *network,
+ int signal, int snr);
+GSupplicantNetwork *g_supplicant_interface_get_network(GSupplicantInterface *interface,
+ const char *group);
-#endif
-#if defined TIZEN_EXT
void g_supplicant_network_set_last_connected_bssid(GSupplicantNetwork *network, const unsigned char *bssid);
const unsigned char *g_supplicant_network_get_last_connected_bssid(GSupplicantNetwork *network);
void g_supplicant_network_update_assoc_reject(GSupplicantInterface *interface,
GSupplicantNetwork *network);
GHashTable *g_supplicant_network_get_assoc_reject_table(GSupplicantNetwork *network);
-GSupplicantNetwork *g_supplicant_interface_get_network(GSupplicantInterface *interface,
- const char *group);
+GHashTable *g_supplicant_network_clone_assoc_reject_table(GSupplicantNetwork *network);
#endif
#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
@@ -598,12 +622,12 @@ struct _GSupplicantCallbacks {
typedef struct _GSupplicantCallbacks GSupplicantCallbacks;
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
void g_supplicant_set_ins_settings(GSupplicantINSPreferredFreq preferred_freq_bssid,
bool last_connected_bssid, bool assoc_reject, bool signal_bssid,
unsigned int preferred_freq_bssid_score, unsigned int last_connected_bssid_score,
unsigned int assoc_reject_score, int signal_level3_5ghz, int signal_level3_24ghz);
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
void g_supplicant_replace_config_file(const char *ifname, const char *config_file);
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c
index 5d1eb8f8..8329975b 100755
--- a/gsupplicant/supplicant.c
+++ b/gsupplicant/supplicant.c
@@ -122,6 +122,7 @@ static struct strvalmap keymgmt_map[] = {
{ "wps", G_SUPPLICANT_KEYMGMT_WPS },
#if defined TIZEN_EXT
{ "sae", G_SUPPLICANT_KEYMGMT_SAE },
+ { "ft-sae", G_SUPPLICANT_KEYMGMT_FT_SAE },
{ "owe", G_SUPPLICANT_KEYMGMT_OWE },
{ "dpp", G_SUPPLICANT_KEYMGMT_DPP },
#endif
@@ -174,7 +175,7 @@ static struct strvalmap mode_capa_map[] = {
{ }
};
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
struct _GSupplicantINSSettings {
GSupplicantINSPreferredFreq preferred_freq_bssid;
unsigned int preferred_freq_bssid_score;
@@ -188,13 +189,11 @@ struct _GSupplicantINSSettings {
};
static struct _GSupplicantINSSettings ins_settings;
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
-#if defined TIZEN_EXT
static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-#endif
+#endif /* defined TIZEN_EXT */
static GHashTable *interface_table;
static GHashTable *bss_mapping;
@@ -264,6 +263,7 @@ struct _GSupplicantInterface {
struct added_network_information network_info;
#if defined TIZEN_EXT
dbus_bool_t is_5_0_Ghz_supported;
+ dbus_bool_t is_6_0_Ghz_supported;
int disconnect_reason;
#endif
#if defined TIZEN_EXT
@@ -307,6 +307,7 @@ struct g_supplicant_bss {
GSupplicantPhy_mode phy_mode;
dbus_int16_t snr;
dbus_uint32_t est_throughput;
+ dbus_bool_t psk_sha256;
#endif
unsigned int wps_capabilities;
#if defined TIZEN_EXT
@@ -538,6 +539,8 @@ static const char *security2string(GSupplicantSecurity security)
case G_SUPPLICANT_SECURITY_IEEE8021X:
return "ieee8021x";
#if defined TIZEN_EXT
+ case G_SUPPLICANT_SECURITY_PSK_SHA256:
+ return "psk_sha256";
case G_SUPPLICANT_SECURITY_FT_PSK:
return "ft_psk";
case G_SUPPLICANT_SECURITY_FT_IEEE8021X:
@@ -669,6 +672,7 @@ static int store_network_information(GSupplicantInterface * interface,
ssid->security == G_SUPPLICANT_SECURITY_PSK ||
#if defined TIZEN_EXT
ssid->security == G_SUPPLICANT_SECURITY_SAE ||
+ ssid->security == G_SUPPLICANT_SECURITY_PSK_SHA256 ||
#endif
ssid->security == G_SUPPLICANT_SECURITY_NONE) &&
ssid->passphrase) {
@@ -1307,6 +1311,11 @@ static void interface_capability(const char *key, DBusMessageIter *iter,
dbus_message_iter_get_basic(iter, &is_5_0_Ghz_supported);
interface->is_5_0_Ghz_supported = is_5_0_Ghz_supported;
+ } else if (g_strcmp0(key, "Is6GhzSupported") == 0) {
+ dbus_bool_t is_6_0_Ghz_supported;
+
+ dbus_message_iter_get_basic(iter, &is_6_0_Ghz_supported);
+ interface->is_6_0_Ghz_supported = is_6_0_Ghz_supported;
#endif
} else
SUPPLICANT_DBG("key %s type %c",
@@ -1418,11 +1427,19 @@ const char *g_supplicant_interface_get_ifname(GSupplicantInterface *interface)
bool g_supplicant_interface_get_is_5_0_ghz_supported(GSupplicantInterface *interface)
{
if (!interface)
- return NULL;
+ return false;
return interface->is_5_0_Ghz_supported;
}
+bool g_supplicant_interface_get_is_6_0_ghz_supported(GSupplicantInterface *interface)
+{
+ if (!interface)
+ return false;
+
+ return interface->is_6_0_Ghz_supported;
+}
+
unsigned char *g_supplicant_interface_get_add_network_bssid(GSupplicantInterface *interface)
{
if (!interface)
@@ -1568,7 +1585,7 @@ const char *g_supplicant_network_get_path(GSupplicantNetwork *network)
const char *g_supplicant_network_get_mode(GSupplicantNetwork *network)
{
if (!network)
- return G_SUPPLICANT_MODE_UNKNOWN;
+ return NULL;
return mode2string(network->mode);
}
@@ -1576,7 +1593,7 @@ const char *g_supplicant_network_get_mode(GSupplicantNetwork *network)
const char *g_supplicant_network_get_security(GSupplicantNetwork *network)
{
if (!network)
- return G_SUPPLICANT_SECURITY_UNKNOWN;
+ return NULL;
return security2string(network->security);
}
@@ -1601,6 +1618,32 @@ dbus_int16_t g_supplicant_network_get_signal(GSupplicantNetwork *network)
return network->signal;
}
+#if defined TIZEN_EXT
+void g_supplicant_network_set_signal(GSupplicantNetwork *network, int signal)
+{
+ if (!network)
+ return;
+
+ network->signal = (dbus_int16_t)signal;
+}
+
+void g_supplicant_network_set_bss_signal(GSupplicantNetwork *network,
+ int signal, int snr)
+{
+ struct g_supplicant_bss *best_bss;
+
+ if (!network)
+ return;
+
+ best_bss = network->best_bss;
+ if (!best_bss)
+ return;
+
+ best_bss->signal = (dbus_int16_t)signal;
+ best_bss->snr = (dbus_int16_t)snr;
+}
+#endif
+
dbus_uint16_t g_supplicant_network_get_frequency(GSupplicantNetwork *network)
{
if (!network)
@@ -1768,8 +1811,8 @@ const unsigned char *g_supplicant_network_get_countrycode(GSupplicantNetwork
dbus_bool_t g_supplicant_network_is_pmf_required(GSupplicantNetwork *network)
{
- if (!network)
- return 0;
+ if (!network || !network->best_bss)
+ return FALSE;
return network->best_bss->pmf_required;
}
@@ -1914,6 +1957,7 @@ const char *g_supplicant_network_get_enc_mode(GSupplicantNetwork *network)
network->best_bss->security == G_SUPPLICANT_SECURITY_SAE ||
network->best_bss->security == G_SUPPLICANT_SECURITY_OWE ||
network->best_bss->security == G_SUPPLICANT_SECURITY_DPP ||
+ network->best_bss->security == G_SUPPLICANT_SECURITY_PSK_SHA256 ||
network->best_bss->security == G_SUPPLICANT_SECURITY_IEEE8021X) {
unsigned int pairwise;
@@ -2009,7 +2053,6 @@ static gchar *convert_bssid_to_str(unsigned char *bssid)
return g_string_free(bssid_str, FALSE);
}
-#if defined TIZEN_EXT_INS
static void count_assoc_reject(gpointer data, gpointer user_data)
{
time_t assoc_reject_time = GPOINTER_TO_INT(data);
@@ -2151,7 +2194,6 @@ static int calculate_score(bool is_last_connected, uint16_t assoc_reject_cnt,
return score;
}
-#endif
static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
{
@@ -2171,24 +2213,26 @@ static void update_bssid_list(gpointer key, gpointer value, gpointer user_data)
bssids->strength = 100;
bssids->frequency = bss->frequency;
+ bssids->est_throughput = bss->est_throughput;
bssids->score_snr = (int)bss->snr;
-#if defined TIZEN_EXT_INS
- bssids->assoc_reject_cnt = get_assoc_reject_cnt(bssid_data->assoc_reject_table, bssids->bssid);
- bssids->is_last_connected = compare_bssid(bssids->bssid, bssid_data->last_connected_bssid);
+ if (TIZEN_INS_ENABLED) {
+ bssids->assoc_reject_cnt = get_assoc_reject_cnt(bssid_data->assoc_reject_table, bssids->bssid);
+ bssids->is_last_connected = compare_bssid(bssids->bssid, bssid_data->last_connected_bssid);
- bssids->score_last_connected_bssid = calculate_score_last_connected_bssid(bssids->is_last_connected);
- bssids->score_assoc_reject = calculate_score_assoc_reject(bssids->assoc_reject_cnt);
- bssids->score_frequency = calculate_score_frequency(bss->signal, bssids->frequency);
- bssids->score_strength = calculate_score_strength(bss->signal);
- bssids->score_est_throughput = calculate_score_est_throughput(bss->est_throughput);
+ bssids->score_last_connected_bssid = calculate_score_last_connected_bssid(bssids->is_last_connected);
+ bssids->score_assoc_reject = calculate_score_assoc_reject(bssids->assoc_reject_cnt);
+ bssids->score_frequency = calculate_score_frequency(bss->signal, bssids->frequency);
+ bssids->score_strength = calculate_score_strength(bss->signal);
+ bssids->score_est_throughput = calculate_score_est_throughput(bss->est_throughput);
+
+ bssids->ins_score = calculate_score(bssids->is_last_connected,
+ bssids->assoc_reject_cnt, bssids->frequency, bss->signal,
+ bss->snr, bss->est_throughput);
+ } else {
+ bssids->ins_score = bss->signal;
+ }
- bssids->ins_score = calculate_score(bssids->is_last_connected,
- bssids->assoc_reject_cnt, bssids->frequency, bss->signal,
- bss->snr, bss->est_throughput);
-#else
- bssids->ins_score = bss->signal;
-#endif
bssid_data->bssid_list = g_slist_append(bssid_data->bssid_list, bssids);
} else
SUPPLICANT_DBG("Failed to allocate memory");
@@ -2205,21 +2249,31 @@ static gint cmp_bss(gconstpointer a, gconstpointer b)
if (entry_a->ins_score < entry_b->ins_score)
return 1;
+ if (entry_a->ins_score == entry_b->ins_score) {
+ if (entry_a->strength >= entry_b->strength)
+ return -1;
+ else
+ return 1;
+ }
+
return 0;
}
-#if defined TIZEN_EXT_INS
static void print_bssid_sort(gpointer data, gpointer user_data)
{
struct g_connman_bssids *bssids = data;
- SUPPLICANT_DBG("bssid[" MACSTR "] total[%2d] freq[%2d] "
- "last_conn[%2d] assoc_reject[%2d] strength[%2d]",
- MAC2STR(bssids->bssid), bssids->ins_score,
+ GSupplicantNetwork *network = (GSupplicantNetwork *) user_data;
+
+ if (!bssids || !network)
+ return;
+
+ SUPPLICANT_DBG("ssid [%-20s] bssid[" MACSTR "] total[%2d] freq[%2d] "
+ "last_conn[%2d] assoc_reject[%2d] strength[%2d] rssi[%2d]",
+ network->ssid, MAC2STR(bssids->bssid), bssids->ins_score,
bssids->score_frequency, bssids->score_last_connected_bssid,
- bssids->score_assoc_reject, bssids->score_strength);
+ bssids->score_assoc_reject, bssids->score_strength, bssids->strength - 120);
}
-#endif
void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
{
@@ -2235,9 +2289,8 @@ void *g_supplicant_network_get_bssid_list(GSupplicantNetwork *network)
g_hash_table_foreach(network->bss_table, update_bssid_list, &bssid_data);
bssid_data.bssid_list = g_slist_sort(bssid_data.bssid_list, cmp_bss);
-#if defined TIZEN_EXT_INS
- g_slist_foreach(bssid_data.bssid_list, print_bssid_sort, NULL);
-#endif
+ if (TIZEN_INS_ENABLED && !simplified_log)
+ g_slist_foreach(bssid_data.bssid_list, print_bssid_sort, (gpointer)network);
return bssid_data.bssid_list;
}
@@ -2307,6 +2360,42 @@ GHashTable *g_supplicant_network_get_assoc_reject_table(GSupplicantNetwork *netw
return network->assoc_reject_table;
}
+static void copy_assoc_reject(gpointer key, gpointer value, gpointer user_data)
+{
+ struct assoc_reject_data *cloned_assoc_data;
+ struct assoc_reject_data *assoc_data = value;
+ GHashTable *cloned_assoc_reject_table = user_data;
+
+ if (assoc_data && cloned_assoc_reject_table) {
+ cloned_assoc_data = g_try_new0(struct assoc_reject_data, 1);
+ if (!cloned_assoc_data)
+ return;
+
+ cloned_assoc_data->bssid = g_strdup(assoc_data->bssid);
+ cloned_assoc_data->reject_time_list = g_slist_copy(assoc_data->reject_time_list);
+ g_hash_table_insert(cloned_assoc_reject_table,
+ cloned_assoc_data->bssid, cloned_assoc_data);
+ }
+}
+
+GHashTable *g_supplicant_network_clone_assoc_reject_table(GSupplicantNetwork *network)
+{
+ GHashTable *cloned_assoc_reject_table;
+
+ if (!network)
+ return NULL;
+
+ GHashTable *assoc_reject_table = g_supplicant_network_get_assoc_reject_table(network);
+ if (!assoc_reject_table)
+ return NULL;
+
+ cloned_assoc_reject_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ NULL, remove_assoc_data);
+ g_hash_table_foreach(assoc_reject_table, copy_assoc_reject, cloned_assoc_reject_table);
+
+ return cloned_assoc_reject_table;
+}
+
GSupplicantNetwork *g_supplicant_interface_get_network(GSupplicantInterface *interface,
const char *group)
{
@@ -2315,7 +2404,7 @@ GSupplicantNetwork *g_supplicant_interface_get_network(GSupplicantInterface *int
return g_hash_table_lookup(interface->network_table, group);
}
-#endif
+#endif /* defined TIZEN_EXT */
static void merge_network(GSupplicantNetwork *network)
{
@@ -2368,8 +2457,16 @@ static void merge_network(GSupplicantNetwork *network)
g_string_append_printf(str, "_mesh");
#endif
+#if defined TIZEN_EXT
if (g_strcmp0(key_mgmt, "WPA-PSK") == 0)
g_string_append_printf(str, "_psk");
+ else if (g_strcmp0(key_mgmt, "SAE") == 0)
+ g_string_append_printf(str, "_sae");
+#else
+ if ((g_strcmp0(key_mgmt, "WPA-PSK") == 0) ||
+ (g_strcmp0(key_mgmt, "SAE") == 0))
+ g_string_append_printf(str, "_psk");
+#endif
#if defined TIZEN_EXT
else if (g_strcmp0(key_mgmt, "WPA-EAP") == 0)
g_string_append_printf(str, "_ieee8021x");
@@ -2545,7 +2642,14 @@ static char *create_group(struct g_supplicant_bss *bss)
if (mode)
g_string_append_printf(str, "_%s", mode);
+#if defined TIZEN_EXT
+ if (bss->security == G_SUPPLICANT_SECURITY_PSK_SHA256)
+ security = "psk";
+ else
+ security = security2string(bss->security);
+#else
security = security2string(bss->security);
+#endif
if (security)
g_string_append_printf(str, "_%s", security);
@@ -2558,11 +2662,12 @@ static void update_network_with_best_bss(GSupplicantNetwork *network,
/*
* Do not change best BSS if we are connected.
*/
- if (network->interface->state == G_SUPPLICANT_STATE_COMPLETED)
+ if (network->interface->state == G_SUPPLICANT_STATE_COMPLETED && network->best_bss)
return;
network->signal = best_bss->signal;
network->frequency = best_bss->frequency;
+ network->phy_mode = best_bss->phy_mode;
network->best_bss = best_bss;
}
@@ -2577,24 +2682,24 @@ static bool update_best_bss(GSupplicantNetwork *network,
return true;
}
-#if defined TIZEN_EXT_INS
- score_new = calculate_score(
- compare_bssid(bss->bssid, network->last_connected_bssid),
- get_assoc_reject_cnt(network->assoc_reject_table, bss->bssid),
- bss->frequency, bss->signal, bss->snr, bss->est_throughput);
+ if (TIZEN_INS_ENABLED) {
+ score_new = calculate_score(
+ compare_bssid(bss->bssid, network->last_connected_bssid),
+ get_assoc_reject_cnt(network->assoc_reject_table, bss->bssid),
+ bss->frequency, bss->signal, bss->snr, bss->est_throughput);
- score_best = calculate_score(
- compare_bssid(network->best_bss->bssid, network->last_connected_bssid),
- get_assoc_reject_cnt(network->assoc_reject_table, network->best_bss->bssid),
- network->best_bss->frequency, network->best_bss->signal,
- network->best_bss->snr, network->best_bss->est_throughput);
-#else
- score_new = bss->signal;
- score_best = network->best_bss->signal;
-#endif
+ score_best = calculate_score(
+ compare_bssid(network->best_bss->bssid, network->last_connected_bssid),
+ get_assoc_reject_cnt(network->assoc_reject_table, network->best_bss->bssid),
+ network->best_bss->frequency, network->best_bss->signal,
+ network->best_bss->snr, network->best_bss->est_throughput);
+ } else {
+ score_new = bss->signal;
+ score_best = network->best_bss->signal;
+ }
if (score_new > score_best) {
- SUPPLICANT_DBG("new[" MACSTR "][%u] : best[" MACSTR "][%u]",
+ SUPPLICANT_DBG("new[" MACSTR "][%d] : best[" MACSTR "][%d]",
MAC2STR(bss->bssid), score_new,
MAC2STR(network->best_bss->bssid), score_best);
@@ -2645,6 +2750,7 @@ static int add_or_replace_bss_to_network(struct g_supplicant_bss *bss)
network->name = create_name(bss->ssid, bss->ssid_len);
network->mode = bss->mode;
network->security = bss->security;
+ network->keymgmt = bss->keymgmt;
network->ssid_len = bss->ssid_len;
memcpy(network->ssid, bss->ssid, bss->ssid_len);
network->signal = bss->signal;
@@ -3139,7 +3245,7 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
#if defined TIZEN_EXT
if (bss->keymgmt &
(G_SUPPLICANT_KEYMGMT_WPA_EAP |
- G_SUPPLICANT_KEYMGMT_WPA_EAP_256))
+ G_SUPPLICANT_KEYMGMT_WPA_EAP_256))
bss->ieee8021x = TRUE;
else if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_EAP)
bss->ft_ieee8021x = TRUE;
@@ -3153,8 +3259,13 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
#if defined TIZEN_EXT
if (bss->keymgmt &
+ G_SUPPLICANT_KEYMGMT_WPA_PSK_256) {
+ bss->psk_sha256 = TRUE;
+ }
+
+ if (bss->keymgmt &
(G_SUPPLICANT_KEYMGMT_WPA_PSK |
- G_SUPPLICANT_KEYMGMT_WPA_PSK_256))
+ G_SUPPLICANT_KEYMGMT_WPA_PSK_256))
bss->psk = TRUE;
else if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_PSK)
bss->ft_psk = TRUE;
@@ -3167,7 +3278,9 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
#endif
#if defined TIZEN_EXT
- if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_SAE)
+ if (bss->keymgmt &
+ (G_SUPPLICANT_KEYMGMT_SAE |
+ G_SUPPLICANT_KEYMGMT_FT_SAE))
bss->sae = TRUE;
if (bss->keymgmt & G_SUPPLICANT_KEYMGMT_OWE)
bss->owe = TRUE;
@@ -3182,6 +3295,8 @@ static void bss_compute_security(struct g_supplicant_bss *bss)
bss->security = G_SUPPLICANT_SECURITY_IEEE8021X;
else if (bss->sae)
bss->security = G_SUPPLICANT_SECURITY_SAE;
+ else if (bss->psk_sha256)
+ bss->security = G_SUPPLICANT_SECURITY_PSK_SHA256;
#endif
else if (bss->psk)
bss->security = G_SUPPLICANT_SECURITY_PSK;
@@ -3426,6 +3541,8 @@ static void update_signal(gpointer key, gpointer value,
if (!network->best_bss || (network->best_bss == bss)) {
if (bss->signal > network->signal) {
network->signal = bss->signal;
+ network->frequency = bss->frequency;
+ network->phy_mode = bss->phy_mode;
network->best_bss = bss;
}
return;
@@ -3502,7 +3619,7 @@ static void remove_timer_for_last_connected(GSupplicantInterface *interface)
}
}
}
-#endif
+#endif /* defined TIZEN_EXT */
static void interface_current_bss(GSupplicantInterface *interface,
DBusMessageIter *iter)
@@ -3510,6 +3627,13 @@ static void interface_current_bss(GSupplicantInterface *interface,
GSupplicantNetwork *network;
struct g_supplicant_bss *bss;
const char *path;
+#if defined TIZEN_EXT
+ char curr_bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+ char best_bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+ char *curr_bssid_str = curr_bssid_buff;
+ char *best_bssid_str = best_bssid_buff;
+ gboolean update = FALSE;
+#endif
dbus_message_iter_get_basic(iter, &path);
if (g_strcmp0(path, "/") == 0) {
@@ -3529,7 +3653,17 @@ static void interface_current_bss(GSupplicantInterface *interface,
interface->current_network = network;
#if defined TIZEN_EXT
- SUPPLICANT_DBG("current network [%p]", interface->current_network);
+ snprintf(curr_bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bss->bssid));
+ snprintf(best_bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(network->best_bss->bssid));
+
+ SUPPLICANT_DBG("current network [%p], Passed bss %s, best bss %s",
+ interface->current_network, curr_bssid_str, best_bssid_str);
+
+ if (network->frequency != bss->frequency) {
+ network->frequency = bss->frequency;
+ network->phy_mode = bss->phy_mode;
+ update = TRUE;
+ }
#endif
if (bss != network->best_bss) {
@@ -3542,24 +3676,25 @@ static void interface_current_bss(GSupplicantInterface *interface,
network->best_bss = bss;
-#if defined TIZEN_EXT
- if (network->frequency != bss->frequency)
- network->frequency = bss->frequency;
-#endif
-
if (network->signal != bss->signal) {
SUPPLICANT_DBG("New network signal %d dBm",
bss->signal);
network->signal = bss->signal;
callback_network_changed(network, "Signal");
- }
#if defined TIZEN_EXT
- else
- callback_network_changed(network, "");
+ update = FALSE;
+ } else {
+ update = TRUE;
#endif
+ }
}
+#if defined TIZEN_EXT
+ if (update)
+ callback_network_changed(network, "");
+#endif
+
/*
* wpa_s could notify about CurrentBSS in any state once
* it got associated. It is not sure such notification will
@@ -3582,7 +3717,8 @@ static void interface_current_bss(GSupplicantInterface *interface,
case G_SUPPLICANT_STATE_COMPLETED:
callback_network_associated(network);
#if defined TIZEN_EXT
- add_timer_for_last_connected(interface);
+ if (TIZEN_INS_ENABLED)
+ add_timer_for_last_connected(interface);
#endif
break;
}
@@ -3741,15 +3877,17 @@ static void interface_property(const char *key, DBusMessageIter *iter,
callback_interface_state(interface);
}
#if defined TIZEN_EXT
- switch (interface->state) {
- case G_SUPPLICANT_STATE_COMPLETED:
- add_timer_for_last_connected(interface);
- break;
- case G_SUPPLICANT_STATE_DISCONNECTED:
- remove_timer_for_last_connected(interface);
- break;
- default:
- break;
+ if (TIZEN_INS_ENABLED) {
+ switch (interface->state) {
+ case G_SUPPLICANT_STATE_COMPLETED:
+ add_timer_for_last_connected(interface);
+ break;
+ case G_SUPPLICANT_STATE_DISCONNECTED:
+ remove_timer_for_last_connected(interface);
+ break;
+ default:
+ break;
+ }
}
#endif
if (interface->ap_create_in_progress) {
@@ -4218,10 +4356,20 @@ static void signal_network_removed(const char *path, DBusMessageIter *iter)
interface_network_removed(iter, interface);
}
+
#if defined TIZEN_EXT
-void *copy_vsie_list(gconstpointer src, gpointer data)
+gpointer copy_vsie_list(gconstpointer src, gpointer data)
{
- return g_strdup(src);
+ unsigned char *str = (unsigned char *)src;
+ unsigned char *vsie;
+ vsie = g_try_malloc0(str[1]+2);
+
+ if (vsie)
+ memcpy(vsie, str, str[1]+2);
+ else
+ SUPPLICANT_DBG("Failed to allocate memory");
+
+ return vsie;
}
#endif
@@ -4324,7 +4472,8 @@ static void signal_bss_changed(const char *path, DBusMessageIter *iter)
supplicant_dbus_property_foreach(iter, bss_property, bss);
#if defined TIZEN_EXT
- if (network->interface->state != G_SUPPLICANT_STATE_COMPLETED) {
+ if (network->interface->state != G_SUPPLICANT_STATE_COMPLETED &&
+ bss == network->best_bss) {
network->frequency = bss->frequency;
network->phy_mode = bss->phy_mode;
}
@@ -6474,6 +6623,7 @@ static void interface_signalpoll_result(const char *error,
dbus_int32_t maxspeed = 0;
dbus_int32_t strength = 0;
dbus_int32_t snr = 0;
+ dbus_uint32_t est_throughput = 0;
DBusMessageIter sub_iter, dict;
if (error) {
@@ -6505,23 +6655,27 @@ static void interface_signalpoll_result(const char *error,
if (g_strcmp0(key, "linkspeed") == 0) {
dbus_message_iter_get_basic(&value, &maxspeed);
SUPPLICANT_DBG("linkspeed = %d", maxspeed);
- break;
} else if (g_strcmp0(key, "rssi") == 0) {
dbus_message_iter_get_basic(&value, &strength);
SUPPLICANT_DBG("Strength = %d", strength);
- break;
} else if (g_strcmp0(key, "SNR") == 0) {
dbus_message_iter_get_basic(&value, &snr);
SUPPLICANT_DBG("SNR = %d", snr);
- break;
}
+ break;
+ case DBUS_TYPE_UINT32:
+ if (g_strcmp0(key, "est_throughput") == 0) {
+ dbus_message_iter_get_basic(&value, &est_throughput);
+ SUPPLICANT_DBG("est_throughput = %u", est_throughput);
+ }
+ break;
}
dbus_message_iter_next(&dict);
}
out:
if(data->callback)
- data->callback(err, maxspeed, strength, snr, data->user_data);
+ data->callback(err, maxspeed, strength, snr, data->user_data, est_throughput);
g_free(data->path);
dbus_free(data);
@@ -6614,10 +6768,14 @@ static void interface_select_network_result(const char *error,
#if defined TIZEN_EXT
g_free(data->ssid->ssid);
- g_free((char *)data->ssid->passphrase);
- g_free((char *)data->ssid->connector);
- g_free((char *)data->ssid->c_sign_key);
- g_free((char *)data->ssid->net_access_key);
+ if (data->ssid->is_passphrase_alloc)
+ g_free((char *)data->ssid->passphrase);
+ if (data->ssid->is_connector_alloc)
+ g_free((char *)data->ssid->connector);
+ if (data->ssid->is_c_sign_key_alloc)
+ g_free((char *)data->ssid->c_sign_key);
+ if (data->ssid->is_net_access_key_alloc)
+ g_free((char *)data->ssid->net_access_key);
#endif
g_free(data->ssid);
dbus_free(data);
@@ -6706,10 +6864,14 @@ error:
g_free(data->path);
#if defined TIZEN_EXT
g_free(data->ssid->ssid);
- g_free((char *)data->ssid->passphrase);
- g_free((char *)data->ssid->connector);
- g_free((char *)data->ssid->c_sign_key);
- g_free((char *)data->ssid->net_access_key);
+ if (data->ssid->is_passphrase_alloc)
+ g_free((char *)data->ssid->passphrase);
+ if (data->ssid->is_connector_alloc)
+ g_free((char *)data->ssid->connector);
+ if (data->ssid->is_c_sign_key_alloc)
+ g_free((char *)data->ssid->c_sign_key);
+ if (data->ssid->is_net_access_key_alloc)
+ g_free((char *)data->ssid->net_access_key);
#endif
g_free(data->ssid);
g_free(data);
@@ -7167,17 +7329,6 @@ static void add_network_security_proto(DBusMessageIter *dict,
}
#if defined TIZEN_EXT
-static void add_network_ieee80211w(DBusMessageIter *dict, GSupplicantSSID *ssid)
-{
- if (ssid->security != G_SUPPLICANT_SECURITY_SAE
- && ssid->security != G_SUPPLICANT_SECURITY_OWE
- && ssid->security != G_SUPPLICANT_SECURITY_DPP)
- return;
-
- supplicant_dbus_dict_append_basic(dict, "ieee80211w", DBUS_TYPE_UINT32,
- &ssid->ieee80211w);
-}
-
static void add_network_security_connector(DBusMessageIter *dict, GSupplicantSSID *ssid)
{
if (ssid->connector && strlen(ssid->connector) > 0) {
@@ -7243,8 +7394,16 @@ static void add_network_security_net_access_key(DBusMessageIter *dict, GSupplica
#endif
+static void add_network_ieee80211w(DBusMessageIter *dict, GSupplicantSSID *ssid,
+ GSupplicantMfpOptions ieee80211w)
+{
+ supplicant_dbus_dict_append_basic(dict, "ieee80211w", DBUS_TYPE_UINT32,
+ &ieee80211w);
+}
+
static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
{
+ GSupplicantMfpOptions ieee80211w;
char *key_mgmt;
switch (ssid->security) {
@@ -7260,7 +7419,14 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
add_network_security_ciphers(dict, ssid);
break;
case G_SUPPLICANT_SECURITY_PSK:
+#if defined TIZEN_EXT
+ if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_PSK)
+ key_mgmt = "FT-PSK WPA-PSK";
+ else
+ key_mgmt = "WPA-PSK";
+#else
key_mgmt = "WPA-PSK";
+#endif
add_network_security_psk(dict, ssid);
add_network_security_ciphers(dict, ssid);
add_network_security_proto(dict, ssid);
@@ -7272,6 +7438,15 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
add_network_security_proto(dict, ssid);
break;
#if defined TIZEN_EXT
+ case G_SUPPLICANT_SECURITY_PSK_SHA256:
+ if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_PSK)
+ key_mgmt = "WPA-PSK-SHA256 WPA-PSK";
+ else
+ key_mgmt = "WPA-PSK-SHA256";
+ add_network_security_psk(dict, ssid);
+ add_network_security_ciphers(dict, ssid);
+ add_network_security_proto(dict, ssid);
+ break;
case G_SUPPLICANT_SECURITY_FT_PSK:
key_mgmt = "FT-PSK";
add_network_security_psk(dict, ssid);
@@ -7285,11 +7460,24 @@ static void add_network_security(DBusMessageIter *dict, GSupplicantSSID *ssid)
add_network_security_proto(dict, ssid);
break;
case G_SUPPLICANT_SECURITY_SAE:
- if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_PSK)
- key_mgmt = "SAE WPA-PSK"; // WFA (WPA3 & WPA2 Mixed -> WPA2 only)
- else
- key_mgmt = "SAE";
+ if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_FT_SAE) {
+ if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_SAE)
+ key_mgmt = "FT-SAE SAE";
+ else
+ key_mgmt = "FT-SAE";
+ } else {
+ if (ssid->keymgmt & G_SUPPLICANT_KEYMGMT_WPA_PSK) {
+ key_mgmt = "SAE WPA-PSK";
+ ieee80211w = G_SUPPLICANT_MFP_OPTIONAL;
+ } else {
+ key_mgmt = "SAE";
+ ieee80211w = G_SUPPLICANT_MFP_REQUIRED;
+ }
+ add_network_ieee80211w(dict, ssid, ieee80211w);
+ }
add_network_security_psk(dict, ssid);
+ add_network_security_ciphers(dict, ssid);
+ add_network_security_proto(dict, ssid);
break;
case G_SUPPLICANT_SECURITY_OWE:
key_mgmt = "OWE";
@@ -7362,10 +7550,6 @@ static void interface_add_network_params(DBusMessageIter *iter, void *user_data)
add_network_security(&dict, ssid);
-#if defined TIZEN_EXT
- add_network_ieee80211w(&dict, ssid);
-#endif
-
supplicant_dbus_dict_append_fixed_array(&dict, "ssid",
DBUS_TYPE_BYTE, &ssid->ssid,
ssid->ssid_len);
@@ -7547,6 +7731,12 @@ static void decryption_request_reply(DBusPendingCall *call,
goto done;
}
+ if (!g_str_has_prefix(data->interface->path, "/")) {
+ SUPPLICANT_DBG("Invalid path %s", data->interface->path);
+ ret = -EINVAL;
+ goto done;
+ }
+
if (dbus_message_iter_init(reply, &args) == FALSE) {
SUPPLICANT_DBG("dbus_message_iter_init() failed");
ret = -EINVAL;
@@ -7555,6 +7745,7 @@ static void decryption_request_reply(DBusPendingCall *call,
dbus_message_iter_get_basic(&args, &out_data);
data->ssid->passphrase = g_strdup((const gchar *)out_data);
+ data->ssid->is_passphrase_alloc = true;
ret = supplicant_dbus_method_call(data->interface->path,
SUPPLICANT_INTERFACE ".Interface", "AddNetwork",
@@ -7568,10 +7759,14 @@ done:
callback_assoc_failed(decrypt_request_data.data->user_data);
g_free(data->path);
g_free(data->ssid->ssid);
- g_free((char *)data->ssid->passphrase);
- g_free((char *)data->ssid->connector);
- g_free((char *)data->ssid->c_sign_key);
- g_free((char *)data->ssid->net_access_key);
+ if (data->ssid->is_passphrase_alloc)
+ g_free((char *)data->ssid->passphrase);
+ if (data->ssid->is_connector_alloc)
+ g_free((char *)data->ssid->connector);
+ if (data->ssid->is_c_sign_key_alloc)
+ g_free((char *)data->ssid->c_sign_key);
+ if (data->ssid->is_net_access_key_alloc)
+ g_free((char *)data->ssid->net_access_key);
g_free(data->ssid);
dbus_free(data);
}
@@ -7677,14 +7872,17 @@ static void decrypt_conf_obj_reply(DBusPendingCall *call,
if (g_strcmp0(key, "connector") == 0) {
dbus_message_iter_get_basic(&value, &out_data);
data->ssid->connector = g_strdup((const gchar *)out_data);
+ data->ssid->is_connector_alloc = true;
SUPPLICANT_DBG("connector %s", data->ssid->connector);
} else if (g_strcmp0(key, "c_sign_key") == 0) {
dbus_message_iter_get_basic(&value, &out_data);
data->ssid->c_sign_key = g_strdup((const gchar *)out_data);
+ data->ssid->is_c_sign_key_alloc = true;
SUPPLICANT_DBG("c_sign_key %s", data->ssid->c_sign_key);
} else if (g_strcmp0(key, "net_access_key") == 0) {
dbus_message_iter_get_basic(&value, &out_data);
data->ssid->net_access_key = g_strdup((const gchar *)out_data);
+ data->ssid->is_net_access_key_alloc = true;
SUPPLICANT_DBG("net_access_key %s", data->ssid->net_access_key);
}
}
@@ -7703,9 +7901,12 @@ done:
callback_assoc_failed(decrypt_request_data.data->user_data);
g_free(data->path);
g_free(data->ssid->ssid);
- g_free((char *)data->ssid->connector);
- g_free((char *)data->ssid->c_sign_key);
- g_free((char *)data->ssid->net_access_key);
+ if (data->ssid->is_connector_alloc)
+ g_free((char *)data->ssid->connector);
+ if (data->ssid->is_c_sign_key_alloc)
+ g_free((char *)data->ssid->c_sign_key);
+ if (data->ssid->is_net_access_key_alloc)
+ g_free((char *)data->ssid->net_access_key);
g_free(data->ssid);
dbus_free(data);
}
@@ -8089,6 +8290,49 @@ int g_supplicant_interface_disconnect(GSupplicantInterface *interface,
return ret;
}
+#if defined TIZEN_EXT
+void g_supplicant_interface_remove_network(GSupplicantInterface *interface,
+ GSupplicantSSID *ssid)
+{
+ struct interface_data *data;
+ int ret;
+
+ SUPPLICANT_DBG("");
+
+ if (!interface)
+ return;
+
+ if (interface->network_path == NULL)
+ return;
+
+ if (!interface->network_info.ssid)
+ return;
+
+ if (memcmp(interface->network_info.ssid, ssid->ssid, ssid->ssid_len))
+ return;
+
+ if (interface->network_info.security != ssid->security)
+ return;
+
+ data = dbus_malloc0(sizeof(*data));
+ if (!data)
+ return;
+
+ data->interface = interface;
+ data->path = g_strdup(interface->path);
+
+ ret = supplicant_dbus_method_call(interface->path,
+ SUPPLICANT_INTERFACE ".Interface", "RemoveNetwork",
+ network_remove_params, network_remove_result, data,
+ interface);
+
+ if (ret < 0) {
+ g_free(data->path);
+ dbus_free(data);
+ }
+}
+#endif
+
static void interface_p2p_find_result(const char *error,
DBusMessageIter *iter, void *user_data)
{
@@ -8588,7 +8832,7 @@ static void invoke_introspect_method(void)
dbus_message_unref(message);
}
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
void g_supplicant_set_ins_settings(GSupplicantINSPreferredFreq preferred_freq_bssid,
bool last_connected_bssid, bool assoc_reject, bool signal_bssid,
unsigned int preferred_freq_bssid_score, unsigned int last_connected_bssid_score,
@@ -8614,7 +8858,7 @@ void g_supplicant_set_ins_settings(GSupplicantINSPreferredFreq preferred_freq_bs
SUPPLICANT_DBG("signal_level3_5ghz [%d]", signal_level3_5ghz);
SUPPLICANT_DBG("signal_level3_24ghz [%d]", signal_level3_24ghz);
}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
void g_supplicant_register_eap_callback(g_supplicant_eap_callback cb)
diff --git a/include/device.h b/include/device.h
index 8cc8ccef..acbd1d54 100755
--- a/include/device.h
+++ b/include/device.h
@@ -118,7 +118,10 @@ void connman_device_set_max_scan_ssids(struct connman_device *device,
int connman_device_get_max_scan_ssids(struct connman_device *device);
void connman_device_set_wifi_5ghz_supported(struct connman_device *device,
bool is_5_0_ghz_supported);
+void connman_device_set_wifi_6ghz_supported(struct connman_device *device,
+ bool is_6_0_ghz_supported);
bool connman_device_get_wifi_5ghz_supported(struct connman_device *device);
+bool connman_device_get_wifi_6ghz_supported(struct connman_device *device);
#endif
int connman_device_remove_network(struct connman_device *device,
struct connman_network *network);
diff --git a/include/network.h b/include/network.h
index 4d09dfff..f9bd3c0a 100755
--- a/include/network.h
+++ b/include/network.h
@@ -79,12 +79,10 @@ struct connman_bssids {
uint16_t frequency;
uint16_t assoc_reject_cnt;
bool is_last_connected;
-#if defined TIZEN_EXT_INS
int score_last_connected_bssid;
int score_assoc_reject;
int score_frequency;
int score_strength;
-#endif
int ins_score;
};
@@ -235,25 +233,30 @@ unsigned char *connman_network_get_countrycode(struct connman_network *network);
int connman_network_set_bssid_list(struct connman_network *network,
GSList *bssids);
void *connman_network_get_bssid_list(struct connman_network *network);
-#if defined TIZEN_EXT
+unsigned int connman_network_get_max_bssid_count(struct connman_network *network);
+
int connman_network_set_last_connected_bssid(struct connman_network *network,
const unsigned char *bssid);
unsigned char *connman_network_get_last_connected_bssid(struct connman_network *network);
void connman_network_set_assoc_reject_table(struct connman_network *network,
GHashTable *assoc_reject_table);
GHashTable *connman_network_get_assoc_reject_table(struct connman_network *network);
+
__time_t connman_network_get_roam_scan_time(struct connman_network *network);
void connman_network_set_roam_scan_time(struct connman_network *network,
__time_t roam_scan_time);
int connman_network_get_snr(struct connman_network *network);
void connman_network_set_snr(struct connman_network *network, int snr);
-#endif
+unsigned int connman_network_get_est_throughput(struct connman_network *network);
+void connman_network_set_est_throughput(struct connman_network *network,
+ unsigned int est_throughput);
int connman_network_set_phy_mode(struct connman_network *network,
ieee80211_modes_e mode);
ieee80211_modes_e connman_network_get_phy_mode(struct connman_network *network);
int connman_network_set_connection_mode(struct connman_network *network,
connection_mode_e mode);
connection_mode_e connman_network_get_connection_mode(struct connman_network *network);
+int set_connected_dhcp(struct connman_network *network);
#endif
int connman_network_set_name(struct connman_network *network,
diff --git a/include/service.h b/include/service.h
index 041949f5..f27e4243 100755
--- a/include/service.h
+++ b/include/service.h
@@ -209,7 +209,8 @@ int connman_service_set_proxy(struct connman_service *service,
const char *proxy, gboolean active);
void connman_service_set_disconnection_requested(struct connman_service *service,
- bool disconnection_requested);
+ bool disconnection_requested);
+void connman_service_notify_reconnection_roaming(struct connman_service *service);
#endif
#if defined TIZEN_EXT
diff --git a/include/setting.h b/include/setting.h
index f141bf68..4fb4957b 100755
--- a/include/setting.h
+++ b/include/setting.h
@@ -28,10 +28,20 @@
extern "C" {
#endif
-bool connman_setting_get_bool(const char *key);
#if defined TIZEN_EXT
+/* AP selection method to be used */
+typedef enum {
+ AP_SELECTION_METHOD_NORMAL = 0,
+ AP_SELECTION_METHOD_INS = 1,
+} ap_selection_method_e;
+
+#define TIZEN_INS_ENABLED \
+ (connman_setting_get_int("ApSelectionMethod") == AP_SELECTION_METHOD_INS)
+
int connman_setting_get_int(const char *key);
#endif
+
+bool connman_setting_get_bool(const char *key);
unsigned int connman_setting_get_uint(const char *key);
char *connman_setting_get_string(const char *key);
char **connman_setting_get_string_list(const char *key);
diff --git a/include/technology.h b/include/technology.h
index d47f5666..c7898396 100755
--- a/include/technology.h
+++ b/include/technology.h
@@ -65,8 +65,10 @@ void connman_technology_regdom_notify(struct connman_technology *technology,
enum connman_service_type connman_technology_get_type
(struct connman_technology *technology);
-bool connman_technology_get_wifi_tethering(const char **ssid,
- const char **psk);
+
+bool connman_technology_get_wifi_tethering(const struct connman_technology *technology,
+ const char **ssid, const char **psk, int *freq);
+
bool connman_technology_is_tethering_allowed(enum connman_service_type type);
struct connman_technology_driver {
@@ -81,7 +83,6 @@ struct connman_technology_driver {
void (*remove_interface) (struct connman_technology *technology,
int index);
int (*set_tethering) (struct connman_technology *technology,
- const char *identifier, const char *passphrase,
const char *bridge, bool enabled);
int (*set_regdom) (struct connman_technology *technology,
const char *alpha2);
@@ -94,6 +95,8 @@ const char *connman_techonology_get_path(enum connman_service_type type);
void __connman_technology_notify_scan_done(const char *ifname, int val);
void __connman_technology_append_interfaces(DBusMessageIter *array,
enum connman_service_type type, const char *ifname);
+void __connman_technology_notify_device_detected_by_device(
+ struct connman_device *device, const char *ifname, bool val);
void __connman_technology_notify_roaming_state(const char *ifname,
const char *state, const char *cur_bssid, const char *dst_bssid);
#endif
diff --git a/isu/isu.cfg b/isu/isu.cfg
new file mode 100644
index 00000000..ebfaa2dd
--- /dev/null
+++ b/isu/isu.cfg
@@ -0,0 +1,8 @@
+[isu]
+name=#NAME#
+version=#VERSION#
+system_service=connman.service
+
+[files]
+/usr/bin/connmand
+/etc/connman/main.conf
diff --git a/isu/system-services/connman.service b/isu/system-services/connman.service
new file mode 100644
index 00000000..78abb6e7
--- /dev/null
+++ b/isu/system-services/connman.service
@@ -0,0 +1,24 @@
+[Unit]
+Description=Connection service
+Conflicts=shutdown.target
+RequiresMountsFor=/var/lib/connman
+After=dbus.service network-pre.target systemd-sysusers.service net-config.service
+Before=network.target multi-user.target shutdown.target
+Wants=network.target
+
+[Service]
+Type=dbus
+User=network_fw
+Group=network_fw
+BusName=net.connman
+Restart=on-failure
+SmackProcessLabel=System
+BindReadOnlyPaths=#ISU_RUN_PATH#/connman/rootfs/etc/connman:/etc/connman
+BindPaths=#ISU_RUN_PATH#/connman/rootfs/usr/bin/connmand:/usr/bin/connmand
+ExecStart=/usr/bin/connmand -n --nobacktrace --noplugin vpn
+Capabilities=cap_setgid,cap_net_admin,cap_net_bind_service,cap_net_broadcast,cap_net_raw,cap_dac_override=i
+StandardOutput=null
+SecureBits=keep-caps
+
+[Install]
+WantedBy=multi-user.target
diff --git a/packaging/connman.spec b/packaging/connman.spec
index 3f73b7b1..c97b261d 100644
--- a/packaging/connman.spec
+++ b/packaging/connman.spec
@@ -5,8 +5,8 @@
%bcond_without connman_vpnd
Name: connman
-Version: 1.40
-Release: 1
+Version: 1.41
+Release: 2
License: GPL-2.0+
Summary: Connection Manager
Url: http://connman.net
@@ -153,6 +153,12 @@ Requires: %{name} = %{version}-%{release}
%description profile_robot
connman extension for Tizen robot profile
+%package isu
+Summary: connman ISU pacakge
+Group: Network & Connectivity/Connection Management
+%description isu
+Configuration files to generate the ISU (Individual Service Upgrade) package
+
%prep
%setup -q
@@ -168,8 +174,7 @@ chmod +x bootstrap
--sysconfdir=/etc \
--enable-client \
--enable-tizen-ext \
- --disable-tizen-ext-ins \
- --enable-tizen-ext-eap-on-ethernet \
+ --enable-tizen-ext-eap-on-ethernet \
--enable-pacrunner \
--enable-wifi=builtin \
%if %{with connman_openconnect}
@@ -350,3 +355,7 @@ mv -f %{_sysconfdir}/connman/main.conf.robot %{_sysconfdir}/connman/main.conf
%manifest %{name}.manifest
%attr(644,root,root) %{_sysconfdir}/dbus-1/system.d/connman-robot.conf
%attr(644,network_fw,network_fw) %{_sysconfdir}/connman/main.conf.robot
+
+%files isu
+/etc/isu/connman/isu.cfg
+/etc/isu/connman/system-services/connman.service
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index a8383e75..0b59a656 100755
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -903,7 +903,6 @@ static void bluetooth_tech_remove(struct connman_technology *technology)
}
static int bluetooth_tech_set_tethering(struct connman_technology *technology,
- const char *identifier, const char *passphrase,
const char *bridge, bool enabled)
{
GHashTableIter hash_iter;
diff --git a/plugins/ethernet.c b/plugins/ethernet.c
index 766f8e44..9d64abe4 100644
--- a/plugins/ethernet.c
+++ b/plugins/ethernet.c
@@ -57,6 +57,11 @@
#include <gsupplicant/gsupplicant.h>
#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */
+#if defined TIZEN_EXT
+#include "connman.h"
+#include "dbus.h"
+#endif
+
static bool eth_tethering = false;
struct ethernet_data {
@@ -669,7 +674,6 @@ static void eth_tech_disable_tethering(struct connman_technology *technology,
}
static int eth_tech_set_tethering(struct connman_technology *technology,
- const char *identifier, const char *passphrase,
const char *bridge, bool enabled)
{
if (!connman_technology_is_tethering_allowed(
diff --git a/plugins/gadget.c b/plugins/gadget.c
index 1b44bbb5..2d58df3e 100755
--- a/plugins/gadget.c
+++ b/plugins/gadget.c
@@ -294,7 +294,6 @@ static void gadget_tech_disable_tethering(struct connman_technology *technology,
}
static int gadget_tech_set_tethering(struct connman_technology *technology,
- const char *identifier, const char *passphrase,
const char *bridge, bool enabled)
{
DBG("bridge %s enabled %d", bridge, enabled);
diff --git a/plugins/iwd.c b/plugins/iwd.c
index 194a99dd..2aed75b6 100644
--- a/plugins/iwd.c
+++ b/plugins/iwd.c
@@ -209,18 +209,13 @@ static int cm_network_probe(struct connman_network *network)
static void update_network_connected(struct iwd_network *iwdn)
{
struct iwd_device *iwdd;
- int index;
iwdd = g_hash_table_lookup(devices, iwdn->device);
if (!iwdd)
return;
- index = connman_inet_ifindex(iwdd->name);
- if (index < 0)
- return;
-
- DBG("interface name %s index %d", iwdd->name, index);
- connman_network_set_index(iwdn->network, index);
+ DBG("interface name %s index %d", iwdd->name,
+ connman_network_get_index(iwdn->network));
connman_network_set_connected(iwdn->network, true);
}
@@ -316,11 +311,13 @@ static int cm_network_disconnect(struct connman_network *network)
if (!iwds)
return -EIO;
+ connman_network_set_associating(network, false);
+
if (!g_dbus_proxy_method_call(iwds->proxy, "Disconnect",
NULL, cm_network_disconnect_cb, g_strdup(iwdn->path), g_free))
return -EIO;
- return -EINPROGRESS;
+ return 0;
}
struct auto_connect_cb_data {
@@ -558,7 +555,7 @@ static void cm_device_scan_cb(DBusMessage *message, void *user_data)
const char *path = user_data;
struct iwd_station *iwds;
- iwds = g_hash_table_lookup(networks, path);
+ iwds = g_hash_table_lookup(stations, path);
if (!iwds)
return;
@@ -818,12 +815,16 @@ static int cm_change_tethering(struct iwd_device *iwdd,
}
static int cm_tech_tethering(struct connman_technology *technology,
- const char *identifier, const char *passphrase,
const char *bridge, bool enabled)
{
GHashTableIter iter;
gpointer key, value;
int err = 0, res;
+ const char *ssid;
+ const char *psk;
+ int freq;
+
+ connman_technology_get_wifi_tethering(technology, &ssid, &psk, &freq);
g_hash_table_iter_init(&iter, devices);
@@ -840,8 +841,8 @@ static int cm_tech_tethering(struct connman_technology *technology,
continue;
if (!enabled && !g_strcmp0("ap", iwdd->mode)) {
- res = cm_change_tethering(iwdd, technology, identifier,
- passphrase, bridge, enabled);
+ res = cm_change_tethering(iwdd, technology, ssid,
+ psk, bridge, enabled);
if (res)
connman_warn("%s switching to Station mode failed",
iwdd->path);
@@ -851,8 +852,8 @@ static int cm_tech_tethering(struct connman_technology *technology,
}
if (enabled && !g_strcmp0("station", iwdd->mode)) {
- err = cm_change_tethering(iwdd, technology, identifier,
- passphrase, bridge, enabled);
+ err = cm_change_tethering(iwdd, technology, ssid,
+ psk, bridge, enabled);
if (err)
connman_warn("%s switching to AccessPoint mode failed",
iwdd->path);
@@ -912,6 +913,7 @@ static void add_network(const char *path, struct iwd_network *iwdn)
{
struct iwd_device *iwdd;
char *identifier;
+ int index;
iwdd = g_hash_table_lookup(devices, iwdn->device);
if (!iwdd)
@@ -920,6 +922,11 @@ static void add_network(const char *path, struct iwd_network *iwdn)
identifier = create_identifier(path, iwdn->type);
iwdn->network = connman_network_create(identifier,
CONNMAN_NETWORK_TYPE_WIFI);
+
+ index = connman_inet_ifindex(iwdd->name);
+ if (index >= 0)
+ connman_network_set_index(iwdn->network, index);
+
connman_network_set_data(iwdn->network, iwdn);
connman_network_set_name(iwdn->network, iwdn->name);
@@ -936,7 +943,9 @@ static void add_network(const char *path, struct iwd_network *iwdn)
}
iwdn->iwdd = iwdd;
- connman_network_set_available(iwdn->network, true);
+ if (connman_network_get_strength(iwdn->network))
+ connman_network_set_available(iwdn->network, true);
+
connman_network_set_group(iwdn->network, identifier);
g_free(identifier);
@@ -1372,13 +1381,7 @@ static void create_adapter(GDBusProxy *proxy)
struct iwd_adapter *iwda;
GSList *modes, *list;
- iwda = g_try_new0(struct iwd_adapter, 1);
-
- if (!iwda) {
- connman_error("Out of memory creating IWD adapter");
- return;
- }
-
+ iwda = g_new0(struct iwd_adapter, 1);
iwda->path = g_strdup(path);
g_hash_table_replace(adapters, iwda->path, iwda);
@@ -1423,13 +1426,7 @@ static void create_device(GDBusProxy *proxy)
const char *path = g_dbus_proxy_get_path(proxy);
struct iwd_device *iwdd;
- iwdd = g_try_new0(struct iwd_device, 1);
-
- if (!iwdd) {
- connman_error("Out of memory creating IWD device");
- return;
- }
-
+ iwdd = g_new0(struct iwd_device, 1);
iwdd->path = g_strdup(path);
g_hash_table_replace(devices, iwdd->path, iwdd);
@@ -1494,6 +1491,8 @@ static DBusMessage *agent_request_passphrase(DBusConnection *dbus_conn,
return get_reply_on_error(message, EINVAL);
passwd = connman_network_get_string(iwdn->network, "WiFi.Passphrase");
+ if (!passwd)
+ return get_reply_on_error(message, ENOKEY);
return g_dbus_create_reply(message, DBUS_TYPE_STRING, &passwd,
DBUS_TYPE_INVALID);
@@ -1596,13 +1595,7 @@ static void create_network(GDBusProxy *proxy)
const char *path = g_dbus_proxy_get_path(proxy);
struct iwd_network *iwdn;
- iwdn = g_try_new0(struct iwd_network, 1);
-
- if (!iwdn) {
- connman_error("Out of memory creating IWD network");
- return;
- }
-
+ iwdn = g_new0(struct iwd_network, 1);
iwdn->path = g_strdup(path);
g_hash_table_replace(networks, iwdn->path, iwdn);
@@ -1762,12 +1755,7 @@ static void create_know_network(GDBusProxy *proxy)
const char *path = g_dbus_proxy_get_path(proxy);
struct iwd_known_network *iwdkn;
- iwdkn = g_try_new0(struct iwd_known_network, 1);
- if (!iwdkn) {
- connman_error("Out of memory creating IWD known network");
- return;
- }
-
+ iwdkn = g_new0(struct iwd_known_network, 1);
iwdkn->path = g_strdup(path);
g_hash_table_replace(known_networks, iwdkn->path, iwdkn);
@@ -1801,12 +1789,7 @@ static void create_station(GDBusProxy *proxy)
const char *path = g_dbus_proxy_get_path(proxy);
struct iwd_station *iwds;
- iwds = g_try_new0(struct iwd_station, 1);
- if (!iwds) {
- connman_error("Out of memory creating IWD station");
- return;
- }
-
+ iwds = g_new0(struct iwd_station, 1);
iwds->path = g_strdup(path);
g_hash_table_replace(stations, iwds->path, iwds);
@@ -1834,11 +1817,7 @@ static void create_ap(GDBusProxy *proxy)
const char *path = g_dbus_proxy_get_path(proxy);
struct iwd_ap *iwdap;
- iwdap = g_try_new0(struct iwd_ap, 1);
- if (!iwdap) {
- connman_error("Out of memory creating IWD access point");
- return;
- }
+ iwdap = g_new0(struct iwd_ap, 1);
iwdap->index = -1;
iwdap->path = g_strdup(path);
diff --git a/plugins/loopback.c b/plugins/loopback.c
index 3809d8f9..d0ed6268 100755
--- a/plugins/loopback.c
+++ b/plugins/loopback.c
@@ -63,14 +63,14 @@ static void _create_hostname(void)
fp = fopen(WIFI_MAC, "r");
if(!fp){
connman_error("Failed to get current hostname");
- strncpy(system_hostname, dev_id, strlen(dev_id));
+ strncpy(system_hostname, dev_id, sizeof(system_hostname) - 1);
return;
}
rv = fgets(wifi_mac, HOST_NAME_MAX, fp);
if(!rv){
connman_error("Failed to get current hostname");
- strncpy(system_hostname, dev_id, strlen(dev_id));
+ strncpy(system_hostname, dev_id, sizeof(system_hostname) - 1);
fclose(fp);
return;
}
diff --git a/plugins/neard.c b/plugins/neard.c
index 45effd44..caaea853 100755
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -223,9 +223,9 @@ static DBusMessage *create_request_oob_reply(DBusMessage *message)
DBusMessageIter dict;
const char *ssid, *psk;
uint8_t *tlv_msg;
- int length;
+ int length, freq;
- if (!connman_technology_get_wifi_tethering(&ssid, &psk))
+ if (!connman_technology_get_wifi_tethering(NULL, &ssid, &psk, &freq))
return get_reply_on_error(message, ENOTSUP);
tlv_msg = encode_to_tlv(ssid, psk, &length);
diff --git a/plugins/vpn.c b/plugins/vpn.c
index d708d1ff..42396d2a 100755
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -3,6 +3,7 @@
* Connection Manager
*
* Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019-2021 Jolla Ltd. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -491,6 +492,9 @@ static int errorstr2val(const char *error) {
if (g_strcmp0(error, CONNMAN_ERROR_INTERFACE ".AlreadyConnected") == 0)
return -EISCONN;
+ if (g_strcmp0(error, CONNMAN_ERROR_INTERFACE ".NoCarrier") == 0)
+ return -ENOLINK;
+
if (g_strcmp0(error, CONNMAN_ERROR_INTERFACE ".OperationCanceled") == 0)
return -ECANCELED;
@@ -529,16 +533,23 @@ static void connect_reply(DBusPendingCall *call, void *user_data)
if (dbus_set_error_from_message(&error, reply)) {
int err = errorstr2val(error.name);
+ switch (err) {
+ case -EINPROGRESS:
+ break;
/*
* ECANCELED means that user has canceled authentication
* dialog. That's not really an error, it's part of a normal
* workflow. We also take it as a request to turn autoconnect
* off, in case if it was on.
*/
- if (err == -ECANCELED) {
+ case -ECANCELED:
DBG("%s connect canceled", data->path);
connman_provider_set_autoconnect(data->provider, false);
- } else if (err != -EINPROGRESS) {
+ break;
+ case -ENOLINK: /* vpnd reports that connmand is not online. */
+ case -EISCONN:
+ case -ECONNREFUSED:
+ default:
connman_error("Connect reply: %s (%s)", error.message,
error.name);
DBG("data %p cb_data %p", data, cb_data);
@@ -1016,7 +1027,7 @@ static int disconnect_provider(struct connection_data *data)
if (data->disconnect_call) {
DBG("already disconnecting");
- return -EINVAL;
+ return -EALREADY;
}
message = dbus_message_new_method_call(VPN_SERVICE, data->path,
diff --git a/plugins/wifi.c b/plugins/wifi.c
index bcb93445..68f34313 100755
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -33,6 +33,10 @@
#include <net/ethernet.h>
#include <linux/wireless.h>
+#if defined TIZEN_EXT
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
#ifndef IFF_LOWER_UP
#define IFF_LOWER_UP 0x10000
#endif
@@ -98,20 +102,38 @@
* Weak : -77 ~ -82
* Very weak : -83 ~ -88
* No signal : -89 ~
+ *
+ * Wi-Fi Signal Strength (for 6G (dB))
+ *
+ * Excellent : ~ -72
+ * Good : -73 ~ -77
+ * Weak : -78 ~ -82
+ * Very weak : -83 ~ -88
+ * No signal : -89 ~
*/
+#define RSSI_LEVEL_2_6G -78
#define RSSI_LEVEL_2_5G -77
-#define RSSI_LEVEL_2_24G -75
+#define RSSI_LEVEL_2_2_4G -75
+#define RSSI_LEVEL_3_6G -73
#define RSSI_LEVEL_3_5G -68
-#define RSSI_LEVEL_3_24G -64
-#define WIFI_BSSID_STR_LEN 18
-#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
-#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+#define RSSI_LEVEL_3_2_4G -64
#define ROAM_SCAN_INTERVAL 60 /* 60 seconds */
+#define FREQUENCY_5G_BASE 5000
+#define FREQUENCY_6G_BASE 5925
+
+static int min_snr = 0;
+static int min_rssi_2_4GHz = 0;
+static int min_rssi_5GHz = 0;
+static int min_rssi_6GHz = 0;
#endif
static struct connman_technology *wifi_technology = NULL;
static struct connman_technology *p2p_technology = NULL;
+#if defined TIZEN_EXT
+static GSupplicantState assoc_last_state = G_SUPPLICANT_STATE_UNKNOWN;
+#endif
+
enum wifi_ap_capability{
WIFI_AP_UNKNOWN = 0,
WIFI_AP_SUPPORTED = 1,
@@ -211,6 +233,10 @@ struct wifi_data {
#endif
};
+struct wifi_network {
+ unsigned int keymgmt;
+};
+
struct disconnect_data {
struct wifi_data *wifi;
struct connman_network *network;
@@ -237,7 +263,6 @@ static bool wfd_service_registered = false;
static void start_autoscan(struct connman_device *device);
static int tech_set_tethering(struct connman_technology *technology,
- const char *identifier, const char *passphrase,
const char *bridge, bool enabled);
#if defined TIZEN_EXT
@@ -252,6 +277,8 @@ struct enc_method_call_data {
static struct enc_method_call_data encrypt_request_data;
+static GSupplicantSecurity network_security(const char *security);
+
static void encryption_request_reply(DBusPendingCall *call,
void *user_data)
{
@@ -2137,46 +2164,180 @@ static gboolean need_bss_transition(uint16_t freq, int snr, int strength)
/*
* If the currently connected AP matches the following conditions,
* scan for BSS transition is started.
- * - SNR is less than 20 or RSSI level is less than 3
+ * - SNR is less than min_snr or RSSI is less than
+ * min_rssi_2_4GHz, min_rssi_5GHz or min_rssi_6GHz.
*/
- if (snr < 20 && snr != 0)
+ if (min_snr != 0 && snr != 0 && snr < min_snr)
return TRUE;
- else if (freq > 4900 && signal <= RSSI_LEVEL_2_5G)
+ else if (freq > FREQUENCY_6G_BASE && signal <= min_rssi_6GHz)
return TRUE;
- else if (freq <= 4900 && signal <= RSSI_LEVEL_2_24G)
+ else if (freq > FREQUENCY_5G_BASE && signal <= min_rssi_5GHz)
+ return TRUE;
+ else if (signal <= min_rssi_2_4GHz)
return TRUE;
return FALSE;
}
-static gboolean check_bss_condition(uint16_t freq, int snr, uint16_t strength)
+static gboolean check_bss_diff(int cur_level, int sel_level, int to_5ghz,
+ unsigned int cur_est, unsigned int sel_est)
+{
+ int min_diff;
+ int diff;
+
+ /* This code is from wpa_supplicant. */
+ if (cur_level < -85) /* ..-86 dBm */
+ min_diff = 1;
+ else if (cur_level < -80) /* -85..-81 dBm */
+ min_diff = 2;
+ else if (cur_level < -75) /* -80..-76 dBm */
+ min_diff = 3;
+ else if (cur_level < -70) /* -75..-71 dBm */
+ min_diff = 4;
+ else if (cur_level < 0) /* -70..-1 dBm */
+ min_diff = 5;
+ else /* unspecified units (not in dBm) */
+ min_diff = 2;
+
+ if (cur_est > sel_est * 1.5)
+ min_diff += 10;
+ else if (cur_est > sel_est * 1.2)
+ min_diff += 5;
+ else if (cur_est > sel_est * 1.1)
+ min_diff += 2;
+ else if (cur_est > sel_est)
+ min_diff++;
+ else if (sel_est > cur_est * 1.5)
+ min_diff -= 10;
+ else if (sel_est > cur_est * 1.2)
+ min_diff -= 5;
+ else if (sel_est > cur_est * 1.1)
+ min_diff -= 2;
+ else if (sel_est > cur_est)
+ min_diff--;
+
+ if (to_5ghz)
+ min_diff -= 2;
+
+ diff = sel_level - cur_level;
+
+ if (diff < min_diff)
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean check_bss_condition(uint16_t freq, uint16_t strength,
+ unsigned int est_throughput, uint16_t cur_freq, uint16_t cur_strength,
+ unsigned int cur_est_throughput)
{
/*
* Since bssid->strength is a positive value,
* it need to be changed to its original value.
*/
int signal = strength - 120;
+ int cur_signal = cur_strength - 120;
+ int to_5ghz = freq > 4000 && cur_freq < 4000;
+
+ DBG("cur_freq=%d cur_level=%d cur_est=%d sel_freq=%d sel_level=%d sel_est=%d",
+ cur_freq, cur_strength, cur_est_throughput,
+ freq, strength, est_throughput);
/*
* If the AP that matches the following conditions exists in the SCAN result,
* BSS transition is started.
- * - SNR is 25 or more and RSSI level is greater than 3
*/
- if (snr < 25 && snr != 0)
- return FALSE;
- if (freq > 4900 && signal > RSSI_LEVEL_3_5G)
- return TRUE;
- else if (freq <= 4900 && signal > RSSI_LEVEL_3_24G)
+ if (est_throughput > cur_est_throughput + 5000)
return TRUE;
- return FALSE;
+ if (cur_signal > signal + to_5ghz * 2 &&
+ est_throughput < cur_est_throughput * 1.2)
+ return FALSE;
+
+ if (cur_est_throughput > est_throughput + 5000)
+ return FALSE;
+
+ return check_bss_diff(cur_signal, signal,
+ to_5ghz, cur_est_throughput, est_throughput);
}
static void scan_callback_hidden(int result,
GSupplicantInterface *interface, void *user_data);
static int network_disconnect(struct connman_network *network);
+
+static void start_roaming(struct wifi_data *wifi)
+{
+ bool roaming_ap_found = false;
+ GSList *bssid_list = NULL;
+
+ if (!wifi || !wifi->network)
+ return;
+
+ if (!connman_setting_get_bool("WifiRoaming"))
+ return;
+
+ struct connman_network *network = wifi->network;
+ bssid_list = connman_network_get_bssid_list(network);
+
+ if (g_slist_length(bssid_list) <= 1)
+ return;
+
+ if (!connman_network_get_connected(network))
+ return;
+
+ if (connman_network_get_bool(network, "WiFi.Roaming"))
+ return;
+
+ uint16_t cur_freq = connman_network_get_frequency(network);
+ uint8_t cur_strength = connman_network_get_strength(network);
+ unsigned int cur_est_throughput = connman_network_get_est_throughput(network);
+
+ if (!need_bss_transition(
+ cur_freq,
+ connman_network_get_snr(network),
+ cur_strength))
+ return;
+
+ unsigned char *cur_bssid = connman_network_get_bssid(network);
+
+ for (; bssid_list; bssid_list = bssid_list->next) {
+ struct g_connman_bssids *bssid = bssid_list->data;
+
+ if (memcmp(cur_bssid, bssid->bssid, WIFI_BSSID_LEN_MAX) == 0)
+ continue;
+
+ if (check_bss_condition(
+ bssid->frequency, bssid->strength, bssid->est_throughput,
+ cur_freq, cur_strength, cur_est_throughput)) {
+ roaming_ap_found = true;
+
+ char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+ char *bssid_str = bssid_buff;
+
+ snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid->bssid));
+ connman_network_set_string(network,
+ "WiFi.RoamingDstBSSID", bssid_str);
+ break;
+ }
+ }
+
+ if (roaming_ap_found) {
+ char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
+ char *bssid_str = bssid_buff;
+ unsigned char *bssid;
+
+ bssid = connman_network_get_bssid(network);
+ snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
+ connman_network_set_string(network,
+ "WiFi.RoamingCurBSSID", bssid_str);
+
+ network_disconnect(network);
+ wifi->pending_network = network;
+ connman_network_set_bool(network, "WiFi.Roaming", true);
+ }
+}
#endif
static void scan_callback(int result, GSupplicantInterface *interface,
@@ -2186,10 +2347,7 @@ static void scan_callback(int result, GSupplicantInterface *interface,
struct wifi_data *wifi = connman_device_get_data(device);
bool scanning;
#if defined TIZEN_EXT
- bool roaming_needed = false;
- bool roaming_ap_found = false;
GSList *list = NULL;
- GSList *bssid_list = NULL;
bool favorite_exists = false;
struct connman_network *network = NULL;
struct connman_service *service = NULL;
@@ -2306,46 +2464,8 @@ static void scan_callback(int result, GSupplicantInterface *interface,
network_connect(wifi->scan_pending_network);
wifi->scan_pending_network = NULL;
connman_network_set_connecting(wifi->network);
- } else if (connman_setting_get_bool("WifiRoaming") && wifi->network) {
- bssid_list = connman_network_get_bssid_list(wifi->network);
-
- if (g_slist_length(bssid_list) <= 1)
- goto done;
-
- if (!connman_network_get_connected(wifi->network))
- goto done;
-
- if (connman_network_get_bool(wifi->network, "WiFi.Roaming"))
- goto done;
-
- if (!need_bss_transition(
- connman_network_get_frequency(wifi->network),
- connman_network_get_snr(wifi->network),
- connman_network_get_strength(wifi->network)))
- goto done;
-
- for (bssid_list; bssid_list; bssid_list = bssid_list->next) {
- struct g_connman_bssids *bssid = bssid_list->data;
-
- if (check_bss_condition(bssid->frequency,
- bssid->score_snr, bssid->strength))
- roaming_ap_found = true;
- }
-
- if (roaming_ap_found) {
- char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
- char *bssid_str = bssid_buff;
- unsigned char *bssid;
-
- bssid = connman_network_get_bssid(wifi->network);
- snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
- connman_network_set_string(wifi->network,
- "WiFi.RoamingCurBSSID", bssid_str);
-
- network_disconnect(wifi->network);
- wifi->pending_network = wifi->network;
- connman_network_set_bool(wifi->network, "WiFi.Roaming", true);
- }
+ } else {
+ start_roaming(wifi);
}
done:
@@ -2613,7 +2733,20 @@ static void interface_create_callback(int result,
wifi->interface = interface;
g_supplicant_interface_set_data(interface, wifi);
+#ifdef TIZEN_EXT
+ if (!interface)
+ return;
+
+ if (wifi->device &&
+ !connman_device_get_wifi_5ghz_supported(wifi->device) &&
+ !connman_device_get_wifi_6ghz_supported(wifi->device)) {
+ bool is_5_0_ghz_supported = g_supplicant_interface_get_is_5_0_ghz_supported(interface);
+ bool is_6_0_ghz_supported = g_supplicant_interface_get_is_6_0_ghz_supported(interface);
+ connman_device_set_wifi_5ghz_supported(wifi->device, is_5_0_ghz_supported);
+ connman_device_set_wifi_6ghz_supported(wifi->device, is_6_0_ghz_supported);
+ }
+#endif
if (g_supplicant_interface_get_ready(interface)) {
wifi->interface_ready = true;
finalize_interface_creation(wifi);
@@ -2787,7 +2920,12 @@ static int get_latest_connections(int max_ssids,
g_key_file_free(keyfile);
continue;
}
+#if defined TIZEN_EXT
+
+ util_iso8601_to_timeval(str, (struct timeval *)&modified);
+#else
util_iso8601_to_timeval(str, &modified);
+#endif
g_free(str);
ssid = g_key_file_get_string(keyfile,
@@ -2957,7 +3095,7 @@ static void specific_scan_callback(int result, GSupplicantInterface *interface,
struct wifi_data *wifi = connman_device_get_data(device);
bool scanning;
- DBG("result %d wifi %p", result, wifi);
+ DBG("result %d device %p wifi %p", result, device, wifi);
if (wifi && wifi->scan_params) {
g_supplicant_free_scan_params(wifi->scan_params);
@@ -2971,6 +3109,8 @@ static void specific_scan_callback(int result, GSupplicantInterface *interface,
CONNMAN_SERVICE_TYPE_WIFI, false);
connman_device_unref(device);
}
+
+ start_roaming(wifi);
}
static int wifi_specific_scan(enum connman_service_type type,
@@ -3052,7 +3192,7 @@ static int wifi_specific_scan(enum connman_service_type type,
count = 0;
for (list = specific_scan_list; list; list = list->next) {
- freq = (int)list->data;
+ freq = GPOINTER_TO_INT(list->data);
scan_params->freqs[count] = freq;
DBG("scan_params->freqs[%d]: %d", count, scan_params->freqs[count]);
@@ -3633,6 +3773,11 @@ static void network_remove(struct connman_network *network)
{
struct connman_device *device = connman_network_get_device(network);
struct wifi_data *wifi;
+#if defined TIZEN_EXT
+ GSupplicantSSID *ssid;
+ const void *ssid_data;
+ const char *security;
+#endif
DBG("network %p", network);
@@ -3653,6 +3798,35 @@ static void network_remove(struct connman_network *network)
if (wifi->scan_pending_network == network)
wifi->scan_pending_network = NULL;
+
+ /*
+ * If this remove network is for the same network
+ * for which wpa_supplicant already has a profile
+ * then need to remove that profile.
+ */
+ ssid = g_try_malloc0(sizeof(GSupplicantSSID));
+ if (!ssid)
+ return;
+
+ ssid_data = connman_network_get_blob(network, "WiFi.SSID",
+ &ssid->ssid_len);
+
+ ssid->ssid = g_try_malloc0(ssid->ssid_len);
+
+ if (!ssid->ssid) {
+ g_free(ssid);
+ return;
+ } else {
+ memcpy(ssid->ssid, ssid_data, ssid->ssid_len);
+ }
+
+ security = connman_network_get_string(network, "WiFi.Security");
+ ssid->security = network_security(security);
+
+ g_supplicant_interface_remove_network(wifi->interface, ssid);
+
+ g_free(ssid->ssid);
+ g_free(ssid);
#endif
}
@@ -3751,6 +3925,8 @@ static GSupplicantSecurity network_security(const char *security)
return G_SUPPLICANT_SECURITY_OWE;
else if (g_str_equal(security, "dpp"))
return G_SUPPLICANT_SECURITY_DPP;
+ else if (g_str_equal(security, "psk_sha256") == TRUE)
+ return G_SUPPLICANT_SECURITY_PSK_SHA256;
#endif
return G_SUPPLICANT_SECURITY_UNKNOWN;
@@ -3773,6 +3949,7 @@ static GSupplicantEapKeymgmt network_eap_keymgmt(const char *security)
static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
{
+ struct wifi_network *network_data = connman_network_get_data(network);
const char *security;
#if defined TIZEN_EXT
const void *ssid_data;
@@ -3795,10 +3972,14 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
#endif
ssid->scan_ssid = 1;
security = connman_network_get_string(network, "WiFi.Security");
- ssid->security = network_security(security);
#if defined TIZEN_EXT
- ssid->ieee80211w = 1;
+ if (connman_network_get_psk_sha256(network))
+ security = "psk_sha256";
#endif
+ ssid->security = network_security(security);
+
+ ssid->keymgmt = network_data->keymgmt;
+ ssid->ieee80211w = G_SUPPLICANT_MFP_OPTIONAL;
ssid->passphrase = connman_network_get_string(network,
"WiFi.Passphrase");
@@ -3880,14 +4061,24 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
}
GSList *list;
- char buff[MAC_ADDRESS_LENGTH];
+ char buff[WIFI_BSSID_STR_LEN];
+ const char *dst_bssid = connman_network_get_string(network,
+ "WiFi.RoamingDstBSSID");
for (list = bssid_list; list; list = list->next) {
struct connman_bssids * bssids = (struct connman_bssids *)list->data;
- g_snprintf(buff, MAC_ADDRESS_LENGTH, "%02x:%02x:%02x:%02x:%02x:%02x",
- bssids->bssid[0], bssids->bssid[1], bssids->bssid[2],
- bssids->bssid[3], bssids->bssid[4], bssids->bssid[5]);
- buff[MAC_ADDRESS_LENGTH - 1] = '\0';
+ g_snprintf(buff, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssids->bssid));
+ buff[WIFI_BSSID_STR_LEN - 1] = '\0';
+
+ if (dst_bssid) {
+ if (g_strcmp0(dst_bssid, (const gchar *)buff) == 0) {
+ memcpy(buff_bssid, bssids->bssid, WIFI_BSSID_LEN_MAX);
+ ssid->bssid = buff_bssid;
+ ssid->freq = (unsigned int)bssids->frequency;
+ break;
+ }
+ continue;
+ }
gchar *curr_bssid = g_strdup((const gchar *)buff);
@@ -3905,6 +4096,9 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
}
}
+ if (dst_bssid)
+ connman_network_set_string(network, "WiFi.RoamingDstBSSID", NULL);
+
if (!list) {
ssid->bssid = connman_network_get_bssid(network);
g_hash_table_remove_all(failed_bssids);
@@ -3917,7 +4111,7 @@ done:
connman_network_get_string(network, "WiFi.KeymgmtType"));
ssid->phase1 = connman_network_get_string(network, "WiFi.Phase1");
- if(g_strcmp0(ssid->eap, "fast") == 0)
+ if (g_strcmp0(ssid->eap, "fast") == 0)
ssid->pac_file = g_strdup(WIFI_EAP_FAST_PAC_FILE);
ssid->keymgmt = connman_network_get_keymgmt(network);
@@ -3978,7 +4172,7 @@ static void disconnect_callback(int result, GSupplicantInterface *interface,
struct connman_network *network = dd->network;
#if defined TIZEN_EXT
GList *list;
- struct wifi_data *wifi;
+ struct wifi_data *wifi = NULL;
g_free(dd);
DBG("network %p result %d", network, result);
@@ -3986,6 +4180,9 @@ static void disconnect_callback(int result, GSupplicantInterface *interface,
for (list = iface_list; list; list = list->next) {
wifi = list->data;
+ if (!wifi)
+ continue;
+
if (wifi->network == NULL && wifi->disconnecting == true)
wifi->disconnecting = false;
@@ -3993,6 +4190,9 @@ static void disconnect_callback(int result, GSupplicantInterface *interface,
goto found;
}
+ if (wifi && network == wifi->pending_network)
+ wifi->pending_network = NULL;
+
/* wifi_data may be invalid because wifi is already disabled */
return;
@@ -4012,9 +4212,8 @@ found:
}
#if defined TIZEN_EXT
- if (wifi->network &&
- (wifi->network != wifi->pending_network ||
- connman_network_get_bool(wifi->network, "WiFi.Roaming")))
+ if (g_slist_find(wifi->networks, network) &&
+ wifi->network != wifi->pending_network)
#else
if (g_slist_find(wifi->networks, network))
#endif
@@ -4174,7 +4373,7 @@ static void set_connection_mode(struct connman_network *network,
}
static void signalpoll_callback(int result, int maxspeed, int strength,
- int snr, void *user_data)
+ int snr, void *user_data, unsigned int est_throughput)
{
char bssid_buff[WIFI_BSSID_STR_LEN] = {0,};
char *bssid_str = bssid_buff;
@@ -4184,7 +4383,10 @@ static void signalpoll_callback(int result, int maxspeed, int strength,
const char *interface = NULL;
struct connman_device *device;
struct connman_network *network = user_data;
+ GSupplicantNetwork *supplicant_network;
+ struct wifi_data *wifi = NULL;
uint16_t freq = connman_network_get_frequency(network);
+ const char *group = connman_network_get_group(network);
if (result != 0) {
DBG("Failed to get maxspeed from signalpoll !");
@@ -4192,30 +4394,45 @@ static void signalpoll_callback(int result, int maxspeed, int strength,
return;
}
+ device = connman_network_get_device(network);
+ if (device)
+ wifi = connman_device_get_data(device);
+
+ if (group && wifi) {
+ supplicant_network = g_supplicant_interface_get_network(wifi->interface, group);
+ if (supplicant_network) {
+ g_supplicant_network_set_signal(supplicant_network, strength);
+ g_supplicant_network_set_bss_signal(supplicant_network, strength, snr);
+ }
+ }
+
strength += 120;
if (strength > 100)
strength = 100;
- DBG("freq = %u, maxspeed = %d, strength = %d, snr = %d", freq, maxspeed, strength, snr);
+ bssid = connman_network_get_bssid(network);
+ snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
+
+ DBG("network %p, bssid %s, freq %u, maxspeed %d, strength %d, snr %d, est_throughput %u",
+ network, bssid_str, freq, maxspeed, strength, snr, est_throughput);
connman_network_set_strength(network, (uint8_t)strength);
connman_network_set_snr(network, snr);
+ connman_network_set_est_throughput(network, est_throughput);
connman_network_set_maxspeed(network, maxspeed);
set_connection_mode(network, maxspeed);
+ if (connman_network_get_max_bssid_count(network) <= 1)
+ goto done;
+
clock_gettime(CLOCK_MONOTONIC, &curr_time);
roam_scan_time = connman_network_get_roam_scan_time(network);
if (curr_time.tv_sec <= roam_scan_time + ROAM_SCAN_INTERVAL)
goto done;
- if (need_bss_transition(freq, snr, strength)) {
- device = connman_network_get_device(network);
- if (!device)
- goto done;
+ if (device && need_bss_transition(freq, snr, strength)) {
interface = connman_device_get_string(device, "Interface");
- bssid = connman_network_get_bssid(network);
- snprintf(bssid_str, WIFI_BSSID_STR_LEN, MACSTR, MAC2STR(bssid));
__connman_technology_notify_roaming_state(interface, "required", bssid_str, NULL);
if (connman_setting_get_bool("WifiRoamingScan") == false)
@@ -4296,6 +4513,7 @@ static void interface_added(GSupplicantInterface *interface)
#if defined TIZEN_EXT
bool is_5_0_ghz_supported = g_supplicant_interface_get_is_5_0_ghz_supported(interface);
+ bool is_6_0_ghz_supported = g_supplicant_interface_get_is_6_0_ghz_supported(interface);
#endif
struct wifi_data *wifi;
@@ -4323,6 +4541,7 @@ static void interface_added(GSupplicantInterface *interface)
connman_device_set_powered(wifi->device, true);
#if defined TIZEN_EXT
connman_device_set_wifi_5ghz_supported(wifi->device, is_5_0_ghz_supported);
+ connman_device_set_wifi_6ghz_supported(wifi->device, is_6_0_ghz_supported);
/* Max number of SSIDs supported by wlan chipset that can be scanned */
int max_scan_ssids = g_supplicant_interface_get_max_scan_ssids(interface);
connman_device_set_max_scan_ssids(wifi->device, max_scan_ssids);
@@ -4458,10 +4677,12 @@ static bool handle_wps_completion(GSupplicantInterface *interface,
static bool handle_assoc_status_code(GSupplicantInterface *interface,
struct wifi_data *wifi)
{
- if (wifi->state == G_SUPPLICANT_STATE_ASSOCIATING &&
#if defined TIZEN_EXT
- wifi->assoc_code > 0 &&
+ if ((wifi->state == G_SUPPLICANT_STATE_ASSOCIATING ||
+ wifi->state == G_SUPPLICANT_STATE_AUTHENTICATING ||
+ wifi->state == G_SUPPLICANT_STATE_ASSOCIATED) &&
#else
+ if (wifi->state == G_SUPPLICANT_STATE_ASSOCIATING &&
wifi->assoc_code == ASSOC_STATUS_NO_CLIENT &&
#endif
wifi->load_shaping_retries < LOAD_SHAPING_MAX_RETRIES) {
@@ -4548,6 +4769,9 @@ static bool handle_wifi_assoc_retry(struct connman_network *network,
return false;
}
+ if (wifi->state > assoc_last_state)
+ assoc_last_state = wifi->state;
+
if (++wifi->assoc_retry_count >= TIZEN_ASSOC_RETRY_COUNT) {
wifi->assoc_retry_count = 0;
@@ -4555,7 +4779,7 @@ static bool handle_wifi_assoc_retry(struct connman_network *network,
* however QA team recommends that the invalid-key error
* might be better to display for user experience.
*/
- switch (wifi->state) {
+ switch (assoc_last_state) {
case G_SUPPLICANT_STATE_AUTHENTICATING:
connman_network_set_error(network, CONNMAN_NETWORK_ERROR_AUTHENTICATE_FAIL);
break;
@@ -4572,6 +4796,65 @@ static bool handle_wifi_assoc_retry(struct connman_network *network,
return true;
}
+
+static void handle_wifi_roaming_complete(struct connman_network *network)
+{
+ const char *cur_bssid;
+ const char *dst_bssid;
+ const char *ifname;
+ struct connman_device *device;
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig_ipv4;
+ enum connman_ipconfig_type type;
+ enum connman_ipconfig_method method;
+
+ if (!connman_setting_get_bool("WifiRoaming") ||
+ !connman_network_get_bool(network, "WiFi.Roaming"))
+ return;
+
+ device = connman_network_get_device(network);
+ if (device) {
+ ifname = connman_device_get_string(device, "Interface");
+ cur_bssid = connman_network_get_string(network,
+ "WiFi.RoamingCurBSSID");
+ dst_bssid = connman_network_get_string(network,
+ "WiFi.RoamingDstBSSID");
+ }
+
+ if (device && ifname && cur_bssid && dst_bssid) {
+ __connman_technology_notify_roaming_state(ifname,
+ "success", cur_bssid, dst_bssid);
+ connman_network_set_bool(network,
+ "WiFi.Roaming", false);
+ connman_network_set_string(network,
+ "WiFi.RoamingCurBSSID", NULL);
+ connman_network_set_string(network,
+ "WiFi.RoamingDstBSSID", NULL);
+
+ service = connman_service_lookup_from_network(network);
+ if (!service)
+ return;
+
+ ipconfig_ipv4 = __connman_service_get_ip4config(service);
+ if (!ipconfig_ipv4) {
+ connman_error("Service has no IPv4 configuration");
+ return;
+ }
+
+ type = __connman_ipconfig_get_config_type(ipconfig_ipv4);
+ if (type != CONNMAN_IPCONFIG_TYPE_IPV4)
+ return;
+
+ method = __connman_ipconfig_get_method(ipconfig_ipv4);
+ if (method != CONNMAN_IPCONFIG_METHOD_DHCP)
+ return;
+
+ connman_network_set_bool(network, "WiFi.RoamingDHCP", true);
+
+ if (set_connected_dhcp(network) != 0)
+ connman_network_set_bool(network, "WiFi.RoamingDHCP", false);
+ }
+}
#endif
static void interface_state(GSupplicantInterface *interface)
@@ -4632,6 +4915,8 @@ static void interface_state(GSupplicantInterface *interface)
wifi->automaxspeed_timeout = 0;
DBG("Remove signalpoll timer!!");
}
+
+ if (!connman_network_get_bool(wifi->network, "WiFi.Roaming"))
#endif
if (wifi->connected)
connman_network_set_connected(network, false);
@@ -4645,7 +4930,9 @@ static void interface_state(GSupplicantInterface *interface)
#else
stop_autoscan(device);
#endif
-
+#if defined TIZEN_EXT
+ if (!connman_network_get_bool(wifi->network, "WiFi.Roaming"))
+#endif
if (!wifi->connected)
connman_network_set_associating(network, true);
@@ -4679,6 +4966,7 @@ static void interface_state(GSupplicantInterface *interface)
}
g_hash_table_remove_all(failed_bssids);
+ handle_wifi_roaming_complete(network);
#else
/* though it should be already stopped: */
stop_autoscan(device);
@@ -4720,19 +5008,22 @@ static void interface_state(GSupplicantInterface *interface)
break;
#if defined TIZEN_EXT
- if (handle_assoc_status_code(interface, wifi)) {
- const char *group = connman_network_get_group(network);
- GSupplicantNetwork *supplicant_network;
+ if (!wifi->connected && handle_assoc_status_code(interface, wifi)) {
GSList *bssid_list = NULL;
guint bssid_length = 0;
- if (group) {
- supplicant_network = g_supplicant_interface_get_network(interface, group);
+ if (TIZEN_INS_ENABLED) {
+ const char *group = connman_network_get_group(network);
+ GSupplicantNetwork *supplicant_network;
+
+ if (group) {
+ supplicant_network = g_supplicant_interface_get_network(interface, group);
- connman_network_set_assoc_reject_table(network,
- g_supplicant_network_get_assoc_reject_table(supplicant_network));
+ connman_network_set_assoc_reject_table(network,
+ g_supplicant_network_clone_assoc_reject_table(supplicant_network));
- g_supplicant_network_update_assoc_reject(interface, supplicant_network);
+ g_supplicant_network_update_assoc_reject(interface, supplicant_network);
+ }
}
bssid_list = (GSList *)connman_network_get_bssid_list(network);
@@ -4746,8 +5037,6 @@ static void interface_state(GSupplicantInterface *interface)
wifi->load_shaping_retries = 0;
}
-
- g_hash_table_remove_all(failed_bssids);
#else
if (handle_assoc_status_code(interface, wifi))
break;
@@ -4777,6 +5066,9 @@ static void interface_state(GSupplicantInterface *interface)
}
#if defined TIZEN_EXT
+ if (wifi->assoc_retry_count == 0)
+ assoc_last_state = G_SUPPLICANT_STATE_UNKNOWN;
+
/* Some of Wi-Fi networks are not comply Wi-Fi specification.
* Retry association until its retry count is expired */
if (handle_wifi_assoc_retry(network, wifi) == true) {
@@ -4785,7 +5077,7 @@ static void interface_state(GSupplicantInterface *interface)
break;
}
- if(wifi->disconnect_code > 0){
+ if (wifi->disconnect_code > 0){
DBG("Set disconnect reason code(%d)", wifi->disconnect_code);
connman_network_set_disconnect_reason(network, wifi->disconnect_code);
}
@@ -5053,8 +5345,6 @@ static void ap_create_fail(GSupplicantInterface *interface)
wifi->tethering = false;
ret = tech_set_tethering(wifi->tethering_param->technology,
- wifi->tethering_param->ssid->ssid,
- wifi->tethering_param->ssid->passphrase,
wifi->bridge, true);
if ((ret == -EOPNOTSUPP) && (wifi_technology)) {
@@ -5202,11 +5492,16 @@ static GSList *get_supported_security_list(unsigned int keymgmt,
sec_list = g_slist_prepend (sec_list, "psk");
sec_list = g_slist_prepend (sec_list, "rsn");
}
- } else if (keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_PSK)
+ }
+
+ if (keymgmt & G_SUPPLICANT_KEYMGMT_WPA_FT_PSK)
sec_list = g_slist_prepend (sec_list, "ft_psk");
if (keymgmt & G_SUPPLICANT_KEYMGMT_SAE)
sec_list = g_slist_prepend (sec_list, "sae");
+ if (keymgmt & G_SUPPLICANT_KEYMGMT_FT_SAE)
+ sec_list = g_slist_prepend (sec_list, "ft_sae");
+
if (keymgmt & G_SUPPLICANT_KEYMGMT_OWE || owe_transition_mode)
sec_list = g_slist_prepend (sec_list, "owe");
if (keymgmt & G_SUPPLICANT_KEYMGMT_DPP)
@@ -5229,6 +5524,7 @@ static void network_added(GSupplicantNetwork *supplicant_network)
struct connman_network *network;
GSupplicantInterface *interface;
struct wifi_data *wifi;
+ struct wifi_network *network_data;
const char *name, *identifier, *security, *group, *mode;
const unsigned char *ssid;
unsigned int ssid_len;
@@ -5307,8 +5603,15 @@ static void network_added(GSupplicantNetwork *supplicant_network)
}
wifi->networks = g_slist_prepend(wifi->networks, network);
+
+ network_data = g_new0(struct wifi_network, 1);
+ connman_network_set_data(network, network_data);
}
+ network_data = connman_network_get_data(network);
+ network_data->keymgmt =
+ g_supplicant_network_get_keymgmt(supplicant_network);
+
if (name && name[0] != '\0')
connman_network_set_name(network, name);
@@ -5324,6 +5627,11 @@ static void network_added(GSupplicantNetwork *supplicant_network)
connman_network_set_countrycode(network, country_code);
phy_mode = g_supplicant_network_get_phy_mode(supplicant_network);
connman_network_set_phy_mode(network, phy_mode);
+
+ if (g_strcmp0(security, "psk_sha256") == 0) {
+ connman_network_set_psk_sha256(network, true);
+ security = "psk";
+ }
#endif
connman_network_set_string(network, "WiFi.Security", security);
connman_network_set_strength(network,
@@ -5378,11 +5686,15 @@ static void network_added(GSupplicantNetwork *supplicant_network)
g_supplicant_network_is_hs20AP(supplicant_network));
connman_network_set_bssid_list(network,
(GSList *)g_supplicant_network_get_bssid_list(supplicant_network));
- connman_network_set_last_connected_bssid(network,
- g_supplicant_network_get_last_connected_bssid(supplicant_network));
- connman_network_set_assoc_reject_table(network,
- g_supplicant_network_get_assoc_reject_table(supplicant_network));
+
+ if (TIZEN_INS_ENABLED) {
+ connman_network_set_last_connected_bssid(network,
+ g_supplicant_network_get_last_connected_bssid(supplicant_network));
+ connman_network_set_assoc_reject_table(network,
+ g_supplicant_network_clone_assoc_reject_table(supplicant_network));
+ }
#endif
+
connman_network_set_available(network, true);
connman_network_set_string(network, "WiFi.Mode", mode);
@@ -5394,11 +5706,10 @@ static void network_added(GSupplicantNetwork *supplicant_network)
connman_network_set_group(network, group);
#if defined TIZEN_EXT
- g_supplicant_network_set_last_connected_bssid(supplicant_network,
- connman_network_get_last_connected_bssid(network));
-#endif
+ if (TIZEN_INS_ENABLED)
+ g_supplicant_network_set_last_connected_bssid(supplicant_network,
+ connman_network_get_last_connected_bssid(network));
-#if defined TIZEN_EXT
if (wifi_first_scan == true)
found_with_first_scan = true;
#endif
@@ -5476,6 +5787,7 @@ static void network_removed(GSupplicantNetwork *network)
wifi->networks = g_slist_remove(wifi->networks, connman_network);
+ g_free(connman_network_get_data(connman_network));
connman_device_remove_network(wifi->device, connman_network);
connman_network_unref(connman_network);
}
@@ -5558,38 +5870,39 @@ static void network_changed(GSupplicantNetwork *network, const char *property)
calculate_strength(network));
update_needed = true;
}
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
- else if (g_str_equal(property, "LastConnectedBSSID")) {
- const char *ident, *group;
- char *service_ident;
- bool need_save;
-
- ident = connman_device_get_ident(wifi->device);
- group = connman_network_get_group(connman_network);
- if (ident && group) {
- service_ident = g_strdup_printf("%s_%s_%s",
- __connman_network_get_type(connman_network), ident, group);
-
- need_save = connman_device_set_last_connected_ident(wifi->device, service_ident);
- if (need_save)
- connman_device_save_last_connected(wifi->device);
-
- g_free(service_ident);
- }
+#if defined TIZEN_EXT
+ else if (TIZEN_INS_ENABLED) {
+ if (g_str_equal(property, "LastConnectedBSSID")) {
+ const char *ident, *group;
+ char *service_ident;
+ bool need_save;
+
+ ident = connman_device_get_ident(wifi->device);
+ group = connman_network_get_group(connman_network);
+ if (ident && group) {
+ service_ident = g_strdup_printf("%s_%s_%s",
+ __connman_network_get_type(connman_network), ident, group);
+
+ need_save = connman_device_set_last_connected_ident(wifi->device, service_ident);
+ if (need_save)
+ connman_device_save_last_connected(wifi->device);
+
+ g_free(service_ident);
+ }
- connman_network_set_last_connected_bssid(connman_network,
+ connman_network_set_last_connected_bssid(connman_network,
g_supplicant_network_get_last_connected_bssid(network));
- update_needed = true;
- }
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
-#if defined TIZEN_EXT
- else if (g_str_equal(property, "UpdateAssocReject")) {
- connman_network_set_assoc_reject_table(connman_network,
- g_supplicant_network_get_assoc_reject_table(network));
- update_needed = true;
+ update_needed = true;
+ } else if (g_str_equal(property, "UpdateAssocReject")) {
+ connman_network_set_assoc_reject_table(connman_network,
+ g_supplicant_network_clone_assoc_reject_table(network));
+ update_needed = true;
+ } else {
+ update_needed = false;
+ }
}
-#endif
+#endif /* defined TIZEN_EXT */
else
update_needed = false;
@@ -6167,14 +6480,27 @@ static void tech_remove(struct connman_technology *technology)
wifi_technology = NULL;
}
-static GSupplicantSSID *ssid_ap_init(const char *ssid, const char *passphrase)
+static GSupplicantSSID *ssid_ap_init(const struct connman_technology *technology)
{
GSupplicantSSID *ap;
+ const char *ssid, *passphrase;
+ int freq;
+ bool ret;
ap = g_try_malloc0(sizeof(GSupplicantSSID));
if (!ap)
return NULL;
+ ret = connman_technology_get_wifi_tethering(technology,
+ &ssid, &passphrase,
+ &freq);
+ if (ret == false) {
+#if defined TIZEN_EXT
+ g_free(ap);
+#endif
+ return NULL;
+ }
+
ap->mode = G_SUPPLICANT_MODE_MASTER;
#if defined TIZEN_EXT
ap->ssid = (void *) ssid;
@@ -6183,7 +6509,10 @@ static GSupplicantSSID *ssid_ap_init(const char *ssid, const char *passphrase)
#endif
ap->ssid_len = strlen(ssid);
ap->scan_ssid = 0;
- ap->freq = 2412;
+ if (freq)
+ ap->freq = freq;
+ else
+ ap->freq = 2412;
if (!passphrase || strlen(passphrase) == 0) {
ap->security = G_SUPPLICANT_SECURITY_NONE;
@@ -6296,8 +6625,7 @@ static void sta_remove_callback(int result,
}
static int enable_wifi_tethering(struct connman_technology *technology,
- const char *bridge, const char *identifier,
- const char *passphrase, bool available)
+ const char *bridge, bool available)
{
GList *list;
GSupplicantInterface *interface;
@@ -6350,14 +6678,14 @@ static int enable_wifi_tethering(struct connman_technology *technology,
info->wifi = wifi;
info->technology = technology;
info->wifi->bridge = bridge;
- info->ssid = ssid_ap_init(identifier, passphrase);
+ info->ssid = ssid_ap_init(technology);
if (!info->ssid)
goto failed;
info->ifname = g_strdup(ifname);
wifi->tethering_param->technology = technology;
- wifi->tethering_param->ssid = ssid_ap_init(identifier, passphrase);
+ wifi->tethering_param->ssid = ssid_ap_init(technology);
if (!wifi->tethering_param->ssid)
goto failed;
@@ -6399,7 +6727,6 @@ static int enable_wifi_tethering(struct connman_technology *technology,
}
static int tech_set_tethering(struct connman_technology *technology,
- const char *identifier, const char *passphrase,
const char *bridge, bool enabled)
{
GList *list;
@@ -6427,13 +6754,11 @@ static int tech_set_tethering(struct connman_technology *technology,
}
DBG("trying tethering for available devices");
- err = enable_wifi_tethering(technology, bridge, identifier, passphrase,
- true);
+ err = enable_wifi_tethering(technology, bridge, true);
if (err < 0) {
DBG("trying tethering for any device");
- err = enable_wifi_tethering(technology, bridge, identifier,
- passphrase, false);
+ err = enable_wifi_tethering(technology, bridge, false);
}
return err;
@@ -6457,7 +6782,7 @@ static int tech_set_regdom(struct connman_technology *technology, const char *al
return g_supplicant_set_country(alpha2, regdom_callback, NULL);
}
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
static void supp_ins_init(void)
{
const char *string;
@@ -6479,10 +6804,10 @@ static void supp_ins_init(void)
connman_setting_get_uint("INSLastConnectedBSSIDScore"),
connman_setting_get_uint("INSAssocRejectScore"),
connman_setting_get_int("INSSignalLevel3_5GHz"),
- connman_setting_get_int("INSSignalLevel3_24GHz")
+ connman_setting_get_int("INSSignalLevel3_2_4GHz")
);
}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
static struct connman_technology_driver tech_driver = {
.name = "wifi",
@@ -6516,11 +6841,27 @@ static int wifi_init(void)
#if defined TIZEN_EXT
failed_bssids = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
-#endif
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
- supp_ins_init();
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+ min_snr = connman_setting_get_int("WifiRoamingMinSNR");
+
+ min_rssi_2_4GHz = connman_setting_get_int("WifiRoamingMinRSSI_2_4GHz");
+ if (min_rssi_2_4GHz >= 0)
+ min_rssi_2_4GHz = RSSI_LEVEL_2_2_4G;
+
+ min_rssi_5GHz = connman_setting_get_int("WifiRoamingMinRSSI_5GHz");
+ if (min_rssi_5GHz >= 0)
+ min_rssi_5GHz = RSSI_LEVEL_2_5G;
+
+ min_rssi_6GHz = connman_setting_get_int("WifiRoamingMinRSSI_6GHz");
+ if (min_rssi_6GHz >= 0)
+ min_rssi_6GHz = RSSI_LEVEL_2_6G;
+
+ DBG("Min SNR: %d, Min RSSI: %d(2.4GHz), %d(5GHz), %d(6GHz)",
+ min_snr, min_rssi_2_4GHz, min_rssi_5GHz, min_rssi_6GHz);
+
+ if (TIZEN_INS_ENABLED)
+ supp_ins_init();
+#endif /* defined TIZEN_EXT */
return 0;
}
diff --git a/resources/var/lib/connman/settings b/resources/var/lib/connman/settings
index ba476b5d..13684c9f 100644
--- a/resources/var/lib/connman/settings
+++ b/resources/var/lib/connman/settings
@@ -1,6 +1,7 @@
[global]
OfflineMode=false
+Timeservers=pool.ntp.org;
[WiFi]
Enable=false
diff --git a/src/agent.c b/src/agent.c
index d6113af7..d4f9add4 100755
--- a/src/agent.c
+++ b/src/agent.c
@@ -366,9 +366,9 @@ static void report_error_reply(DBusMessage *reply, void *user_data)
retry = true;
}
+out:
report_error->callback(report_error->user_context, retry,
report_error->user_data);
-out:
g_free(report_error);
}
diff --git a/src/clock.c b/src/clock.c
index 58a52c0e..54552cab 100755
--- a/src/clock.c
+++ b/src/clock.c
@@ -119,6 +119,17 @@ static void clock_properties_load(void)
g_free(str);
+#if defined TIZEN_EXT
+ str = g_key_file_get_string(keyfile, "global", "Timeservers", NULL);
+
+ if (str && str[0] == ';') {
+ DBG("Set time_updates_config to MANUAL.");
+ time_updates_config = TIME_UPDATES_MANUAL;
+ }
+
+ g_free(str);
+#endif
+
g_key_file_free(keyfile);
}
@@ -387,6 +398,21 @@ static DBusMessage *set_property(DBusConnection *conn,
__connman_timeserver_system_set(str);
+#if defined TIZEN_EXT
+ if (str) {
+ if (str[0][0] == '\0') {
+ DBG("Set time_updates_config to MANUAL.");
+ time_updates_config = TIMEZONE_UPDATES_MANUAL;
+ } else {
+ DBG("Set time_updates_config to AUTO.");
+ time_updates_config = TIMEZONE_UPDATES_AUTO;
+ }
+ } else {
+ DBG("Set time_updates_config to MANUAL.");
+ time_updates_config = TIMEZONE_UPDATES_MANUAL;
+ }
+#endif
+
if (str)
g_strfreev(str);
diff --git a/src/config.c b/src/config.c
index 993f4f6b..afcb0cce 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1167,8 +1167,7 @@ static char *config_pem_fsid(const char *pem_file)
static void provision_service_wifi(struct connman_config_service *config,
struct connman_service *service,
- struct connman_network *network,
- const void *ssid, unsigned int ssid_len)
+ struct connman_network *network)
{
if (config->eap)
__connman_service_set_string(service, "EAP", config->eap);
@@ -1541,8 +1540,7 @@ ipv4_out:
config->timeservers);
if (type == CONNMAN_SERVICE_TYPE_WIFI) {
- provision_service_wifi(config, service, network,
- ssid, ssid_len);
+ provision_service_wifi(config, service, network);
}
__connman_service_mark_dirty();
diff --git a/src/connman-robot.conf b/src/connman-robot.conf
index b089f404..7a2e4caf 100644
--- a/src/connman-robot.conf
+++ b/src/connman-robot.conf
@@ -15,6 +15,7 @@
<allow send_destination="net.connman" send_type="signal"/>
<allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="GetScanState" />
<allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="Get5GhzSupported" />
+ <allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="Get6GHzSupported" />
<allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="GetMaxScanSsid" />
<allow send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetTechnologies" />
@@ -27,6 +28,7 @@
<allow send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetDisconnectedMeshPeers" />
<allow send_destination="net.connman" send_interface="net.connman.Manager" send_member="MeshAddPeer" />
<allow send_destination="net.connman" send_interface="net.connman.Manager" send_member="MeshRemovePeer" />
+ <allow send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetDhcpStatus" />
<allow send_destination="net.connman" send_interface="net.connman.Service" send_member="Connect" />
<allow send_destination="net.connman" send_interface="net.connman.Service" send_member="Disconnect" />
<allow send_destination="net.connman" send_interface="net.connman.Service" send_member="SetProperty" />
@@ -40,5 +42,6 @@
<allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="SetBSSID" />
<allow send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetInterfaces" />
<allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="MeshCommands" />
+ <allow send_destination="net.connman" send_interface="net.connman.Clock" send_member="GetProperties" />
</policy>
</busconfig>
diff --git a/src/connman.conf b/src/connman.conf
index 267a4fcd..7cc819e2 100644
--- a/src/connman.conf
+++ b/src/connman.conf
@@ -15,9 +15,11 @@
<allow send_destination="net.connman" send_type="signal"/>
<allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="GetScanState" />
<allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="Get5GhzSupported" />
+ <allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="Get6GHzSupported" />
<allow send_destination="net.connman" send_interface="net.connman.Technology" send_member="GetMaxScanSsid" />
<check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetTechnologies" privilege="http://tizen.org/privilege/network.get" />
+ <check send_destination="net.connman" send_interface="net.connman.Manager" send_member="SetProperty" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetProperties" privilege="http://tizen.org/privilege/network.get" />
<check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetServices" privilege="http://tizen.org/privilege/network.get" />
<check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetDefaultService" privilege="http://tizen.org/privilege/network.get" />
@@ -27,12 +29,15 @@
<check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetDisconnectedMeshPeers" privilege="http://tizen.org/privilege/network.get" />
<check send_destination="net.connman" send_interface="net.connman.Manager" send_member="MeshAddPeer" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.connman" send_interface="net.connman.Manager" send_member="MeshRemovePeer" privilege="http://tizen.org/privilege/network.set" />
+ <check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetDhcpStatus" privilege="http://tizen.org/privilege/network.get" />
<check send_destination="net.connman" send_interface="net.connman.Service" send_member="Connect" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.connman" send_interface="net.connman.Service" send_member="Disconnect" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.connman" send_interface="net.connman.Service" send_member="SetProperty" privilege="http://tizen.org/privilege/network.profile" />
<check send_destination="net.connman" send_interface="net.connman.Service" send_member="GetProperties" privilege="http://tizen.org/privilege/network.get" />
<check send_destination="net.connman" send_interface="net.connman.Service" send_member="Remove" privilege="http://tizen.org/privilege/network.profile" />
<check send_destination="net.connman" send_interface="net.connman.Service" send_member="PropertyChanged" privilege="http://tizen.org/privilege/network.get" />
+ <check send_destination="net.connman" send_interface="net.connman.Technology" send_member="GetProperties" privilege="http://tizen.org/privilege/network.get" />
+ <check send_destination="net.connman" send_interface="net.connman.Technology" send_member="SetProperty" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.connman" send_interface="net.connman.Technology" send_member="Scan" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.connman" send_interface="net.connman.Technology" send_member="SpecificScan" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.connman" send_interface="net.connman.Technology" send_member="ScanDevice" privilege="http://tizen.org/privilege/network.set" />
@@ -40,5 +45,6 @@
<check send_destination="net.connman" send_interface="net.connman.Technology" send_member="SetBSSID" privilege="http://tizen.org/privilege/network.set" />
<check send_destination="net.connman" send_interface="net.connman.Manager" send_member="GetInterfaces" privilege="http://tizen.org/privilege/network.get" />
<check send_destination="net.connman" send_interface="net.connman.Technology" send_member="MeshCommands" privilege="http://tizen.org/privilege/network.set" />
+ <check send_destination="net.connman" send_interface="net.connman.Clock" send_member="GetProperties" privilege="http://tizen.org/privilege/network.get" />
</policy>
</busconfig>
diff --git a/src/connman.h b/src/connman.h
index 18c4fe0e..e6e16d11 100755
--- a/src/connman.h
+++ b/src/connman.h
@@ -598,6 +598,13 @@ void __connman_technology_notify_regdom_by_device(struct connman_device *device,
int result, const char *alpha2);
#if defined TIZEN_EXT
+void __connman_technology_notify_mac_policy_by_device(struct connman_device *device,
+ int result, unsigned int policy);
+void __connman_technology_notify_preassoc_mac_policy_by_device(struct connman_device *device,
+ int result, unsigned int policy);
+void __connman_technology_notify_random_mac_lifetime_by_device(struct connman_device *device,
+ int result, unsigned int lifetime);
+
enum bssid_type {
CHECK_BSSID = 0,
GET_BSSID = 1,
@@ -677,6 +684,12 @@ const char *__connman_network_get_group(struct connman_network *network);
const char *__connman_network_get_ident(struct connman_network *network);
bool __connman_network_get_weakness(struct connman_network *network);
bool __connman_network_native_autoconnect(struct connman_network *network);
+#if defined TIZEN_EXT
+char *__connman_network_get_dhcp_status(const char *ifname);
+dbus_bool_t __connman_network_notify_dhcp_changed(const char *key, const char *val);
+bool connman_network_get_psk_sha256(struct connman_network *network);
+void connman_network_set_psk_sha256(struct connman_network *network, bool is_psk_sha256);
+#endif
int __connman_config_init();
void __connman_config_cleanup(void);
@@ -745,11 +758,9 @@ int __connman_service_move(struct connman_service *service,
int __connman_service_load_modifiable(struct connman_service *service);
void __connman_service_list_struct(DBusMessageIter *iter);
-#if defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
void __connman_ins_list_struct(DBusMessageIter *iter);
-#endif
-#if defined TIZEN_EXT
int connman_service_get_ipv6_dns_method(struct connman_service *service);
enum connman_dnsconfig_method {
CONNMAN_DNSCONFIG_METHOD_UNKNOWN = 0,
diff --git a/src/dbus.c b/src/dbus.c
index c454a581..74b3157b 100755
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -687,7 +687,7 @@ int __connman_dbus_init(DBusConnection *conn)
connection = conn;
- return 0;
+ return g_dbus_attach_object_manager(conn);
}
void __connman_dbus_cleanup(void)
diff --git a/src/device.c b/src/device.c
index 51169001..da86084f 100755
--- a/src/device.c
+++ b/src/device.c
@@ -82,6 +82,7 @@ struct connman_device {
*/
int max_scan_ssids;
bool is_5_0_ghz_supported;
+ bool is_6_0_ghz_supported;
unsigned int mac_policy;
unsigned int preassoc_mac_policy;
unsigned int random_mac_lifetime;
@@ -387,6 +388,10 @@ static void remove_device(struct connman_device *device)
if (device->driver->remove)
device->driver->remove(device);
+#if defined TIZEN_EXT
+ __connman_technology_notify_device_detected_by_device(device, "", false);
+#endif
+
device->driver = NULL;
}
@@ -882,7 +887,7 @@ const char *connman_device_get_last_connected_ident(struct connman_device *devic
}
#endif
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
void connman_device_save_last_user_selection(struct connman_device *device)
{
GKeyFile *keyfile;
@@ -1016,7 +1021,7 @@ void connman_device_load_last_connected(struct connman_device *device)
g_key_file_free(keyfile);
}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
static void mark_network_available(gpointer key, gpointer value,
gpointer user_data)
@@ -1281,10 +1286,21 @@ void connman_device_set_wifi_5ghz_supported(struct connman_device *device,
device->is_5_0_ghz_supported = is_5_0_ghz_supported;
}
+void connman_device_set_wifi_6ghz_supported(struct connman_device *device,
+ bool is_6_0_ghz_supported)
+{
+ device->is_6_0_ghz_supported = is_6_0_ghz_supported;
+}
+
bool connman_device_get_wifi_5ghz_supported(struct connman_device *device)
{
return device->is_5_0_ghz_supported;
}
+
+bool connman_device_get_wifi_6ghz_supported(struct connman_device *device)
+{
+ return device->is_6_0_ghz_supported;
+}
#endif
/**
@@ -2050,10 +2066,12 @@ struct connman_device *connman_device_create_from_index(int index)
connman_device_set_index(device, index);
connman_device_set_interface(device, devname);
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
- connman_device_load_last_connected(device);
- connman_device_load_last_user_selection(device);
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#if defined TIZEN_EXT
+ if (TIZEN_INS_ENABLED) {
+ connman_device_load_last_connected(device);
+ connman_device_load_last_user_selection(device);
+ }
+#endif /* defined TIZEN_EXT */
if (ident) {
connman_device_set_ident(device, ident);
diff --git a/src/dhcp.c b/src/dhcp.c
index 5cef0387..5ad1efba 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -43,6 +43,12 @@
#define RATE_LIMIT_INTERVAL 60 /* delay between successive attempts */
+#if defined TIZEN_EXT
+#define DHCP_SUCCESS "DHCP_SUCCESS"
+#define DHCP_FAIL "DHCP_FAIL"
+#define DHCP_STARTED "DHCP_STARTED"
+#endif
+
struct connman_dhcp {
struct connman_ipconfig *ipconfig;
struct connman_network *network;
@@ -285,10 +291,26 @@ static void no_lease_cb(GDHCPClient *dhcp_client, gpointer user_data)
dhcp->ipv4ll_client);
#if defined TIZEN_EXT
+ if (dhcp->network &&
+ connman_network_get_bool(dhcp->network, "WiFi.RoamingDHCP")) {
+
+ connman_network_set_bool(dhcp->network, "WiFi.RoamingDHCP", false);
+ __connman_network_enable_ipconfig(dhcp->network, dhcp->ipconfig);
+ __connman_network_notify_dhcp_changed(DHCP_FAIL,
+ g_dhcp_client_get_interface(dhcp_client));
+
+ return;
+ }
+
if (connman_setting_get_bool("EnableAutoIp") == false) {
DBG("link-local address autoconfiguration is disabled.");
- if (dhcp->network)
- __connman_network_disconnect(dhcp->network);
+
+ if (dhcp->network) {
+ DBG("[DHCP-C] auto ip is not used, set dhcp-fail error and disconnect");
+ __connman_network_notify_dhcp_changed(DHCP_FAIL,
+ g_dhcp_client_get_interface(dhcp_client));
+ connman_network_set_error(dhcp->network, CONNMAN_NETWORK_ERROR_DHCP_FAIL);
+ }
return;
}
#endif
@@ -547,6 +569,8 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
#if defined TIZEN_EXT
__connman_ipconfig_set_dhcp_lease_duration(dhcp->ipconfig, dhcp_lease_duration);
+ __connman_network_notify_dhcp_changed(DHCP_SUCCESS,
+ g_dhcp_client_get_interface(dhcp_client));
#endif
/*
@@ -563,6 +587,17 @@ static void lease_available_cb(GDHCPClient *dhcp_client, gpointer user_data)
__connman_service_notify_ipv4_configuration(service);
}
+#if defined TIZEN_EXT
+ if (connman_network_get_bool(dhcp->network, "WiFi.RoamingDHCP")) {
+
+ if (ip_change)
+ connman_service_notify_reconnection_roaming(
+ connman_service_lookup_from_network(dhcp->network));
+
+ connman_network_set_bool(dhcp->network, "WiFi.RoamingDHCP", false);
+ }
+#endif
+
if (ip_change) {
__connman_ipconfig_set_local(dhcp->ipconfig, address);
__connman_ipconfig_set_prefixlen(dhcp->ipconfig, prefixlen);
@@ -622,6 +657,11 @@ static void ipv4ll_available_cb(GDHCPClient *ipv4ll_client, gpointer user_data)
g_free(address);
g_free(netmask);
+
+#if defined TIZEN_EXT
+ __connman_network_notify_dhcp_changed(DHCP_FAIL,
+ g_dhcp_client_get_interface(ipv4ll_client));
+#endif
}
static int dhcp_initialize(struct connman_dhcp *dhcp)
@@ -829,9 +869,18 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig,
dhcp->user_data = user_data;
#if defined TIZEN_EXT
- DBG("Start DHCP with DHCPDISCOVER request");
+ __connman_network_notify_dhcp_changed(DHCP_STARTED,
+ g_dhcp_client_get_interface(dhcp->dhcp_client));
- return g_dhcp_client_start(dhcp->dhcp_client, NULL);
+ if (network && connman_network_get_bool(network, "WiFi.RoamingDHCP")) {
+ const char *last_addr = __connman_ipconfig_get_dhcp_address(ipconfig);
+
+ DBG("Start DHCP with last address request");
+ return g_dhcp_client_start(dhcp->dhcp_client, last_addr);
+ } else {
+ DBG("Start DHCP with DHCPDISCOVER request");
+ return g_dhcp_client_start(dhcp->dhcp_client, NULL);
+ }
#else
return g_dhcp_client_start(dhcp->dhcp_client, last_addr);
#endif
diff --git a/src/dnsproxy.c b/src/dnsproxy.c
index 18dc6480..8e3ce973 100755
--- a/src/dnsproxy.c
+++ b/src/dnsproxy.c
@@ -1843,7 +1843,8 @@ static char *uncompress(int16_t field_count, char *start, char *end,
ulen = strlen(name) + 1;
if ((uptr + ulen) > uncomp_end)
goto out;
- strncpy(uptr, name, ulen);
+
+ memcpy(uptr, name, ulen);
debug("pos %d ulen %d left %d name %s", pos, ulen,
(int)(uncomp_end - (uptr + ulen)), uptr);
@@ -2003,6 +2004,12 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
if (offset < 0)
return offset;
+ if (reply_len < 0)
+ return -EINVAL;
+ if (reply_len < offset + 1)
+ return -EINVAL;
+ if ((size_t)reply_len < sizeof(struct domain_hdr))
+ return -EINVAL;
hdr = (void *)(reply + offset);
dns_id = reply[offset] | reply[offset + 1] << 8;
@@ -2038,23 +2045,31 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
*/
if (req->append_domain && ntohs(hdr->qdcount) == 1) {
uint16_t domain_len = 0;
- uint16_t header_len;
+ uint16_t header_len, payload_len;
uint16_t dns_type, dns_class;
uint8_t host_len, dns_type_pos;
char uncompressed[NS_MAXDNAME], *uptr;
char *ptr, *eom = (char *)reply + reply_len;
+ char *domain;
/*
* ptr points to the first char of the hostname.
* ->hostname.domain.net
*/
header_len = offset + sizeof(struct domain_hdr);
+ if (reply_len < header_len)
+ return -EINVAL;
+ payload_len = reply_len - header_len;
+
ptr = (char *)reply + header_len;
host_len = *ptr;
+ domain = ptr + 1 + host_len;
+ if (domain > eom)
+ return -EINVAL;
+
if (host_len > 0)
- domain_len = strnlen(ptr + 1 + host_len,
- reply_len - header_len);
+ domain_len = strnlen(domain, eom - domain);
/*
* If the query type is anything other than A or AAAA,
@@ -2063,6 +2078,8 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
*/
dns_type_pos = host_len + 1 + domain_len + 1;
+ if (ptr + (dns_type_pos + 3) > eom)
+ return -EINVAL;
dns_type = ptr[dns_type_pos] << 8 |
ptr[dns_type_pos + 1];
dns_class = ptr[dns_type_pos + 2] << 8 |
@@ -2092,6 +2109,8 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
int new_len, fixed_len;
char *answers;
+ if (len > payload_len)
+ return -EINVAL;
/*
* First copy host (without domain name) into
* tmp buffer.
@@ -2106,6 +2125,8 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
* Copy type and class fields of the question.
*/
ptr += len + domain_len + 1;
+ if (ptr + NS_QFIXEDSZ > eom)
+ return -EINVAL;
memcpy(uptr, ptr, NS_QFIXEDSZ);
/*
@@ -2115,6 +2136,8 @@ static int forward_dns_reply(unsigned char *reply, int reply_len, int protocol,
uptr += NS_QFIXEDSZ;
answers = uptr;
fixed_len = answers - uncompressed;
+ if (ptr + offset > eom)
+ return -EINVAL;
/*
* We then uncompress the result to buffer
@@ -2225,6 +2248,9 @@ out:
err = sendto(sk, req->resp, req->resplen, 0,
&req->sa, req->sa_len);
} else {
+ uint16_t tcp_len = htons(req->resplen - 2);
+ /* correct TCP message length */
+ memcpy(req->resp, &tcp_len, sizeof(tcp_len));
sk = req->client_sk;
err = send(sk, req->resp, req->resplen, MSG_NOSIGNAL);
}
@@ -2313,14 +2339,15 @@ static gboolean udp_server_event(GIOChannel *channel, GIOCondition condition,
len = recv(sk, buf, sizeof(buf), 0);
- if (len >= 12)
- forward_dns_reply(buf, len, IPPROTO_UDP, data);
+ forward_dns_reply(buf, len, IPPROTO_UDP, data);
#if defined TIZEN_EXT
GSList *list;
- for (list = server_list_sec; list; list = list->next) {
+ list = server_list_sec;
+ while (list) {
struct server_data *new_data = list->data;
+ list = list->next;
if (new_data == data) {
destroy_server_sec(data);
@@ -2408,14 +2435,21 @@ hangup:
}
}
+ /*
+ * Remove the G_IO_OUT flag from the watch, otherwise we end
+ * up in a busy loop, because the socket is constantly writable.
+ *
+ * There seems to be no better way in g_io to do that than
+ * re-adding the watch.
+ */
+ g_source_remove(server->watch);
+ server->watch = g_io_add_watch(server->channel,
+ G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
+ tcp_server_event, server);
+
server->connected = true;
server_list = g_slist_append(server_list, server);
- if (server->timeout > 0) {
- g_source_remove(server->timeout);
- server->timeout = 0;
- }
-
for (list = request_list; list; ) {
struct request_data *req = list->data;
int status;
@@ -2693,8 +2727,10 @@ static void destroy_all_server_sec()
DBG("remove all dns server");
- for (list = server_list_sec; list; list = list->next) {
+ list = server_list_sec;
+ while (list) {
struct server_data *server = list->data;
+ list = list->next;
destroy_server_sec(server);
}
server_list_sec = NULL;
@@ -2950,7 +2986,7 @@ static void update_domain(int index, const char *domain, bool append)
for (list = server_list; list; list = list->next) {
struct server_data *data = list->data;
GList *dom_list;
- char *dom;
+ char *dom = NULL;
bool dom_found = false;
if (data->index < 0)
diff --git a/src/inet.c b/src/inet.c
index 268dc513..b1c55b88 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -1984,13 +1984,6 @@ int __connman_inet_ipv6_send_rs(int index, int timeout,
return 0;
}
-static inline void ipv6_addr_advert_mult(const struct in6_addr *addr,
- struct in6_addr *advert)
-{
- ipv6_addr_set(advert, htonl(0xFF020000), 0, htonl(0x2),
- htonl(0xFF000000) | addr->s6_addr32[3]);
-}
-
#define MSG_SIZE_SEND 1452
static int inc_len(int len, int inc)
@@ -2454,7 +2447,7 @@ int connman_inet_get_dest_addr(int index, char **dest)
int connman_inet_ipv6_get_dest_addr(int index, char **dest)
{
struct interface_address if_addr = { 0 };
- struct in_addr dstaddr = { 0 };
+ struct in6_addr dstaddr = { 0 };
char buf[INET6_ADDRSTRLEN] = { 0 };
int err;
@@ -3516,6 +3509,10 @@ static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
for (pp = args; *pp; pp++) {
if (!strcmp(*pp, "root=/dev/nfs"))
break;
+ if (!strncmp(*pp, "root=/dev/nbd", strlen("root=/dev/nbd")))
+ break;
+ if (!strncmp(*pp, "nbddev=", strlen("nbddev=")))
+ break;
}
/* no rootnfs found */
if (!*pp)
@@ -3525,6 +3522,8 @@ static int get_nfs_server_ip(const char *cmdline_file, const char *pnp_file,
for (pp = args; *pp; pp++) {
if (!strncmp(*pp, "nfsroot=", strlen("nfsroot=")))
break;
+ if (!strncmp(*pp, "nbdroot=", strlen("nbdroot=")))
+ break;
}
/* no nfsroot argument found */
if (!*pp)
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 4a0e4ad0..9765ca14 100755
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -1638,6 +1638,9 @@ static void disable_ipv6(struct connman_ipconfig *ipconfig)
ifname = connman_inet_ifname(ipconfig->index);
+ if (!ifname)
+ return;
+
set_ipv6_state(ifname, false);
g_free(ifname);
@@ -1657,6 +1660,9 @@ static void enable_ipv6(struct connman_ipconfig *ipconfig)
ifname = connman_inet_ifname(ipconfig->index);
+ if (!ifname)
+ return;
+
if (ipconfig->method == CONNMAN_IPCONFIG_METHOD_AUTO)
set_ipv6_privacy(ifname, ipconfig->ipv6_privacy_config);
diff --git a/src/main.c b/src/main.c
index 13e26d46..8b0a995c 100755
--- a/src/main.c
+++ b/src/main.c
@@ -46,6 +46,9 @@
#define DEFAULT_INPUT_REQUEST_TIMEOUT (120 * 1000)
#define DEFAULT_BROWSER_LAUNCH_TIMEOUT (300 * 1000)
+#define DEFAULT_ONLINE_CHECK_IPV4_URL "http://ipv4.connman.net/online/status.html"
+#define DEFAULT_ONLINE_CHECK_IPV6_URL "http://ipv6.connman.net/online/status.html"
+
/*
* We set the integer to 1 sec so that we have a chance to get
* necessary IPv6 router advertisement messages that might have
@@ -104,6 +107,8 @@ static struct {
char *vendor_class_id;
bool enable_online_check;
bool enable_online_to_ready_transition;
+ char *online_check_ipv4_url;
+ char *online_check_ipv6_url;
unsigned int online_check_initial_interval;
unsigned int online_check_max_interval;
bool auto_connect_roaming_services;
@@ -121,6 +126,11 @@ static struct {
bool simple_log;
bool wifi_roam_scan;
bool wifi_roam;
+ int wifi_roam_min_snr;
+ int wifi_roam_min_rssi_2_4GHz;
+ int wifi_roam_min_rssi_5GHz;
+ int wifi_roam_min_rssi_6GHz;
+ int wifi_ap_selection_method;
#endif
} connman_settings = {
.bg_scan = true,
@@ -142,6 +152,8 @@ static struct {
.vendor_class_id = NULL,
.enable_online_check = true,
.enable_online_to_ready_transition = false,
+ .online_check_ipv4_url = NULL,
+ .online_check_ipv6_url = NULL,
.online_check_initial_interval = DEFAULT_ONLINE_CHECK_INITIAL_INTERVAL,
.online_check_max_interval = DEFAULT_ONLINE_CHECK_MAX_INTERVAL,
.auto_connect_roaming_services = false,
@@ -159,6 +171,11 @@ static struct {
.simple_log = true,
.wifi_roam_scan = false,
.wifi_roam = false,
+ .wifi_roam_min_snr = 0,
+ .wifi_roam_min_rssi_2_4GHz = 0,
+ .wifi_roam_min_rssi_5GHz = 0,
+ .wifi_roam_min_rssi_6GHz = 0,
+ .wifi_ap_selection_method = AP_SELECTION_METHOD_NORMAL,
#endif
};
@@ -237,6 +254,8 @@ static struct {
#define CONF_VENDOR_CLASS_ID "VendorClassID"
#define CONF_ENABLE_ONLINE_CHECK "EnableOnlineCheck"
#define CONF_ENABLE_ONLINE_TO_READY_TRANSITION "EnableOnlineToReadyTransition"
+#define CONF_ONLINE_CHECK_IPV4_URL "OnlineCheckIPv4URL"
+#define CONF_ONLINE_CHECK_IPV6_URL "OnlineCheckIPv6URL"
#define CONF_ONLINE_CHECK_INITIAL_INTERVAL "OnlineCheckInitialInterval"
#define CONF_ONLINE_CHECK_MAX_INTERVAL "OnlineCheckMaxInterval"
#define CONF_AUTO_CONNECT_ROAMING_SERVICES "AutoConnectRoamingServices"
@@ -247,13 +266,18 @@ static struct {
#define CONF_TIZEN_TV_EXT "TizenTVExtension"
#define CONF_ENABLE_AUTO_IP "EnableAutoIp"
#define CONF_GLOBAL_NAMESERVER "GlobalNameserver"
-#define CONF_CONNMAN_SUPPLICANT_DEBUG "ConnmanSupplicantDebug"
-#define CONF_CONNMAN_WIFI_DEF_IFNAME "DefaultWifiInterface"
-#define CONF_CONNMAN_FILE_LOG "FileLogging"
-#define CONF_CONNMAN_DLOG_LOG "DlogLogging"
-#define CONF_CONNMAN_SIMPLIFIED_LOG "SimplifiedLog"
-#define CONF_CONNMAN_WIFI_ROAM_SCAN "WifiRoamingScan"
-#define CONF_CONNMAN_WIFI_ROAM "WifiRoaming"
+#define CONF_SUPPLICANT_DEBUG "ConnmanSupplicantDebug"
+#define CONF_WIFI_DEF_IFNAME "DefaultWifiInterface"
+#define CONF_FILE_LOG "FileLogging"
+#define CONF_DLOG_LOG "DlogLogging"
+#define CONF_SIMPLIFIED_LOG "SimplifiedLog"
+#define CONF_WIFI_ROAM_SCAN "WifiRoamingScan"
+#define CONF_WIFI_ROAM "WifiRoaming"
+#define CONF_WIFI_ROAM_MIN_SNR "WifiRoamingMinSNR"
+#define CONF_WIFI_ROAM_MIN_RSSI_2_4 "WifiRoamingMinRSSI_2_4GHz"
+#define CONF_WIFI_ROAM_MIN_RSSI_5 "WifiRoamingMinRSSI_5GHz"
+#define CONF_WIFI_ROAM_MIN_RSSI_6 "WifiRoamingMinRSSI_6GHz"
+#define CONF_WIFI_AP_SELECTION_METHOD "ApSelectionMethod"
#endif
#if defined TIZEN_EXT
@@ -281,7 +305,7 @@ static struct {
#define CONF_INS_INTERNET_SCORE "INSInternetScore"
/* Common */
#define CONF_INS_SIGNAL_LEVEL3_5GHZ "INSSignalLevel3_5GHz"
-#define CONF_INS_SIGNAL_LEVEL3_24GHZ "INSSignalLevel3_24GHz"
+#define CONF_INS_SIGNAL_LEVEL3_2_4GHZ "INSSignalLevel3_2_4GHz"
#endif
static const char *supported_options[] = {
@@ -304,6 +328,8 @@ static const char *supported_options[] = {
CONF_VENDOR_CLASS_ID,
CONF_ENABLE_ONLINE_CHECK,
CONF_ENABLE_ONLINE_TO_READY_TRANSITION,
+ CONF_ONLINE_CHECK_IPV4_URL,
+ CONF_ONLINE_CHECK_IPV6_URL,
CONF_ONLINE_CHECK_INITIAL_INTERVAL,
CONF_ONLINE_CHECK_MAX_INTERVAL,
CONF_AUTO_CONNECT_ROAMING_SERVICES,
@@ -314,13 +340,18 @@ static const char *supported_options[] = {
CONF_TIZEN_TV_EXT,
CONF_ENABLE_AUTO_IP,
CONF_GLOBAL_NAMESERVER,
- CONF_CONNMAN_SUPPLICANT_DEBUG,
- CONF_CONNMAN_WIFI_DEF_IFNAME,
- CONF_CONNMAN_FILE_LOG,
- CONF_CONNMAN_DLOG_LOG,
- CONF_CONNMAN_SIMPLIFIED_LOG,
- CONF_CONNMAN_WIFI_ROAM_SCAN,
- CONF_CONNMAN_WIFI_ROAM,
+ CONF_SUPPLICANT_DEBUG,
+ CONF_WIFI_DEF_IFNAME,
+ CONF_FILE_LOG,
+ CONF_DLOG_LOG,
+ CONF_SIMPLIFIED_LOG,
+ CONF_WIFI_ROAM_SCAN,
+ CONF_WIFI_ROAM,
+ CONF_WIFI_ROAM_MIN_SNR,
+ CONF_WIFI_ROAM_MIN_RSSI_2_4,
+ CONF_WIFI_ROAM_MIN_RSSI_5,
+ CONF_WIFI_ROAM_MIN_RSSI_6,
+ CONF_WIFI_AP_SELECTION_METHOD,
#endif
NULL
};
@@ -351,7 +382,7 @@ static const char *supported_ins_options[] = {
CONF_INS_INTERNET_SCORE,
/* Common */
CONF_INS_SIGNAL_LEVEL3_5GHZ,
- CONF_INS_SIGNAL_LEVEL3_24GHZ,
+ CONF_INS_SIGNAL_LEVEL3_2_4GHZ,
NULL
};
#endif
@@ -495,7 +526,7 @@ static void check_config(GKeyFile *config)
}
#if defined TIZEN_EXT
-static void check_Tizen_INS_configuration(GKeyFile *config)
+static void check_tizen_ins_configuration(GKeyFile *config)
{
GError *error = NULL;
char *ins_preferred_freq_bssid;
@@ -649,20 +680,21 @@ static void check_Tizen_INS_configuration(GKeyFile *config)
g_clear_error(&error);
integer = g_key_file_get_integer(config, "INS",
- CONF_INS_SIGNAL_LEVEL3_24GHZ, &error);
+ CONF_INS_SIGNAL_LEVEL3_2_4GHZ, &error);
if (!error)
connman_ins_settings.ins_signal_level3_24ghz = integer;
g_clear_error(&error);
}
-static void check_Tizen_configuration(GKeyFile *config)
+static void check_tizen_configuration(GKeyFile *config)
{
GError *error = NULL;
char **cellular_interfaces;
char *global_nameserver;
char *default_wifi_ifname;
bool boolean;
+ int integer;
gsize len;
cellular_interfaces = g_key_file_get_string_list(config, "General",
@@ -695,51 +727,90 @@ static void check_Tizen_configuration(GKeyFile *config)
g_clear_error(&error);
boolean = __connman_config_get_bool(config, "General",
- CONF_CONNMAN_SUPPLICANT_DEBUG, &error);
+ CONF_SUPPLICANT_DEBUG, &error);
if (!error)
connman_settings.supplicant_debug = boolean;
g_clear_error(&error);
default_wifi_ifname = __connman_config_get_string(config, "General",
- CONF_CONNMAN_WIFI_DEF_IFNAME, &error);
+ CONF_WIFI_DEF_IFNAME, &error);
if (!error)
connman_settings.def_wifi_ifname = default_wifi_ifname;
g_clear_error(&error);
boolean = __connman_config_get_bool(config, "General",
- CONF_CONNMAN_FILE_LOG, &error);
+ CONF_FILE_LOG, &error);
if (!error)
connman_settings.file_log = boolean;
g_clear_error(&error);
boolean = __connman_config_get_bool(config, "General",
- CONF_CONNMAN_DLOG_LOG, &error);
+ CONF_DLOG_LOG, &error);
if (!error)
connman_settings.dlog_log = boolean;
g_clear_error(&error);
boolean = __connman_config_get_bool(config, "General",
- CONF_CONNMAN_SIMPLIFIED_LOG, &error);
+ CONF_SIMPLIFIED_LOG, &error);
if (!error)
connman_settings.simple_log = boolean;
+ g_clear_error(&error);
+
boolean = __connman_config_get_bool(config, "General",
- CONF_CONNMAN_WIFI_ROAM_SCAN, &error);
+ CONF_WIFI_ROAM_SCAN, &error);
if (!error)
connman_settings.wifi_roam_scan = boolean;
+ g_clear_error(&error);
+
boolean = __connman_config_get_bool(config, "General",
- CONF_CONNMAN_WIFI_ROAM, &error);
+ CONF_WIFI_ROAM, &error);
if (!error)
connman_settings.wifi_roam = boolean;
g_clear_error(&error);
- check_Tizen_INS_configuration(config);
+ integer = g_key_file_get_integer(config, "General",
+ CONF_WIFI_ROAM_MIN_SNR, &error);
+ if (!error && integer >= 0)
+ connman_settings.wifi_roam_min_snr = integer;
+
+ g_clear_error(&error);
+
+ integer = g_key_file_get_integer(config, "General",
+ CONF_WIFI_ROAM_MIN_RSSI_2_4, &error);
+ if (!error)
+ connman_settings.wifi_roam_min_rssi_2_4GHz = integer;
+
+ g_clear_error(&error);
+
+ integer = g_key_file_get_integer(config, "General",
+ CONF_WIFI_ROAM_MIN_RSSI_5, &error);
+ if (!error)
+ connman_settings.wifi_roam_min_rssi_5GHz = integer;
+
+ g_clear_error(&error);
+
+ integer = g_key_file_get_integer(config, "General",
+ CONF_WIFI_ROAM_MIN_RSSI_6, &error);
+ if (!error)
+ connman_settings.wifi_roam_min_rssi_6GHz = integer;
+
+ g_clear_error(&error);
+
+ integer = g_key_file_get_integer(config, "General",
+ CONF_WIFI_AP_SELECTION_METHOD, &error);
+ if (!error)
+ connman_settings.wifi_ap_selection_method = integer;
+
+ g_clear_error(&error);
+
+ check_tizen_ins_configuration(config);
}
static void set_nofile_inc(void)
@@ -953,6 +1024,27 @@ static void parse_config(GKeyFile *config)
g_clear_error(&error);
+ string = __connman_config_get_string(config, "General",
+ CONF_ONLINE_CHECK_IPV4_URL, &error);
+ if (!error)
+ connman_settings.online_check_ipv4_url = string;
+ else
+ connman_settings.online_check_ipv4_url =
+ g_strdup(DEFAULT_ONLINE_CHECK_IPV4_URL);
+
+ g_clear_error(&error);
+
+ string = __connman_config_get_string(config, "General",
+ CONF_ONLINE_CHECK_IPV6_URL, &error);
+ if (!error)
+ connman_settings.online_check_ipv6_url = string;
+ else
+ connman_settings.online_check_ipv6_url =
+ g_strdup(DEFAULT_ONLINE_CHECK_IPV6_URL);
+
+
+ g_clear_error(&error);
+
integer = g_key_file_get_integer(config, "General",
CONF_ONLINE_CHECK_INITIAL_INTERVAL, &error);
if (!error && integer >= 0)
@@ -1000,7 +1092,7 @@ static void parse_config(GKeyFile *config)
g_clear_error(&error);
#if defined TIZEN_EXT
- check_Tizen_configuration(config);
+ check_tizen_configuration(config);
#endif
}
@@ -1187,6 +1279,12 @@ char *connman_setting_get_string(const char *key)
if (g_str_equal(key, CONF_VENDOR_CLASS_ID))
return connman_settings.vendor_class_id;
+ if (g_str_equal(key, CONF_ONLINE_CHECK_IPV4_URL))
+ return connman_settings.online_check_ipv4_url;
+
+ if (g_str_equal(key, CONF_ONLINE_CHECK_IPV6_URL))
+ return connman_settings.online_check_ipv6_url;
+
if (g_strcmp0(key, "wifi") == 0) {
if (!option_wifi)
return "nl80211,wext";
@@ -1204,7 +1302,7 @@ char *connman_setting_get_string(const char *key)
if (g_str_equal(key, CONF_INS_PREFERRED_FREQ))
return connman_ins_settings.ins_preferred_freq;
- if (g_str_equal(key, CONF_CONNMAN_WIFI_DEF_IFNAME))
+ if (g_str_equal(key, CONF_WIFI_DEF_IFNAME))
return connman_settings.def_wifi_ifname;
#endif
return NULL;
@@ -1249,22 +1347,22 @@ bool connman_setting_get_bool(const char *key)
if (g_str_equal(key, CONF_ENABLE_AUTO_IP))
return connman_settings.auto_ip;
- if (g_str_equal(key, CONF_CONNMAN_SUPPLICANT_DEBUG))
+ if (g_str_equal(key, CONF_SUPPLICANT_DEBUG))
return connman_settings.supplicant_debug;
- if (g_str_equal(key, CONF_CONNMAN_FILE_LOG))
+ if (g_str_equal(key, CONF_FILE_LOG))
return connman_settings.file_log;
- if (g_str_equal(key, CONF_CONNMAN_DLOG_LOG))
+ if (g_str_equal(key, CONF_DLOG_LOG))
return connman_settings.dlog_log;
- if (g_str_equal(key, CONF_CONNMAN_SIMPLIFIED_LOG))
+ if (g_str_equal(key, CONF_SIMPLIFIED_LOG))
return connman_settings.simple_log;
- if (g_str_equal(key, CONF_CONNMAN_WIFI_ROAM_SCAN))
+ if (g_str_equal(key, CONF_WIFI_ROAM_SCAN))
return connman_settings.wifi_roam_scan;
- if (g_str_equal(key, CONF_CONNMAN_WIFI_ROAM))
+ if (g_str_equal(key, CONF_WIFI_ROAM))
return connman_settings.wifi_roam;
if (g_str_equal(key, CONF_INS_LAST_CONNECTED_BSSID))
@@ -1337,12 +1435,27 @@ unsigned int connman_setting_get_uint(const char *key)
#if defined TIZEN_EXT
int connman_setting_get_int(const char *key)
{
+ if (g_str_equal(key, CONF_WIFI_AP_SELECTION_METHOD))
+ return connman_settings.wifi_ap_selection_method;
+
if (g_str_equal(key, CONF_INS_SIGNAL_LEVEL3_5GHZ))
return connman_ins_settings.ins_signal_level3_5ghz;
- if (g_str_equal(key, CONF_INS_SIGNAL_LEVEL3_24GHZ))
+ if (g_str_equal(key, CONF_INS_SIGNAL_LEVEL3_2_4GHZ))
return connman_ins_settings.ins_signal_level3_24ghz;
+ if (g_str_equal(key, CONF_WIFI_ROAM_MIN_SNR))
+ return connman_settings.wifi_roam_min_snr;
+
+ if (g_str_equal(key, CONF_WIFI_ROAM_MIN_RSSI_2_4))
+ return connman_settings.wifi_roam_min_rssi_2_4GHz;
+
+ if (g_str_equal(key, CONF_WIFI_ROAM_MIN_RSSI_5))
+ return connman_settings.wifi_roam_min_rssi_5GHz;
+
+ if (g_str_equal(key, CONF_WIFI_ROAM_MIN_RSSI_6))
+ return connman_settings.wifi_roam_min_rssi_6GHz;
+
return 0;
}
#endif
@@ -1608,6 +1721,8 @@ int main(int argc, char *argv[])
g_strfreev(connman_settings.blacklisted_interfaces);
g_strfreev(connman_settings.tethering_technologies);
g_free(connman_settings.vendor_class_id);
+ g_free(connman_settings.online_check_ipv4_url);
+ g_free(connman_settings.online_check_ipv6_url);
#if defined TIZEN_EXT
g_free(connman_ins_settings.ins_preferred_freq_bssid);
diff --git a/src/main.conf b/src/main.conf
index e734ecfe..9905e3e2 100755
--- a/src/main.conf
+++ b/src/main.conf
@@ -130,12 +130,16 @@ SingleConnectedTechnology = true
# Default value is true.
# EnableOnlineCheck = false
+# Urls (IPv4 and IPv6 respectively) used during the online status check.
+# Please refer to the README for more detailed information.
+# Default values are http://ipv4.connman.net/online/status.html and
+# http://ipv6.connman.net/online/status.html respectively.
+# OnlineCheckIPv4URL= http://ipv4.connman.net/online/status.html
+# OnlineCheckIPv6URL= http://ipv6.connman.net/online/status.html
+
# Range of intervals between two online check requests.
-# When an online check request fails, another one is triggered after a
-# longer interval. The intervals follow the power of two series of numbers
-# between OnlineCheckInitialInterval and OnlineCheckMaxInterval.
-# Default range is [1, 12], corresponding to the following intervals, in
-# seconds: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121 and 144.
+# Please refer to the README for more detailed information.
+# Default values are 1 and 12 respectively.
# OnlineCheckInitialInterval = 1
# OnlineCheckMaxInterval = 12
@@ -215,6 +219,20 @@ DefaultWifiInterface = wlan0
# Default value is false.
# WifiRoaming = true
+# Determine if the SNR and signal have weakened
+# based on the following conditions.
+# - SNR is less than WifiRoamingMinSNR or RSSI is less than
+# WifiRoamingMinRSSI_2_4GHz, WifiRoamingMinRSSI_5GHz or WifiRoamingMinRSSI_6GHz.
+# - If the WifiRoamingMinSNR value is 0, the SNR check will be skipped.
+WifiRoamingMinSNR = 20
+WifiRoamingMinRSSI_2_4GHz = -75
+WifiRoamingMinRSSI_5GHz = -77
+WifiRoamingMinRSSI_6GHz = -78
+
+# This value indicates which AP selection method to be used.
+# 0: Normal(Signal strength)
+# 1: INS
+ApSelectionMethod = 0
[INS]
# INS(Intelligent Network Selection) configuration: BSSID Selection.
@@ -245,4 +263,4 @@ INSInternetScore = 30
# INS(Intelligent Network Selection) configuration: Common.
INSSignalLevel3_5GHz = -76
-INSSignalLevel3_24GHz = -74
+INSSignalLevel3_2_4GHz = -74
diff --git a/src/main_robot.conf b/src/main_robot.conf
index f2b84b55..5b72cd98 100755
--- a/src/main_robot.conf
+++ b/src/main_robot.conf
@@ -215,6 +215,20 @@ DefaultWifiInterface = wlan0
# Default value is false.
# WifiRoaming = true
+# Determine if the SNR and signal have weakened
+# based on the following conditions.
+# - SNR is less than WifiRoamingMinSNR or RSSI is less than
+# WifiRoamingMinRSSI_2_4GHz, WifiRoamingMinRSSI_5GHz or WifiRoamingMinRSSI_6GHz.
+# - If the WifiRoamingMinSNR value is 0, the SNR check will be skipped.
+WifiRoamingMinSNR = 20
+WifiRoamingMinRSSI_2_4GHz = -75
+WifiRoamingMinRSSI_5GHz = -77
+WifiRoamingMinRSSI_6GHz = -78
+
+# This value indicates which AP selection method to be used.
+# 0: Normal(Signal strength)
+# 1: INS
+ApSelectionMethod = 0
[INS]
# INS(Intelligent Network Selection) configuration: BSSID Selection.
@@ -245,4 +259,4 @@ INSInternetScore = 30
# INS(Intelligent Network Selection) configuration: Common.
INSSignalLevel3_5GHz = -76
-INSSignalLevel3_24GHz = -74
+INSSignalLevel3_2_4GHz = -74
diff --git a/src/main_tv.conf b/src/main_tv.conf
index c7b8e112..b40394c0 100755
--- a/src/main_tv.conf
+++ b/src/main_tv.conf
@@ -120,6 +120,11 @@ TizenTVExtension = true
# Default value is wlan0.
DefaultWifiInterface = wlan0
+# This value indicates which AP selection method to be used.
+# 0: Normal(Signal strength)
+# 1: INS
+ApSelectionMethod = 0
+
[INS]
# INS(Intelligent Network Selection) configuration: BSSID Selection.
INSPreferredFreqBSSID = 5GHz
@@ -149,4 +154,4 @@ INSInternetScore = 30
# INS(Intelligent Network Selection) configuration: Common.
INSSignalLevel3_5GHz = -76
-INSSignalLevel3_24GHz = -74
+INSSignalLevel3_2_4GHz = -74
diff --git a/src/manager.c b/src/manager.c
index 0000f784..9fea4e0e 100755
--- a/src/manager.c
+++ b/src/manager.c
@@ -266,9 +266,30 @@ static DBusMessage *get_connected_service(DBusConnection *conn,
return connman_service_create_dbus_service_reply(msg, service);
}
-#endif
-#if defined TIZEN_EXT_INS
+static DBusMessage *get_dhcp_status(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ const char *ifname;
+ const char *dhcp_status;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &ifname, DBUS_TYPE_INVALID);
+ dhcp_status = __connman_network_get_dhcp_status(ifname);
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ if (!dhcp_status)
+ dhcp_status = "Unknown";
+
+ dbus_message_iter_init_append(reply, &iter);
+ dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &dhcp_status);
+
+ return reply;
+}
+
static void append_ins_structs(DBusMessageIter *iter, void *user_data)
{
__connman_ins_list_struct(iter);
@@ -283,8 +304,9 @@ static DBusMessage *get_ins(DBusConnection *conn,
if (!reply)
return NULL;
- __connman_dbus_append_objpath_dict_array(reply,
- append_ins_structs, NULL);
+ if (TIZEN_INS_ENABLED)
+ __connman_dbus_append_objpath_dict_array(reply,
+ append_ins_structs, NULL);
return reply;
}
@@ -751,8 +773,10 @@ static const GDBusMethodTable manager_methods[] = {
GDBUS_ARGS({ "ifname", "s" }),
GDBUS_ARGS({ "service", "oa{sv}" }),
get_connected_service) },
-#endif
-#if defined TIZEN_EXT_INS
+ { GDBUS_METHOD("GetDhcpStatus",
+ GDBUS_ARGS({ "ifname", "s" }),
+ GDBUS_ARGS({ "status", "s" }),
+ get_dhcp_status) },
{ GDBUS_METHOD("GetINS",
NULL, GDBUS_ARGS({ "services", "a(oa{sv})" }),
get_ins) },
@@ -835,6 +859,9 @@ static const GDBusSignalTable manager_signals[] = {
{ GDBUS_SIGNAL("PeersChanged",
GDBUS_ARGS({ "changed", "a(oa{sv})" },
{ "removed", "ao" })) },
+ { GDBUS_SIGNAL("TetheringClientsChanged",
+ GDBUS_ARGS({ "registered", "as" },
+ { "removed", "as" })) },
{ },
};
diff --git a/src/network.c b/src/network.c
index 70461370..69816999 100755
--- a/src/network.c
+++ b/src/network.c
@@ -30,6 +30,12 @@
#include <connman/acd.h>
#include "src/shared/arp.h"
+#if defined TIZEN_EXT
+#include <gdbus.h>
+
+static DBusConnection *connection;
+#endif
+
/*
* How many times to send RS with the purpose of
* refreshing RDNSS entries before they actually expire.
@@ -56,6 +62,8 @@
static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
+
+static GHashTable *dhcp_status_list = NULL;
#endif
static GSList *network_list = NULL;
@@ -138,8 +146,7 @@ struct connman_network {
char *connector;
char *c_sign_key;
char *net_access_key;
-#endif
-#if defined TIZEN_EXT
+
unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
GHashTable *assoc_reject_table;
bool owe_transition_mode;
@@ -147,16 +154,20 @@ struct connman_network {
int transition_mode_ssid_len;
unsigned char transition_mode_bssid[WIFI_BSSID_LEN_MAX];
bool roaming_progress;
+ bool roaming_dhcp;
char *roaming_cur_bssid;
char *roaming_dst_bssid;
__time_t roam_scan_time;
+ unsigned int max_bssid_count;
int snr;
+ unsigned int est_throughput;
#endif
} wifi;
#if defined TIZEN_EXT
/* Multiple APN services and a default APN which a user selected */
bool default_internet;
+ bool is_psk_sha256;
#endif
};
@@ -600,7 +611,11 @@ static void remove_dhcp_timeout(struct connman_network *network)
}
}
+#if defined TIZEN_EXT
+int set_connected_dhcp(struct connman_network *network)
+#else
static int set_connected_dhcp(struct connman_network *network)
+#endif
{
struct connman_service *service;
struct connman_ipconfig *ipconfig_ipv4;
@@ -1350,6 +1365,9 @@ static void network_destruct(struct connman_network *network)
#if defined TIZEN_EXT
g_slist_free_full(network->wifi.vsie_list, g_free);
g_slist_free_full(network->wifi.bssid_list, g_free);
+
+ if (TIZEN_INS_ENABLED)
+ g_hash_table_destroy(network->wifi.assoc_reject_table);
#endif
g_free(network->path);
g_free(network->group);
@@ -1414,6 +1432,9 @@ struct connman_network *
connman_network_ref_debug(struct connman_network *network,
const char *file, int line, const char *caller)
{
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
network->refcount + 1, file, line, caller);
@@ -1431,6 +1452,9 @@ connman_network_ref_debug(struct connman_network *network,
void connman_network_unref_debug(struct connman_network *network,
const char *file, int line, const char *caller)
{
+#if defined TIZEN_EXT
+ if (!simplified_log)
+#endif
DBG("%p name %s ref %d by %s:%d:%s()", network, network->name,
network->refcount - 1, file, line, caller);
@@ -1808,6 +1832,10 @@ static void set_authenticate_error(struct connman_network *network)
if (!service)
return;
+ if (connman_service_get_favorite(service)) {
+ __connman_service_set_ignore(service, true);
+ }
+
__connman_service_indicate_error(service,
CONNMAN_SERVICE_ERROR_AUTH_FAILED);
}
@@ -1824,6 +1852,9 @@ static void set_associate_error(struct connman_network *network)
if (!service)
return;
+ if (connman_service_get_favorite(service))
+ __connman_service_set_ignore(service, true);
+
__connman_service_indicate_error(service,
CONNMAN_SERVICE_ERROR_ASSOC_FAILED);
#else
@@ -2006,6 +2037,18 @@ bool connman_network_get_connected(struct connman_network *network)
return network->connected;
}
+#if defined TIZEN_EXT
+bool connman_network_get_psk_sha256(struct connman_network *network)
+{
+ return network->is_psk_sha256;
+}
+
+void connman_network_set_psk_sha256(struct connman_network *network, bool is_psk_sha256)
+{
+ network->is_psk_sha256 = is_psk_sha256;
+}
+#endif
+
/**
* connman_network_get_associating:
* @network: network structure
@@ -2068,6 +2111,63 @@ out:
return err;
}
+#if defined TIZEN_EXT
+char *__connman_network_get_dhcp_status(const char *ifname)
+{
+ char *status = NULL;
+
+ if (!ifname)
+ return NULL;
+
+ status = g_hash_table_lookup(dhcp_status_list, ifname);
+ DBG("ifname: %s, DHCP status: %s", ifname, status);
+
+ return status;
+}
+
+static void __connman_network_update_dhcp_status(
+ const char *ifname, const char *status)
+{
+ if (!ifname || !status)
+ return;
+
+ g_hash_table_replace(dhcp_status_list, g_strdup(ifname), g_strdup(status));
+}
+
+dbus_bool_t __connman_network_notify_dhcp_changed(const char *key, const char *val)
+{
+ DBusMessage *signal;
+ DBusMessageIter iter;
+ dbus_bool_t result = FALSE;
+
+ if (val)
+ DBG("key %s, val %s", key, val);
+ else
+ DBG("key %s, val NULL", key);
+
+ signal = dbus_message_new_signal(CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE, "DhcpChanged");
+
+ if (!signal)
+ return result;
+
+ dbus_message_iter_init_append(signal, &iter);
+ connman_dbus_property_append_basic(&iter, key, DBUS_TYPE_STRING, &val);
+
+ result = dbus_connection_send(connection, signal, NULL);
+ if (result)
+ DBG("Successfuly sent signal");
+ else
+ DBG("Fail to send signal");
+
+ dbus_message_unref(signal);
+
+ __connman_network_update_dhcp_status(val, key);
+
+ return result;
+}
+#endif
+
/**
* __connman_network_connect:
* @network: network structure
@@ -2379,9 +2479,6 @@ int connman_network_set_bssid(struct connman_network *network,
if (bssid == NULL)
return -EINVAL;
- if (network->connected)
- return -EPERM;
-
if (!simplified_log)
DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network,
bssid[0], bssid[1], bssid[2],
@@ -2600,9 +2697,15 @@ unsigned char *connman_network_get_countrycode(struct connman_network *network)
int connman_network_set_bssid_list(struct connman_network *network,
GSList *bssids)
{
+ unsigned int max_bssid_count;
+
g_slist_free_full(network->wifi.bssid_list, g_free);
network->wifi.bssid_list = bssids;
+ max_bssid_count = g_slist_length(bssids);
+ if (network->wifi.max_bssid_count < max_bssid_count)
+ network->wifi.max_bssid_count = max_bssid_count;
+
return 0;
}
@@ -2640,6 +2743,11 @@ void *connman_network_get_bssid_list(struct connman_network *network)
return network->wifi.bssid_list;
}
+unsigned int connman_network_get_max_bssid_count(struct connman_network *network)
+{
+ return network->wifi.max_bssid_count;
+}
+
int connman_network_set_last_connected_bssid(struct connman_network *network,
const unsigned char *bssid)
{
@@ -2668,6 +2776,8 @@ void connman_network_set_assoc_reject_table(struct connman_network *network,
if (!assoc_reject_table)
return;
+ g_hash_table_destroy(network->wifi.assoc_reject_table);
+
network->wifi.assoc_reject_table = assoc_reject_table;
}
@@ -2699,6 +2809,17 @@ void connman_network_set_snr(struct connman_network *network, int snr)
{
network->wifi.snr = snr;
}
+
+unsigned int connman_network_get_est_throughput(struct connman_network *network)
+{
+ return network->wifi.est_throughput;
+}
+
+void connman_network_set_est_throughput(struct connman_network *network,
+ unsigned int est_throughput)
+{
+ network->wifi.est_throughput = est_throughput;
+}
#endif
int connman_network_set_nameservers(struct connman_network *network,
@@ -3031,6 +3152,8 @@ int connman_network_set_bool(struct connman_network *network,
network->wifi.owe_transition_mode = value;
else if (g_strcmp0(key, "WiFi.Roaming") == 0)
network->wifi.roaming_progress = value;
+ else if (g_strcmp0(key, "WiFi.RoamingDHCP") == 0)
+ network->wifi.roaming_dhcp = value;
else if (g_strcmp0(key, "WiFi.PMFRequired") == 0)
network->wifi.pmf_required = value;
#endif
@@ -3065,6 +3188,8 @@ bool connman_network_get_bool(struct connman_network *network,
return network->wifi.owe_transition_mode;
else if (g_str_equal(key, "WiFi.Roaming"))
return network->wifi.roaming_progress;
+ else if (g_str_equal(key, "WiFi.RoamingDHCP"))
+ return network->wifi.roaming_dhcp;
else if (g_str_equal(key, "WiFi.PMFRequired"))
return network->wifi.pmf_required;
#endif
@@ -3232,6 +3357,11 @@ void connman_network_update(struct connman_network *network)
int __connman_network_init(void)
{
DBG("");
+#if defined TIZEN_EXT
+ connection = connman_dbus_get_connection();
+ dhcp_status_list = g_hash_table_new_full(g_str_hash,
+ g_str_equal, g_free, g_free);
+#endif
return 0;
}
@@ -3239,4 +3369,9 @@ int __connman_network_init(void)
void __connman_network_cleanup(void)
{
DBG("");
+#if defined TIZEN_EXT
+ dbus_connection_unref(connection);
+ if (dhcp_status_list)
+ g_hash_table_destroy(dhcp_status_list);
+#endif
}
diff --git a/src/ntp.c b/src/ntp.c
index 0de4df75..81b6835a 100755
--- a/src/ntp.c
+++ b/src/ntp.c
@@ -370,6 +370,7 @@ static void decode_msg(struct ntp_data *nd, void *base, size_t len,
connection = connman_dbus_get_connection();
if(!connection){
DBG("dbus connection does not exist");
+ nd->cb(false, nd->user_data);
return;
}
@@ -397,6 +398,7 @@ static void decode_msg(struct ntp_data *nd, void *base, size_t len,
}
dbus_connection_unref(connection);
dbus_message_unref(msg);
+ nd->cb(false, nd->user_data);
return;
}
@@ -409,6 +411,7 @@ static void decode_msg(struct ntp_data *nd, void *base, size_t len,
DBG("setting time");
__connman_clock_set_time_updated(true);
+ nd->cb(true, nd->user_data);
}
#else
if (offset < STEPTIME_MIN_OFFSET && offset > -STEPTIME_MIN_OFFSET) {
@@ -527,6 +530,13 @@ static gboolean received_data(GIOChannel *channel, GIOCondition condition,
}
}
+#if defined TIZEN_EXT
+ if (__connman_clock_timeupdates() == TIME_UPDATES_MANUAL) {
+ DBG("Skip time update.");
+ return TRUE;
+ }
+#endif
+
decode_msg(nd, iov.iov_base, iov.iov_len, tv, &mrx_time);
return TRUE;
diff --git a/src/rtnl.c b/src/rtnl.c
index 40ede4f4..6a47a8c1 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -1456,75 +1456,71 @@ static const char *type2string(uint16_t type)
static GIOChannel *channel = NULL;
static guint channel_watch = 0;
-struct rtnl_request {
- struct nlmsghdr hdr;
- struct rtgenmsg msg;
-};
-#define RTNL_REQUEST_SIZE (sizeof(struct nlmsghdr) + sizeof(struct rtgenmsg))
+#define RTNL_REQUEST_SIZE (NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(struct rtgenmsg)))
static GSList *request_list = NULL;
static guint32 request_seq = 0;
-static struct rtnl_request *find_request(guint32 seq)
+static struct nlmsghdr *find_request(guint32 seq)
{
GSList *list;
for (list = request_list; list; list = list->next) {
- struct rtnl_request *req = list->data;
+ struct nlmsghdr *hdr = list->data;
- if (req->hdr.nlmsg_seq == seq)
- return req;
+ if (hdr->nlmsg_seq == seq)
+ return hdr;
}
return NULL;
}
-static int send_request(struct rtnl_request *req)
+static int send_request(struct nlmsghdr *hdr)
{
struct sockaddr_nl addr;
int sk;
DBG("%s len %d type %d flags 0x%04x seq %d",
- type2string(req->hdr.nlmsg_type),
- req->hdr.nlmsg_len, req->hdr.nlmsg_type,
- req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
+ type2string(hdr->nlmsg_type),
+ hdr->nlmsg_len, hdr->nlmsg_type,
+ hdr->nlmsg_flags, hdr->nlmsg_seq);
sk = g_io_channel_unix_get_fd(channel);
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
- return sendto(sk, req, req->hdr.nlmsg_len, 0,
+ return sendto(sk, hdr, hdr->nlmsg_len, 0,
(struct sockaddr *) &addr, sizeof(addr));
}
-static int queue_request(struct rtnl_request *req)
+static int queue_request(struct nlmsghdr *hdr)
{
- request_list = g_slist_append(request_list, req);
+ request_list = g_slist_append(request_list, hdr);
if (g_slist_length(request_list) > 1)
return 0;
- return send_request(req);
+ return send_request(hdr);
}
static int process_response(guint32 seq)
{
- struct rtnl_request *req;
+ struct nlmsghdr *hdr;
DBG("seq %d", seq);
- req = find_request(seq);
- if (req) {
- request_list = g_slist_remove(request_list, req);
- g_free(req);
+ hdr = find_request(seq);
+ if (hdr) {
+ request_list = g_slist_remove(request_list, hdr);
+ g_free(hdr);
}
- req = g_slist_nth_data(request_list, 0);
- if (!req)
+ hdr = g_slist_nth_data(request_list, 0);
+ if (!hdr)
return 0;
- return send_request(req);
+ return send_request(hdr);
}
static void rtnl_message(void *buf, size_t len)
@@ -1639,62 +1635,65 @@ static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data
static int send_getlink(void)
{
- struct rtnl_request *req;
+ struct nlmsghdr *hdr;
+ struct rtgenmsg *msg;
DBG("");
- req = g_try_malloc0(RTNL_REQUEST_SIZE);
- if (!req)
- return -ENOMEM;
+ hdr = g_malloc0(RTNL_REQUEST_SIZE);
+
+ hdr->nlmsg_len = RTNL_REQUEST_SIZE;
+ hdr->nlmsg_type = RTM_GETLINK;
+ hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ hdr->nlmsg_pid = 0;
+ hdr->nlmsg_seq = request_seq++;
- req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
- req->hdr.nlmsg_type = RTM_GETLINK;
- req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
- req->hdr.nlmsg_pid = 0;
- req->hdr.nlmsg_seq = request_seq++;
- req->msg.rtgen_family = AF_INET;
+ msg = (struct rtgenmsg *) NLMSG_DATA(hdr);
+ msg->rtgen_family = AF_INET;
- return queue_request(req);
+ return queue_request(hdr);
}
static int send_getaddr(void)
{
- struct rtnl_request *req;
+ struct nlmsghdr *hdr;
+ struct rtgenmsg *msg;
DBG("");
- req = g_try_malloc0(RTNL_REQUEST_SIZE);
- if (!req)
- return -ENOMEM;
+ hdr = g_malloc0(RTNL_REQUEST_SIZE);
- req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
- req->hdr.nlmsg_type = RTM_GETADDR;
- req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
- req->hdr.nlmsg_pid = 0;
- req->hdr.nlmsg_seq = request_seq++;
- req->msg.rtgen_family = AF_INET;
+ hdr->nlmsg_len = RTNL_REQUEST_SIZE;
+ hdr->nlmsg_type = RTM_GETADDR;
+ hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ hdr->nlmsg_pid = 0;
+ hdr->nlmsg_seq = request_seq++;
- return queue_request(req);
+ msg = (struct rtgenmsg *) NLMSG_DATA(hdr);
+ msg->rtgen_family = AF_INET;
+
+ return queue_request(hdr);
}
static int send_getroute(void)
{
- struct rtnl_request *req;
+ struct nlmsghdr *hdr;
+ struct rtgenmsg *msg;
DBG("");
- req = g_try_malloc0(RTNL_REQUEST_SIZE);
- if (!req)
- return -ENOMEM;
+ hdr = g_malloc0(RTNL_REQUEST_SIZE);
+
+ hdr->nlmsg_len = RTNL_REQUEST_SIZE;
+ hdr->nlmsg_type = RTM_GETROUTE;
+ hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ hdr->nlmsg_pid = 0;
+ hdr->nlmsg_seq = request_seq++;
- req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
- req->hdr.nlmsg_type = RTM_GETROUTE;
- req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
- req->hdr.nlmsg_pid = 0;
- req->hdr.nlmsg_seq = request_seq++;
- req->msg.rtgen_family = AF_INET;
+ msg = (struct rtgenmsg *) NLMSG_DATA(hdr);
+ msg->rtgen_family = AF_INET;
- return queue_request(req);
+ return queue_request(hdr);
}
static gboolean update_timeout_cb(gpointer user_data)
@@ -1857,14 +1856,14 @@ void __connman_rtnl_cleanup(void)
update_list = NULL;
for (list = request_list; list; list = list->next) {
- struct rtnl_request *req = list->data;
+ struct nlmsghdr *hdr= list->data;
DBG("%s len %d type %d flags 0x%04x seq %d",
- type2string(req->hdr.nlmsg_type),
- req->hdr.nlmsg_len, req->hdr.nlmsg_type,
- req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
+ type2string(hdr->nlmsg_type),
+ hdr->nlmsg_len, hdr->nlmsg_type,
+ hdr->nlmsg_flags, hdr->nlmsg_seq);
- g_free(req);
+ g_free(hdr);
list->data = NULL;
}
diff --git a/src/service.c b/src/service.c
index 794555ea..9f7c4690 100755
--- a/src/service.c
+++ b/src/service.c
@@ -31,6 +31,10 @@
#include <ctype.h>
#include <stdint.h>
+#if defined TIZEN_EXT
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
#include <connman/storage.h>
#include <connman/setting.h>
#include <connman/agent.h>
@@ -61,6 +65,7 @@ static DBusConnection *connection = NULL;
static GList *service_list = NULL;
static GHashTable *service_hash = NULL;
+static GHashTable *passphrase_requested = NULL;
static GSList *counter_list = NULL;
static unsigned int autoconnect_id = 0;
static unsigned int vpn_autoconnect_id = 0;
@@ -81,9 +86,7 @@ struct saved_profiles {
static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
-#endif
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
enum connman_ins_preferred_freq {
CONNMAN_INS_PREFERRED_FREQ_UNKNOWN,
CONNMAN_INS_PREFERRED_FREQ_24GHZ,
@@ -109,7 +112,7 @@ struct connman_ins_settings {
};
static struct connman_ins_settings ins_settings;
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
struct connman_stats {
bool valid;
@@ -231,22 +234,19 @@ struct connman_service {
enum connman_dnsconfig_method dns_config_method_ipv4;
enum connman_dnsconfig_method dns_config_method_ipv6;
-#endif
-#if defined TIZEN_EXT
+
char *connector;
char *c_sign_key;
char *net_access_key;
unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
bool is_internet_connection;
int assoc_reject_count;
-#if defined TIZEN_EXT_INS
int score_last_user_selection;
int score_last_connected;
int score_frequency;
int score_security_priority;
int score_internet_connection;
int score_strength;
-#endif
int ins_score;
#endif
#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET
@@ -475,6 +475,10 @@ static const char *security2string(enum connman_service_security security)
#endif
case CONNMAN_SERVICE_SECURITY_8021X:
return "ieee8021x";
+#if defined TIZEN_EXT
+ default:
+ break;
+#endif
}
return NULL;
@@ -828,6 +832,9 @@ static void save_assoc_reject(gpointer key, gpointer value, gpointer user_data)
GSList *list;
char *val_str;
+ if (!assoc_rd)
+ return;
+
if (g_slist_length(assoc_rd->reject_time_list) < 1)
return;
@@ -866,10 +873,10 @@ static bool update_assoc_reject(struct connman_service *service)
if (assoc_reject_table) {
assoc_reject_count = 0;
g_hash_table_foreach(assoc_reject_table, count_assoc_reject, &assoc_reject_count);
-#if defined TIZEN_EXT_INS
+
DBG("assoc reject count [%d -> %d]",
service->assoc_reject_count, assoc_reject_count);
-#endif
+
if (service->assoc_reject_count != assoc_reject_count) {
service->assoc_reject_count = assoc_reject_count;
return true;
@@ -956,9 +963,7 @@ static int service_ext_load(struct connman_service *service)
reject_data->reject_time_list = g_slist_append(reject_data->reject_time_list,
GINT_TO_POINTER(reject_time));
-#if defined TIZEN_EXT_INS
DBG("assoc reject [%s_%ld]", bssid, reject_time);
-#endif
g_strfreev(bssid_time);
}
@@ -987,7 +992,8 @@ static int service_ext_save(struct connman_service *service)
if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
return -EINVAL;
- keyfile = g_key_file_new();
+ keyfile = connman_storage_load_service(service->identifier);
+
if (!keyfile)
return -EIO;
@@ -1013,9 +1019,7 @@ static int service_ext_save(struct connman_service *service)
g_key_file_set_string(keyfile, identifier,
"LastConnectedBSSID", bssid_str->str);
-#if defined TIZEN_EXT_INS
DBG("last connected bssid[%s]", bssid_str->str);
-#endif
g_string_free(bssid_str, TRUE);
}
@@ -1039,9 +1043,7 @@ next:
g_key_file_set_string_list(keyfile, service->identifier,
"AssocReject", (const gchar **)reject_list, reject_len);
-#if defined TIZEN_EXT_INS
DBG("assoc reject table [%d]", reject_len);
-#endif
g_strfreev(reject_list);
g_string_free(reject_str, TRUE);
@@ -1055,7 +1057,7 @@ done:
g_key_file_free(keyfile);
return err;
}
-#endif
+#endif /* defined TIZEN_EXT */
static int service_load(struct connman_service *service)
{
@@ -1157,44 +1159,46 @@ static int service_load(struct connman_service *service)
}
#if defined TIZEN_EXT
- /* Last connected BSSID */
- if (service->network) {
- gchar *bssid_str;
- unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
- char **str_list;
- unsigned int i;
+ if (TIZEN_INS_ENABLED) {
+ /* Last connected BSSID */
+ if (service->network) {
+ gchar *bssid_str;
+ unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX];
+ char **str_list;
+ unsigned int i;
- bssid_str = g_key_file_get_string(keyfile,
- service->identifier, "LastConnectedBSSID", NULL);
+ bssid_str = g_key_file_get_string(keyfile,
+ service->identifier, "LastConnectedBSSID", NULL);
- if (bssid_str) {
- str_list = g_strsplit(bssid_str, ":", 0);
+ if (bssid_str) {
+ str_list = g_strsplit(bssid_str, ":", 0);
- if (str_list) {
- for (i = 0; i < WIFI_BSSID_LEN_MAX; i++)
- last_connected_bssid[i] = strtol(str_list[i], NULL, 16);
+ if (str_list) {
+ for (i = 0; i < WIFI_BSSID_LEN_MAX; i++)
+ last_connected_bssid[i] = strtol(str_list[i], NULL, 16);
- memcpy(service->last_connected_bssid,
- last_connected_bssid, WIFI_BSSID_LEN_MAX);
+ memcpy(service->last_connected_bssid,
+ last_connected_bssid, WIFI_BSSID_LEN_MAX);
- connman_network_set_last_connected_bssid(service->network,
- last_connected_bssid);
+ connman_network_set_last_connected_bssid(service->network,
+ last_connected_bssid);
- g_strfreev(str_list);
- }
+ g_strfreev(str_list);
+ }
- g_free(bssid_str);
+ g_free(bssid_str);
+ }
}
- }
- /* Internet connection */
- internet_connection = g_key_file_get_boolean(keyfile,
- service->identifier, "InternetConnection", &error);
- if (!error)
- service->is_internet_connection = internet_connection;
+ /* Internet connection */
+ internet_connection = g_key_file_get_boolean(keyfile,
+ service->identifier, "InternetConnection", &error);
+ if (!error)
+ service->is_internet_connection = internet_connection;
- g_clear_error(&error);
-#endif
+ g_clear_error(&error);
+ }
+#endif /* defined TIZEN_EXT */
/* fall through */
case CONNMAN_SERVICE_TYPE_GADGET:
@@ -1504,72 +1508,69 @@ static int service_save(struct connman_service *service)
"Frequency", freq);
#if defined TIZEN_EXT
- /* Last connected BSSID */
- if (memcmp(service->last_connected_bssid, invalid_bssid, WIFI_BSSID_LEN_MAX)) {
- char *identifier = service->identifier;
- GString *bssid_str;
- unsigned int i;
+ if (TIZEN_INS_ENABLED) {
+ /* Last connected BSSID */
+ if (memcmp(service->last_connected_bssid, invalid_bssid, WIFI_BSSID_LEN_MAX)) {
+ char *identifier = service->identifier;
+ GString *bssid_str;
+ unsigned int i;
- bssid_str = g_string_sized_new(18);
- if (!bssid_str) {
- err = -ENOMEM;
- goto done;
- }
+ bssid_str = g_string_sized_new(18);
+ if (!bssid_str) {
+ err = -ENOMEM;
+ goto done;
+ }
- for (i = 0; i < WIFI_BSSID_LEN_MAX; i++) {
- g_string_append_printf(bssid_str,
- "%02x", service->last_connected_bssid[i]);
- if (i < WIFI_BSSID_LEN_MAX - 1)
- g_string_append(bssid_str, ":");
- }
+ for (i = 0; i < WIFI_BSSID_LEN_MAX; i++) {
+ g_string_append_printf(bssid_str,
+ "%02x", service->last_connected_bssid[i]);
+ if (i < WIFI_BSSID_LEN_MAX - 1)
+ g_string_append(bssid_str, ":");
+ }
- g_key_file_set_string(keyfile, identifier,
+ g_key_file_set_string(keyfile, identifier,
"LastConnectedBSSID", bssid_str->str);
-#if defined TIZEN_EXT_INS
- DBG("last connected bssid[%s]", bssid_str->str);
-#endif
+ DBG("last connected bssid[%s]", bssid_str->str);
- g_string_free(bssid_str, TRUE);
- }
+ g_string_free(bssid_str, TRUE);
+ }
- /* Assoc reject */
- assoc_reject_table = connman_network_get_assoc_reject_table(service->network);
- if (assoc_reject_table && g_hash_table_size(assoc_reject_table) > 0) {
- GString *assoc_reject_str;
- char **assoc_reject_list;
- guint assoc_reject_len;
+ /* Assoc reject */
+ assoc_reject_table = connman_network_get_assoc_reject_table(service->network);
+ if (assoc_reject_table && g_hash_table_size(assoc_reject_table) > 0) {
+ GString *assoc_reject_str;
+ char **assoc_reject_list;
+ guint assoc_reject_len;
- assoc_reject_str = g_string_new(NULL);
- if (!assoc_reject_str) {
- err = -ENOMEM;
- goto done;
- }
+ assoc_reject_str = g_string_new(NULL);
+ if (!assoc_reject_str) {
+ err = -ENOMEM;
+ goto done;
+ }
- g_hash_table_foreach(assoc_reject_table, save_assoc_reject, assoc_reject_str);
+ g_hash_table_foreach(assoc_reject_table, save_assoc_reject, assoc_reject_str);
- assoc_reject_list = g_strsplit_set(assoc_reject_str->str, " ", 0);
- assoc_reject_len = g_strv_length(assoc_reject_list);
+ assoc_reject_list = g_strsplit_set(assoc_reject_str->str, " ", 0);
+ assoc_reject_len = g_strv_length(assoc_reject_list);
- g_key_file_set_string_list(keyfile, service->identifier,
- "AssocReject", (const gchar **)assoc_reject_list, assoc_reject_len);
+ g_key_file_set_string_list(keyfile, service->identifier,
+ "AssocReject", (const gchar **)assoc_reject_list, assoc_reject_len);
-#if defined TIZEN_EXT_INS
- DBG("assoc reject table [%d]", assoc_reject_len);
-#endif
+ DBG("assoc reject table [%d]", assoc_reject_len);
- g_strfreev(assoc_reject_list);
- g_string_free(assoc_reject_str, TRUE);
- } else
- g_key_file_remove_key(keyfile, service->identifier, "AssocReject", NULL);
+ g_strfreev(assoc_reject_list);
+ g_string_free(assoc_reject_str, TRUE);
+ } else
+ g_key_file_remove_key(keyfile, service->identifier, "AssocReject", NULL);
- /* Internet connection */
- g_key_file_set_boolean(keyfile, service->identifier,
- "InternetConnection", service->is_internet_connection);
-#if defined TIZEN_EXT_INS
- DBG("internet connection [%s]", service->is_internet_connection ? "true" : "false");
-#endif
-#endif
+ /* Internet connection */
+ g_key_file_set_boolean(keyfile, service->identifier,
+ "InternetConnection", service->is_internet_connection);
+
+ DBG("internet connection [%s]", service->is_internet_connection ? "true" : "false");
+ }
+#endif /* defined TIZEN_EXT */
}
/* fall through */
@@ -3028,6 +3029,25 @@ bool __connman_service_index_is_default(int index)
return __connman_service_get_index(service) == index;
}
+static void start_wispr_when_connected(struct connman_service *service)
+{
+ if (!connman_setting_get_bool("EnableOnlineCheck")) {
+ connman_info("Online check disabled. "
+ "Default service remains in READY state.");
+ return;
+ }
+
+ if (__connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4))
+ __connman_service_wispr_start(service,
+ CONNMAN_IPCONFIG_TYPE_IPV4);
+
+ if (__connman_service_is_connected_state(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6))
+ __connman_service_wispr_start(service,
+ CONNMAN_IPCONFIG_TYPE_IPV6);
+}
+
static void default_changed(void)
{
#if defined TIZEN_EXT
@@ -3062,15 +3082,7 @@ static void default_changed(void)
connman_setting_get_bool("AllowDomainnameUpdates"))
__connman_utsname_set_domainname(service->domainname);
- if (__connman_service_is_connected_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV4))
- __connman_service_wispr_start(service,
- CONNMAN_IPCONFIG_TYPE_IPV4);
-
- if (__connman_service_is_connected_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV6))
- __connman_service_wispr_start(service,
- CONNMAN_IPCONFIG_TYPE_IPV6);
+ start_wispr_when_connected(service);
/*
* Connect VPN automatically when new default service
@@ -3140,33 +3152,32 @@ static void state_changed(struct connman_service *service)
#if defined TIZEN_EXT
static void connect_reason_changed(struct connman_service *service)
{
-#if defined TIZEN_EXT_INS
struct connman_device *device;
-#endif
+
if (!service->path)
return;
if (!allow_property_changed(service))
return;
-#if defined TIZEN_EXT_INS
- if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
- device = connman_network_get_device(service->network);
- if (device) {
- bool need_save = false;
+ if (TIZEN_INS_ENABLED) {
+ if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
+ device = connman_network_get_device(service->network);
+ if (device) {
+ bool need_save = false;
- need_save |= connman_device_set_last_user_selection_ident(device, service->identifier);
- need_save |= connman_device_set_last_user_selection_time(device, time(NULL));
+ need_save |= connman_device_set_last_user_selection_ident(device, service->identifier);
+ need_save |= connman_device_set_last_user_selection_time(device, time(NULL));
- DBG("last user selection ident[%s] time[%ld]",
- connman_device_get_last_user_selection_ident(device),
- connman_device_get_last_user_selection_time(device));
+ DBG("last user selection ident[%s] time[%ld]",
+ connman_device_get_last_user_selection_ident(device),
+ connman_device_get_last_user_selection_time(device));
- if (need_save)
- connman_device_save_last_user_selection(device);
+ if (need_save)
+ connman_device_save_last_user_selection(device);
+ }
}
}
-#endif
connman_dbus_property_changed_basic(service->path,
CONNMAN_SERVICE_INTERFACE,
@@ -3174,9 +3185,7 @@ static void connect_reason_changed(struct connman_service *service)
DBUS_TYPE_INT32,
&service->connect_reason);
}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
-#if defined TIZEN_EXT
static void disconnection_requested_changed(struct connman_service *service)
{
dbus_bool_t disconnection_requested;
@@ -3196,7 +3205,7 @@ static void disconnection_requested_changed(struct connman_service *service)
}
void connman_service_set_disconnection_requested(struct connman_service *service,
- bool disconnection_requested)
+ bool disconnection_requested)
{
if (service == NULL)
return;
@@ -3204,6 +3213,47 @@ void connman_service_set_disconnection_requested(struct connman_service *service
service->disconnection_requested = disconnection_requested;
disconnection_requested_changed(service);
}
+
+static void connman_service_emit_state(struct connman_service *service,
+ enum connman_service_state state)
+{
+ const char *str;
+ enum connman_service_state cur_state = service->state;
+
+ if (service->state != state)
+ service->state = state;
+
+ str = state2string(service->state);
+ if (!str) {
+ service->state = cur_state;
+ return;
+ }
+
+ DBG(" %s, %s", str, service->path);
+
+ connman_dbus_property_changed_basic(service->path,
+ CONNMAN_SERVICE_INTERFACE, "State",
+ DBUS_TYPE_STRING, &str);
+
+ emit_state_changed_with_properties(service);
+ service->state = cur_state;
+}
+
+void connman_service_notify_reconnection_roaming(struct connman_service *service)
+{
+ if (!service)
+ return;
+
+ if (service->state != CONNMAN_SERVICE_STATE_READY &&
+ service->state != CONNMAN_SERVICE_STATE_ONLINE)
+ return;
+
+ connman_service_emit_state(service, CONNMAN_SERVICE_STATE_CONFIGURATION);
+ connman_service_emit_state(service, CONNMAN_SERVICE_STATE_READY);
+
+ if (service->state == CONNMAN_SERVICE_STATE_ONLINE)
+ connman_service_emit_state(service, CONNMAN_SERVICE_STATE_ONLINE);
+}
#endif
static void strength_changed(struct connman_service *service)
@@ -3347,12 +3397,17 @@ static void append_security(DBusMessageIter *iter, void *user_data)
break;
#if defined TIZEN_EXT
case CONNMAN_SERVICE_SECURITY_OWE:
+ case CONNMAN_SERVICE_SECURITY_DPP:
#endif
case CONNMAN_SERVICE_SECURITY_UNKNOWN:
case CONNMAN_SERVICE_SECURITY_NONE:
case CONNMAN_SERVICE_SECURITY_WEP:
case CONNMAN_SERVICE_SECURITY_8021X:
break;
+#if defined TIZEN_EXT
+ default:
+ break;
+#endif
}
if (service->wps_advertizing) {
@@ -4650,7 +4705,7 @@ static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
connman_network_append_acddbus(dict, service->network);
}
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
static void append_ins_bssid_info(DBusMessageIter *iter, void *user_data)
{
GSList *bssid_list = NULL;
@@ -4741,7 +4796,7 @@ static void append_ins_properties(DBusMessageIter *dict,
append_ins_bssid_info, service->network);
}
}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
static void append_struct_service(DBusMessageIter *iter,
connman_dbus_append_cb_t function,
@@ -4780,7 +4835,7 @@ static void append_struct(gpointer value, gpointer user_data)
append_struct_service(iter, append_dict_properties, service);
}
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
static void append_dict_ins_properties(DBusMessageIter *dict, void *user_data)
{
struct connman_service *service = user_data;
@@ -4806,7 +4861,7 @@ void __connman_ins_list_struct(DBusMessageIter *iter)
{
g_list_foreach(service_list, append_ins_struct, iter);
}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
void __connman_service_list_struct(DBusMessageIter *iter)
{
@@ -5071,7 +5126,7 @@ void connman_service_set_internet_connection(struct connman_service *service,
if (service->is_internet_connection != internet_connection) {
service->is_internet_connection = internet_connection;
- g_get_current_time(&service->modified);
+ g_get_current_time((GTimeVal *)&service->modified);
service_save(service);
}
}
@@ -5465,6 +5520,7 @@ int __connman_service_check_passphrase(enum connman_service_security security,
#if defined TIZEN_EXT
case CONNMAN_SERVICE_SECURITY_OWE:
case CONNMAN_SERVICE_SECURITY_DPP:
+ default:
#endif
break;
}
@@ -6081,13 +6137,7 @@ static DBusMessage *set_property(DBusConnection *conn,
#endif
dns_configuration_changed(service);
- if (__connman_service_is_connected_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV4))
- __connman_service_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV4);
-
- if (__connman_service_is_connected_state(service,
- CONNMAN_IPCONFIG_TYPE_IPV6))
- __connman_service_wispr_start(service, CONNMAN_IPCONFIG_TYPE_IPV6);
+ start_wispr_when_connected(service);
service_save(service);
} else if (g_str_equal(name, "Timeservers.Configuration")) {
@@ -6307,8 +6357,10 @@ static void set_error(struct connman_service *service,
{
const char *str;
+#if !defined TIZEN_EXT
if (service->error == error)
return;
+#endif
service->error = error;
@@ -6611,6 +6663,7 @@ static bool auto_connect_service(GList *services,
#if defined TIZEN_EXT
GSList *wifi_ignore = NULL;
#endif
+ int index;
DBG("preferred %d sessions %d reason %s", preferred, active_count,
reason2string(reason));
@@ -6659,6 +6712,11 @@ static bool auto_connect_service(GList *services,
continue;
}
+ index = __connman_service_get_index(service);
+ if (g_hash_table_lookup(passphrase_requested,
+ GINT_TO_POINTER(index)))
+ return true;
+
if (service->pending ||
is_connecting(service->state) ||
is_connected(service->state)) {
@@ -7286,13 +7344,90 @@ bool __connman_service_remove(struct connman_service *service)
return true;
}
+#if defined TIZEN_EXT
+static char *__connman_service_get_wpa_id_to_remove(struct connman_service *service)
+{
+ char *identifier;
+ char *ptr;
+
+ if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return NULL;
+
+ if (service->security != CONNMAN_SERVICE_SECURITY_SAE &&
+ service->security != CONNMAN_SERVICE_SECURITY_PSK)
+ return NULL;
+
+ identifier = g_strdup(service->identifier);
+ if (!identifier)
+ return NULL;
+
+ if (service->security == CONNMAN_SERVICE_SECURITY_SAE) {
+ ptr = strstr(identifier, "_sae");
+ if (!ptr) {
+ g_free(identifier);
+ return NULL;
+ }
+
+ memcpy(ptr, "_psk", strlen("_psk"));
+ } else if (service->security == CONNMAN_SERVICE_SECURITY_PSK) {
+ ptr = strstr(identifier, "_psk");
+ if (!ptr) {
+ g_free(identifier);
+ return NULL;
+ }
+
+ memcpy(ptr, "_sae", strlen("_sae"));
+ }
+
+ return identifier;
+}
+
+
+static void __connman_service_remove_wpa_service(struct connman_service *service)
+{
+ gchar *dir;
+ GList *list;
+ char *identifier = __connman_service_get_wpa_id_to_remove(service);
+
+ if (!identifier)
+ return;
+
+ dir = g_strdup_printf("%s/%s", STORAGEDIR, identifier);
+ if (!dir)
+ goto done;
+
+ if (g_file_test(dir, G_FILE_TEST_EXISTS) != TRUE)
+ goto done;
+
+ for (list = service_list; list; list = list->next) {
+ struct connman_service *dst_service = list->data;
+
+ if (dst_service->type != CONNMAN_SERVICE_TYPE_WIFI)
+ continue;
+
+ if (g_strcmp0(dst_service->identifier, identifier) == 0) {
+ __connman_service_remove(dst_service);
+ goto done;
+ }
+ }
+
+ __connman_storage_remove_service(identifier);
+
+done:
+ g_free(identifier);
+ g_free(dir);
+}
+#endif
+
static DBusMessage *remove_service(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
struct connman_service *service = user_data;
DBG("service %p", service);
-
+#if defined TIZEN_EXT
+ __connman_service_remove_wpa_service(service);
+#endif
if (!__connman_service_remove(service))
return __connman_error_not_supported(msg);
@@ -7339,15 +7474,11 @@ static void apply_relevant_default_downgrade(struct connman_service *service)
struct connman_service *def_service;
def_service = connman_service_get_default();
- if (!def_service)
+ if (!def_service || def_service != service ||
+ def_service->state != CONNMAN_SERVICE_STATE_ONLINE)
return;
- if (def_service == service &&
- def_service->state == CONNMAN_SERVICE_STATE_ONLINE) {
- def_service->state = CONNMAN_SERVICE_STATE_READY;
- __connman_notifier_leave_online(def_service->type);
- state_changed(def_service);
- }
+ downgrade_state(def_service);
}
static void switch_default_service(struct connman_service *default_service,
@@ -7893,7 +8024,6 @@ static void service_initialize(struct connman_service *service)
memset(service->last_connected_bssid, 0, WIFI_BSSID_LEN_MAX);
service->is_internet_connection = false;
service->assoc_reject_count = 0;
-
service->disconnection_requested = false;
service->storage_reload = false;
/*
@@ -7993,7 +8123,7 @@ void connman_service_unref_debug(struct connman_service *service,
g_hash_table_remove(service_hash, service->identifier);
}
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
static int calculate_score_last_user_selection(struct connman_service *service)
{
int score = 0;
@@ -8171,7 +8301,7 @@ static int calculate_score(struct connman_service *service)
service->ins_score = score;
return score;
}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
static gint service_compare(gconstpointer a, gconstpointer b);
@@ -8207,18 +8337,38 @@ static gint service_compare_vpn(struct connman_service *a,
return service_compare(transport, service);
}
+static gint service_compare_preferred(struct connman_service *service_a,
+ struct connman_service *service_b)
+{
+ unsigned int *tech_array;
+ int i;
+
+ tech_array = connman_setting_get_uint_list("PreferredTechnologies");
+ if (tech_array) {
+ for (i = 0; tech_array[i]; i++) {
+ if (tech_array[i] == service_a->type)
+ return -1;
+
+ if (tech_array[i] == service_b->type)
+ return 1;
+ }
+ }
+ return 0;
+}
+
static gint service_compare(gconstpointer a, gconstpointer b)
{
struct connman_service *service_a = (void *) a;
struct connman_service *service_b = (void *) b;
enum connman_service_state state_a, state_b;
bool a_connected, b_connected;
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
int score_a;
int score_b;
-#else /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+ gint strength = 0;
+#else /* defined TIZEN_EXT */
gint strength;
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
state_a = service_a->state;
state_b = service_b->state;
@@ -8261,6 +8411,10 @@ static gint service_compare(gconstpointer a, gconstpointer b)
if (service_a->order < service_b->order)
return 1;
+
+ rval = service_compare_preferred(service_a, service_b);
+ if (rval)
+ return rval;
}
if (state_a != state_b) {
@@ -8291,20 +8445,11 @@ static gint service_compare(gconstpointer a, gconstpointer b)
return 1;
if (service_a->type != service_b->type) {
- unsigned int *tech_array;
- int i;
-
- tech_array = connman_setting_get_uint_list(
- "PreferredTechnologies");
- if (tech_array) {
- for (i = 0; tech_array[i]; i++) {
- if (tech_array[i] == service_a->type)
- return -1;
+ int rval;
- if (tech_array[i] == service_b->type)
- return 1;
- }
- }
+ rval = service_compare_preferred(service_a, service_b);
+ if (rval)
+ return rval;
if (service_a->type == CONNMAN_SERVICE_TYPE_ETHERNET)
return -1;
@@ -8337,44 +8482,32 @@ static gint service_compare(gconstpointer a, gconstpointer b)
return 1;
}
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
- score_a = calculate_score(service_a);
- score_b = calculate_score(service_b);
- if (score_b != score_a)
- return score_b - score_a;
-#else /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#if defined TIZEN_EXT
+ if (TIZEN_INS_ENABLED) {
+ score_a = calculate_score(service_a);
+ score_b = calculate_score(service_b);
+
+ if (score_b != score_a)
+ return score_b - score_a;
+ else if (score_b == score_a) {
+ strength = (gint) service_b->strength - (gint) service_a->strength;
+ if (strength)
+ return strength;
+ }
+ }
+#else /* defined TIZEN_EXT */
strength = (gint) service_b->strength - (gint) service_a->strength;
if (strength)
return strength;
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
return g_strcmp0(service_a->name, service_b->name);
}
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
-static void print_service_sort(gpointer data, gpointer user_data)
-{
- struct connman_service *service = data;
-
- if (service->type != CONNMAN_SERVICE_TYPE_WIFI)
- return;
-
- DBG("name[%-20s] total[%2d] last_usr[%2d] last_conn[%2d] "
- "freq[%2d] sec[%2d] internet[%2d] strength[%2d]",
- service->name, service->ins_score, service->score_last_user_selection,
- service->score_last_connected, service->score_frequency,
- service->score_security_priority, service->score_internet_connection,
- service->score_strength);
-}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
-
static void service_list_sort(void)
{
if (service_list && service_list->next) {
service_list = g_list_sort(service_list, service_compare);
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
- g_list_foreach(service_list, print_service_sort, NULL);
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
service_schedule_changed();
}
}
@@ -8803,6 +8936,7 @@ static void request_input_cb(struct connman_service *service,
struct connman_device *device;
const char *security;
int err = 0;
+ int index;
DBG("RequestInput return, %p", service);
@@ -8865,6 +8999,10 @@ static void request_input_cb(struct connman_service *service,
err = __connman_service_set_passphrase(service, passphrase);
done:
+ index = __connman_service_get_index(service);
+ g_hash_table_remove(passphrase_requested,
+ GINT_TO_POINTER(index));
+
if (err >= 0) {
/* We forget any previous error. */
set_error(service, CONNMAN_SERVICE_ERROR_UNKNOWN);
@@ -8918,27 +9056,14 @@ static int service_update_preferred_order(struct connman_service *default_servic
struct connman_service *new_service,
enum connman_service_state new_state)
{
- unsigned int *tech_array;
- int i;
-
- if (!default_service || default_service == new_service ||
- default_service->state != new_state)
+ if (!default_service || default_service == new_service)
return 0;
- tech_array = connman_setting_get_uint_list("PreferredTechnologies");
- if (tech_array) {
-
- for (i = 0; tech_array[i] != 0; i += 1) {
- if (default_service->type == tech_array[i])
- return -EALREADY;
-
- if (new_service->type == tech_array[i]) {
- switch_default_service(default_service,
- new_service);
- __connman_connection_update_gateway();
- return 0;
- }
- }
+ if (service_compare_preferred(default_service, new_service) > 0) {
+ switch_default_service(default_service,
+ new_service);
+ __connman_connection_update_gateway();
+ return 0;
}
return -EALREADY;
@@ -9147,6 +9272,50 @@ static void set_priority_connected_service(void)
#endif
}
}
+
+static void emit_wifi_roaming_failure(struct connman_service *service,
+ enum connman_service_state new_state)
+{
+ if (connman_setting_get_bool("WifiRoaming") &&
+ connman_network_get_bool(service->network, "WiFi.Roaming")) {
+ const char *cur_bssid;
+ const char *dst_bssid;
+ const char *ifname;
+ struct connman_device *device;
+
+ device = connman_network_get_device(service->network);
+ if (device) {
+ ifname = connman_device_get_string(device, "Interface");
+ cur_bssid = connman_network_get_string(service->network,
+ "WiFi.RoamingCurBSSID");
+ dst_bssid = connman_network_get_string(service->network,
+ "WiFi.RoamingDstBSSID");
+ }
+
+ if (device && ifname && cur_bssid && dst_bssid) {
+ switch(new_state) {
+ case CONNMAN_SERVICE_STATE_UNKNOWN:
+ case CONNMAN_SERVICE_STATE_ASSOCIATION:
+ case CONNMAN_SERVICE_STATE_CONFIGURATION:
+ case CONNMAN_SERVICE_STATE_READY:
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ break;
+ case CONNMAN_SERVICE_STATE_DISCONNECT:
+ case CONNMAN_SERVICE_STATE_FAILURE:
+ case CONNMAN_SERVICE_STATE_IDLE:
+ __connman_technology_notify_roaming_state(ifname,
+ "failure", cur_bssid, dst_bssid);
+ connman_network_set_bool(service->network,
+ "WiFi.Roaming", false);
+ connman_network_set_string(service->network,
+ "WiFi.RoamingCurBSSID", NULL);
+ connman_network_set_string(service->network,
+ "WiFi.RoamingDstBSSID", NULL);
+ break;
+ }
+ }
+ }
+}
#endif
static const char *get_dbus_sender(struct connman_service *service)
@@ -9215,6 +9384,15 @@ static int service_indicate_state(struct connman_service *service)
break;
case CONNMAN_SERVICE_STATE_IDLE:
+ if (old_state == CONNMAN_SERVICE_STATE_FAILURE &&
+ service->connect_reason ==
+ CONNMAN_SERVICE_CONNECT_REASON_NATIVE &&
+ service->error ==
+ CONNMAN_SERVICE_ERROR_INVALID_KEY) {
+ __connman_service_clear_error(service);
+ service_complete(service);
+ }
+
if (old_state != CONNMAN_SERVICE_STATE_DISCONNECT)
__connman_service_disconnect(service);
@@ -9257,12 +9435,12 @@ static int service_indicate_state(struct connman_service *service)
service->new_service = false;
- default_changed();
-
def_service = connman_service_get_default();
service_update_preferred_order(def_service, service, new_state);
+ default_changed();
+
__connman_service_set_favorite(service, true);
reply_pending(service, 0);
@@ -9324,7 +9502,7 @@ static int service_indicate_state(struct connman_service *service)
#endif
#if defined TIZEN_EXT
- if (service->type == CONNMAN_SERVICE_TYPE_WIFI)
+ if (TIZEN_INS_ENABLED && service->type == CONNMAN_SERVICE_TYPE_WIFI)
connman_service_set_internet_connection(service, true);
#endif
break;
@@ -9353,6 +9531,8 @@ static int service_indicate_state(struct connman_service *service)
proxy_changed(service);
#if defined TIZEN_EXT
}
+
+ emit_wifi_roaming_failure(service, new_state);
#endif
/*
@@ -9371,7 +9551,8 @@ static int service_indicate_state(struct connman_service *service)
service->order = 5;
__connman_service_auto_connect(CONNMAN_SERVICE_CONNECT_REASON_AUTO);
#endif
- if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
+ if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER ||
+ service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_NATIVE) {
connman_agent_report_error(service, service->path,
error2string(service->error),
report_error_cb,
@@ -9393,55 +9574,7 @@ static int service_indicate_state(struct connman_service *service)
#else
__connman_service_connect_default(service);
#endif
- /* Update Wi-Fi Roaming result */
- if (connman_setting_get_bool("WifiRoaming") &&
- connman_network_get_bool(service->network, "WiFi.Roaming")) {
- const char *cur_bssid;
- const char *dst_bssid;
- const char *ifname;
- struct connman_device *device;
-
- device = connman_network_get_device(service->network);
- if (device) {
- ifname = connman_device_get_string(device, "Interface");
- cur_bssid = connman_network_get_string(service->network,
- "WiFi.RoamingCurBSSID");
- dst_bssid = connman_network_get_string(service->network,
- "WiFi.RoamingDstBSSID");
- }
-
- if (device && ifname && cur_bssid && dst_bssid) {
- switch(new_state) {
- case CONNMAN_SERVICE_STATE_UNKNOWN:
- case CONNMAN_SERVICE_STATE_ASSOCIATION:
- case CONNMAN_SERVICE_STATE_CONFIGURATION:
- break;
- case CONNMAN_SERVICE_STATE_READY:
- case CONNMAN_SERVICE_STATE_ONLINE:
- __connman_technology_notify_roaming_state(ifname,
- "success", cur_bssid, dst_bssid);
- connman_network_set_bool(service->network,
- "WiFi.Roaming", false);
- connman_network_set_string(service->network,
- "WiFi.RoamingCurBSSID", NULL);
- connman_network_set_string(service->network,
- "WiFi.RoamingDstBSSID", NULL);
- break;
- case CONNMAN_SERVICE_STATE_DISCONNECT:
- case CONNMAN_SERVICE_STATE_FAILURE:
- case CONNMAN_SERVICE_STATE_IDLE:
- __connman_technology_notify_roaming_state(ifname,
- "failure", cur_bssid, dst_bssid);
- connman_network_set_bool(service->network,
- "WiFi.Roaming", false);
- connman_network_set_string(service->network,
- "WiFi.RoamingCurBSSID", NULL);
- connman_network_set_string(service->network,
- "WiFi.RoamingDstBSSID", NULL);
- break;
- }
- }
- }
+ emit_wifi_roaming_failure(service, new_state);
#endif
__connman_connection_update_gateway();
@@ -9475,6 +9608,20 @@ int __connman_service_indicate_error(struct connman_service *service,
if (service->state == CONNMAN_SERVICE_STATE_FAILURE)
return -EALREADY;
+#if defined TIZEN_EXT
+ /*
+ * change connman_service_error type
+ * from CONNMAN_SERVICE_ERROR_AUTH_FAILED to CONNMAN_SERVICE_ERROR_INVALID_KEY
+ * in case of SAE security type.
+ */
+ if (error == CONNMAN_SERVICE_ERROR_AUTH_FAILED &&
+ service->security == CONNMAN_SERVICE_SECURITY_SAE) {
+ DBG("SAE security auth failed, set error to invalid-key and ignore the service");
+ error = CONNMAN_SERVICE_ERROR_INVALID_KEY;
+ __connman_service_set_ignore(service, true);
+ }
+#endif
+
set_error(service, error);
/* default internet service: fix not cleared if pdp activation*/
@@ -10124,6 +10271,10 @@ static int service_connect(struct connman_service *service)
return -ENOKEY;
break;
+#if defined TIZEN_EXT
+ default:
+ break;
+#endif
}
break;
}
@@ -10150,6 +10301,10 @@ static int service_connect(struct connman_service *service)
case CONNMAN_SERVICE_SECURITY_8021X:
prepare_8021x(service);
break;
+#if defined TIZEN_EXT
+ default:
+ break;
+#endif
}
if (__connman_stats_service_register(service) == 0) {
@@ -10185,6 +10340,7 @@ static int service_connect(struct connman_service *service)
int __connman_service_connect(struct connman_service *service,
enum connman_service_connect_reason reason)
{
+ int index;
int err;
DBG("service %p state %s connect reason %s -> %s",
@@ -10254,7 +10410,8 @@ int __connman_service_connect(struct connman_service *service,
service->provider)
connman_provider_disconnect(service->provider);
- if (service->connect_reason == CONNMAN_SERVICE_CONNECT_REASON_USER) {
+ if (reason == CONNMAN_SERVICE_CONNECT_REASON_USER ||
+ reason == CONNMAN_SERVICE_CONNECT_REASON_NATIVE) {
if (err == -ENOKEY || err == -EPERM) {
DBusMessage *pending = NULL;
const char *dbus_sender = get_dbus_sender(service);
@@ -10277,6 +10434,13 @@ int __connman_service_connect(struct connman_service *service,
if (service->hidden && err != -EINPROGRESS)
service->pending = pending;
+ if (err == -EINPROGRESS) {
+ index = __connman_service_get_index(service);
+ g_hash_table_replace(passphrase_requested,
+ GINT_TO_POINTER(index),
+ GINT_TO_POINTER(true));
+ }
+
return err;
}
}
@@ -10475,6 +10639,63 @@ static struct connman_service *service_get(const char *identifier)
return service;
}
+#if defined TIZEN_EXT
+static void service_load_wpa_passphrase(struct connman_service *service)
+{
+ char *identifier;
+ char *ptr;
+ GKeyFile *keyfile;
+ bool favorite;
+ bool autoconnect;
+ char *passphrase;
+
+ if (service->security != CONNMAN_SERVICE_SECURITY_SAE)
+ return;
+
+ if (service->passphrase)
+ return;
+
+ if (!service->identifier)
+ return;
+
+ identifier = g_strdup(service->identifier);
+ if (!identifier)
+ return;
+
+ ptr = strstr(identifier, "_sae");
+ if (!ptr) {
+ g_free(identifier);
+ return;
+ }
+
+ memcpy(ptr, "_psk", strlen("_psk"));
+
+ keyfile = connman_storage_load_service(identifier);
+ if (!keyfile) {
+ g_free(identifier);
+ return;
+ }
+
+ favorite = g_key_file_get_boolean(keyfile, identifier, "Favorite", NULL);
+ autoconnect = g_key_file_get_boolean(keyfile, identifier, "AutoConnect", NULL);
+
+ if (!favorite || !autoconnect) {
+ g_free(identifier);
+ return;
+ }
+
+ passphrase = g_key_file_get_string(keyfile, identifier, "Passphrase", NULL);
+ if (passphrase) {
+ service->passphrase = g_strdup(passphrase);
+ service->favorite = favorite;
+ service->autoconnect = autoconnect;
+ }
+
+ g_free(identifier);
+ g_free(passphrase);
+}
+#endif
+
static int service_register(struct connman_service *service)
{
#if defined TIZEN_EXT
@@ -10493,16 +10714,21 @@ static int service_register(struct connman_service *service)
#if defined TIZEN_EXT
int ret;
service_load(service);
- ret = service_ext_load(service);
- if (ret == -ERANGE)
- service_ext_save(service);
+ service_load_wpa_passphrase(service);
+
+ if (TIZEN_INS_ENABLED) {
+ ret = service_ext_load(service);
+ if (ret == -ERANGE)
+ service_ext_save(service);
+ }
+
ret = __connman_config_provision_service(service);
if (ret < 0 && !simplified_log)
DBG("Failed to provision service");
#else
if (__connman_config_provision_service(service) < 0)
service_load(service);
-#endif
+#endif /* defined TIZEN_EXT */
g_dbus_register_interface(connection, service->path,
CONNMAN_SERVICE_INTERFACE,
@@ -11061,8 +11287,19 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
if (__connman_network_get_weakness(network))
return service;
+ index = connman_network_get_index(network);
+
if (service->path) {
update_from_network(service, network);
+
+ if (service->ipconfig_ipv4)
+ __connman_ipconfig_set_index(service->ipconfig_ipv4,
+ index);
+
+ if (service->ipconfig_ipv6)
+ __connman_ipconfig_set_index(service->ipconfig_ipv6,
+ index);
+
__connman_connection_update_gateway();
return service;
}
@@ -11093,14 +11330,16 @@ struct connman_service * __connman_service_create_from_network(struct connman_ne
update_from_network(service, network);
- index = connman_network_get_index(network);
-
if (!service->ipconfig_ipv4)
service->ipconfig_ipv4 = create_ip4config(service, index,
CONNMAN_IPCONFIG_METHOD_DHCP);
+ else
+ __connman_ipconfig_set_index(service->ipconfig_ipv4, index);
if (!service->ipconfig_ipv6)
service->ipconfig_ipv6 = create_ip6config(service, index);
+ else
+ __connman_ipconfig_set_index(service->ipconfig_ipv6, index);
service_register(service);
service_schedule_added(service);
@@ -11145,9 +11384,6 @@ void __connman_service_update_from_network(struct connman_network *network)
bool roaming;
const char *name;
bool stats_enable;
-#if defined TIZEN_EXT
- bool need_save = false;
-#endif
service = connman_service_lookup_from_network(network);
if (!service)
@@ -11205,12 +11441,17 @@ roaming:
sorting:
#if defined TIZEN_EXT
- need_save |= update_last_connected_bssid(service);
- need_save |= update_assoc_reject(service);
- if (need_save) {
- g_get_current_time(&service->modified);
- service_ext_save(service);
- need_sort = true;
+ if (TIZEN_INS_ENABLED) {
+ bool need_save = false;
+
+ need_save |= update_last_connected_bssid(service);
+ need_save |= update_assoc_reject(service);
+
+ if (need_save) {
+ g_get_current_time((GTimeVal *)&service->modified);
+ service_ext_save(service);
+ need_sort = true;
+ }
}
#endif
@@ -11396,7 +11637,7 @@ static struct connman_agent_driver agent_driver = {
.context_unref = agent_context_unref,
};
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
static void ins_setting_init(void)
{
int i;
@@ -11459,7 +11700,7 @@ static void ins_setting_init(void)
* So the value for comparison should also be converted to the same.
*/
ins_settings.signal_level3_5ghz = connman_setting_get_int("INSSignalLevel3_5GHz") + 120;
- ins_settings.signal_level3_24ghz = connman_setting_get_int("INSSignalLevel3_24GHz") + 120;
+ ins_settings.signal_level3_24ghz = connman_setting_get_int("INSSignalLevel3_2_4GHz") + 120;
DBG("last_user_selection [%s]", ins_settings.last_user_selection ? "true" : "false");
DBG("last_user_selection_time [%d]", ins_settings.last_user_selection_time);
@@ -11487,7 +11728,7 @@ static void ins_setting_init(void)
DBG("signal_level3_5ghz [%d]", ins_settings.signal_level3_5ghz);
DBG("signal_level3_24ghz [%d]", ins_settings.signal_level3_24ghz);
}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
int __connman_service_init(void)
{
@@ -11509,6 +11750,8 @@ int __connman_service_init(void)
service_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, service_free);
+ passphrase_requested = g_hash_table_new(g_direct_hash, g_direct_equal);
+
services_notify = g_new0(struct _services_notify, 1);
services_notify->remove = g_hash_table_new_full(g_str_hash,
g_str_equal, g_free, NULL);
@@ -11516,9 +11759,10 @@ int __connman_service_init(void)
remove_unprovisioned_services();
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
- ins_setting_init();
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#if defined TIZEN_EXT
+ if (TIZEN_INS_ENABLED)
+ ins_setting_init();
+#endif /* defined TIZEN_EXT */
return 0;
}
@@ -11545,6 +11789,9 @@ void __connman_service_cleanup(void)
g_hash_table_destroy(service_hash);
service_hash = NULL;
+ g_hash_table_destroy(passphrase_requested);
+ passphrase_requested = NULL;
+
g_slist_free(counter_list);
counter_list = NULL;
diff --git a/src/storage.c b/src/storage.c
index fb6dc149..67f6036b 100755
--- a/src/storage.c
+++ b/src/storage.c
@@ -35,9 +35,9 @@
#define SETTINGS "settings"
#define DEFAULT "default.profile"
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
#define INS_SETTINGS "settings.ins"
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
#define MODE (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | \
S_IXGRP | S_IROTH | S_IXOTH)
@@ -133,7 +133,7 @@ int __connman_storage_save_global(GKeyFile *keyfile)
return ret;
}
-#if defined TIZEN_EXT && defined TIZEN_EXT_INS
+#if defined TIZEN_EXT
GKeyFile *__connman_storage_load_ins(void)
{
gchar *pathname;
@@ -165,7 +165,7 @@ int __connman_storage_save_ins(GKeyFile *keyfile)
return ret;
}
-#endif /* defined TIZEN_EXT && defined TIZEN_EXT_INS */
+#endif /* defined TIZEN_EXT */
void __connman_storage_delete_global(void)
{
diff --git a/src/technology.c b/src/technology.c
index 2ba02e2d..d21d790f 100644
--- a/src/technology.c
+++ b/src/technology.c
@@ -84,6 +84,7 @@ struct connman_technology {
*/
char *tethering_ident;
char *tethering_passphrase;
+ int tethering_freq;
bool enable_persistent; /* Save the tech state */
@@ -235,6 +236,12 @@ static void technology_save(struct connman_technology *technology)
technology->random_mac_lifetime);
}
#endif /* TIZEN_EXT */
+ if (technology->tethering_freq == 0)
+ technology->tethering_freq = 2412;
+
+ g_key_file_set_integer(keyfile, identifier,
+ "Tethering.Freq",
+ technology->tethering_freq);
done:
g_free(identifier);
@@ -308,8 +315,7 @@ static int set_tethering(struct connman_technology *technology,
if (!driver || !driver->set_tethering)
continue;
- err = driver->set_tethering(technology, ident, passphrase,
- bridge, enabled);
+ err = driver->set_tethering(technology, bridge, enabled);
if (result == -EINPROGRESS)
continue;
@@ -400,25 +406,32 @@ enum connman_service_type connman_technology_get_type
return technology->type;
}
-bool connman_technology_get_wifi_tethering(const char **ssid,
- const char **psk)
+bool connman_technology_get_wifi_tethering(const struct connman_technology *technology,
+ const char **ssid, const char **psk,
+ int *freq)
{
- struct connman_technology *technology;
+ bool force = true;
if (!ssid || !psk)
return false;
*ssid = *psk = NULL;
- technology = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
+ /* Workaround for the neard plugin */
+ if (!technology) {
+ technology = technology_find(CONNMAN_SERVICE_TYPE_WIFI);
+ force = false;
+ }
+
if (!technology)
return false;
- if (!technology->tethering)
+ if (!force && !technology->tethering)
return false;
*ssid = technology->tethering_ident;
*psk = technology->tethering_passphrase;
+ *freq = technology->tethering_freq;
return true;
}
@@ -540,6 +553,9 @@ static void technology_load(struct connman_technology *technology)
}
#endif /* TIZEN_EXT */
+ technology->tethering_freq = g_key_file_get_integer(keyfile,
+ identifier, "Tethering.Freq", NULL);
+
done:
g_free(identifier);
@@ -743,6 +759,9 @@ static void append_properties(DBusMessageIter *iter,
DBUS_TYPE_STRING,
&technology->regdom);
#endif
+ connman_dbus_dict_append_basic(&dict, "TetheringFreq",
+ DBUS_TYPE_INT32,
+ &technology->tethering_freq);
connman_dbus_dict_close(iter, &dict);
}
@@ -1440,6 +1459,27 @@ static DBusMessage *set_property(DBusConnection *conn,
DBUS_TYPE_STRING,
&technology->tethering_passphrase);
}
+ } else if (g_str_equal(name, "TetheringFreq")) {
+ dbus_int32_t freq;
+
+ if (type != DBUS_TYPE_INT32)
+ return __connman_error_invalid_arguments(msg);
+
+ dbus_message_iter_get_basic(&value, &freq);
+
+ if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return __connman_error_not_supported(msg);
+
+ if (freq >= 0) {
+ technology->tethering_freq = freq;
+ technology_save(technology);
+
+ connman_dbus_property_changed_basic(technology->path,
+ CONNMAN_TECHNOLOGY_INTERFACE,
+ "TetheringFreq",
+ DBUS_TYPE_INT32,
+ &technology->tethering_freq);
+ }
} else if (g_str_equal(name, "Powered")) {
dbus_bool_t enable;
@@ -1675,6 +1715,19 @@ static void __connman_technology_notify_device_detected(
DBG("Successfuly sent DeviceDetected signal");
}
+void __connman_technology_notify_device_detected_by_device(
+ struct connman_device *device, const char *ifname, bool val)
+{
+ struct connman_technology *technology;
+ enum connman_service_type type;
+
+ type = __connman_device_get_service_type(device);
+
+ technology = technology_find(type);
+ if (technology)
+ __connman_technology_notify_device_detected(technology, ifname, val);
+}
+
void __connman_technology_notify_roaming_state(const char *ifname,
const char *state, const char *cur_bssid, const char *dst_bssid)
{
@@ -2064,6 +2117,41 @@ static DBusMessage *get_5ghz_supported(DBusConnection *conn, DBusMessage *msg, v
return reply;
}
+static DBusMessage *get_6ghz_supported(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ DBusMessage *reply;
+ DBusMessageIter iter, dict;
+ GSList *list;
+ struct connman_technology *technology = data;
+ dbus_bool_t supported = false;
+ const char *ifname = NULL;
+
+ DBG("technology %p", technology);
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &iter);
+ connman_dbus_dict_open(&iter, &dict);
+
+ for (list = technology->device_list; list; list = list->next) {
+ struct connman_device *device = list->data;
+
+ supported = connman_device_get_wifi_6ghz_supported(device);
+ ifname = connman_device_get_string(device, "Interface");
+
+ DBG("ifname %s supported : %d", ifname, supported);
+ connman_dbus_dict_append_basic(&dict, ifname,
+ DBUS_TYPE_BOOLEAN,
+ &supported);
+ }
+
+ connman_dbus_dict_close(&iter, &dict);
+
+ return reply;
+}
+
static DBusMessage *get_scan_state(DBusConnection *conn, DBusMessage *msg, void *data)
{
DBusMessage *reply;
@@ -2842,6 +2930,8 @@ static const GDBusMethodTable technology_methods[] = {
get_scan_state) },
{ GDBUS_METHOD("Get5GhzSupported", NULL, GDBUS_ARGS({ "supported", "a{sv}" }),
get_5ghz_supported) },
+ { GDBUS_METHOD("Get6GHzSupported", NULL, GDBUS_ARGS({ "supported", "a{sv}" }),
+ get_6ghz_supported) },
{ GDBUS_METHOD("GetMaxScanSsid", NULL, GDBUS_ARGS({ "maxscanssid", "a{sv}" }),
get_max_scan_ssid) },
{ GDBUS_ASYNC_METHOD("SetDevicePower",
@@ -2925,7 +3015,9 @@ static void technology_put(struct connman_technology *technology)
g_slist_delete_link(technology->driver_list,
technology->driver_list);
}
-
+#ifdef TIZEN_EXT
+ __connman_technology_notify_device_detected(technology, "", false);
+#endif
technology_list = g_slist_remove(technology_list, technology);
technology_dbus_unregister(technology);
@@ -3345,9 +3437,6 @@ int __connman_technology_remove_device(struct connman_device *device)
#if defined TIZEN_EXT
technology_save_device(device);
-
- const char *ifname = connman_device_get_string(device, "Interface");
- __connman_technology_notify_device_detected(technology, ifname, false);
#endif
if (technology->tethering)
diff --git a/src/timeserver.c b/src/timeserver.c
index b2707fad..2df609f3 100755
--- a/src/timeserver.c
+++ b/src/timeserver.c
@@ -206,7 +206,12 @@ static void sync_next(void)
return;
}
#if defined TIZEN_EXT
- if (!simplified_log)
+ if (ts_current[0] == '\0') {
+ DBG("current time server is empty. ignore next time server..");
+ return;
+ }
+
+ if (!simplified_log)
#endif
DBG("Resolving timeserver %s", ts_current);
#if defined TIZEN_EXT
diff --git a/src/wispr.c b/src/wispr.c
index fb101a1d..f4dcb73e 100755
--- a/src/wispr.c
+++ b/src/wispr.c
@@ -30,9 +30,6 @@
#include "connman.h"
-#define STATUS_URL_IPV4 "http://ipv4.connman.net/online/status.html"
-#define STATUS_URL_IPV6 "http://ipv6.connman.net/online/status.html"
-
struct connman_wispr_message {
bool has_error;
const char *current_element;
@@ -96,6 +93,8 @@ static bool wispr_portal_web_result(GWebResult *result, gpointer user_data);
static GHashTable *wispr_portal_list = NULL;
+static char *online_check_ipv4_url = NULL;
+static char *online_check_ipv6_url = NULL;
static bool enable_online_to_ready_transition = false;
static void connman_wispr_message_init(struct connman_wispr_message *msg)
@@ -426,7 +425,8 @@ static void wispr_portal_error(struct connman_wispr_portal_context *wp_context)
wp_context->wispr_result = CONNMAN_WISPR_RESULT_FAILED;
#if defined TIZEN_EXT
- connman_service_set_internet_connection(wp_context->service, false);
+ if (TIZEN_INS_ENABLED)
+ connman_service_set_internet_connection(wp_context->service, false);
#endif
}
@@ -937,10 +937,10 @@ static int wispr_portal_detect(struct connman_wispr_portal_context *wp_context)
if (wp_context->type == CONNMAN_IPCONFIG_TYPE_IPV4) {
g_web_set_address_family(wp_context->web, AF_INET);
- wp_context->status_url = STATUS_URL_IPV4;
+ wp_context->status_url = online_check_ipv4_url;
} else {
g_web_set_address_family(wp_context->web, AF_INET6);
- wp_context->status_url = STATUS_URL_IPV6;
+ wp_context->status_url = online_check_ipv6_url;
}
for (i = 0; nameservers[i]; i++)
@@ -1047,17 +1047,11 @@ void __connman_wispr_stop(struct connman_service *service)
if (!wispr_portal)
return;
- if (wispr_portal->ipv4_context) {
- if (service == wispr_portal->ipv4_context->service)
- g_hash_table_remove(wispr_portal_list,
- GINT_TO_POINTER(index));
- }
-
- if (wispr_portal->ipv6_context) {
- if (service == wispr_portal->ipv6_context->service)
- g_hash_table_remove(wispr_portal_list,
- GINT_TO_POINTER(index));
- }
+ if ((wispr_portal->ipv4_context &&
+ service == wispr_portal->ipv4_context->service) ||
+ (wispr_portal->ipv6_context &&
+ service == wispr_portal->ipv6_context->service))
+ g_hash_table_remove(wispr_portal_list, GINT_TO_POINTER(index));
}
int __connman_wispr_init(void)
@@ -1068,6 +1062,11 @@ int __connman_wispr_init(void)
g_direct_equal, NULL,
free_connman_wispr_portal);
+ online_check_ipv4_url =
+ connman_setting_get_string("OnlineCheckIPv4URL");
+ online_check_ipv6_url =
+ connman_setting_get_string("OnlineCheckIPv6URL");
+
enable_online_to_ready_transition =
connman_setting_get_bool("EnableOnlineToReadyTransition");
diff --git a/tools/ip6tables-test.c b/tools/ip6tables-test.c
index 41e842dd..a52f4af0 100644
--- a/tools/ip6tables-test.c
+++ b/tools/ip6tables-test.c
@@ -45,7 +45,7 @@ int main(int argc, char *argv[])
{
enum iptables_command cmd = IPTABLES_COMMAND_UNKNOWN;
char *table = NULL, *chain = NULL, *rule = NULL, *tmp;
- int err, c, i;
+ int err = -EINVAL, c, i;
opterr = 0;
diff --git a/tools/iptables-test.c b/tools/iptables-test.c
index e9b7cb22..f9d091eb 100755
--- a/tools/iptables-test.c
+++ b/tools/iptables-test.c
@@ -44,7 +44,7 @@ int main(int argc, char *argv[])
{
enum iptables_command cmd = IPTABLES_COMMAND_UNKNOWN;
char *table = NULL, *chain = NULL, *rule = NULL, *tmp;
- int err, c, i;
+ int err = -EINVAL, c, i;
opterr = 0;
diff --git a/unit/test-iptables.c b/unit/test-iptables.c
index cd261d05..f08736ea 100644
--- a/unit/test-iptables.c
+++ b/unit/test-iptables.c
@@ -69,13 +69,13 @@ static void set_test_config(enum configtype type)
#define IP6T_SO_GET_INFO (IP6T_BASE_CTL)
#define IP6T_SO_GET_ENTRIES (IP6T_BASE_CTL + 1)
-int xt_match_parse(int c, char **argv, int invert, unsigned int *flags,
+int static xt_match_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match)
{
return 0;
}
-int xt_target_parse(int c, char **argv, int invert, unsigned int *flags,
+int static xt_target_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_target **targetinfo)
{
return 0;
diff --git a/vpn/plugins/l2tp.c b/vpn/plugins/l2tp.c
index 1e4fcd1f..ee40dd72 100755
--- a/vpn/plugins/l2tp.c
+++ b/vpn/plugins/l2tp.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2010,2013 BMW Car IT GmbH.
* Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -121,12 +122,40 @@ struct {
static DBusConnection *connection;
struct l2tp_private_data {
+ struct vpn_provider *provider;
struct connman_task *task;
char *if_name;
vpn_provider_connect_cb_t cb;
void *user_data;
};
+static void l2tp_connect_done(struct l2tp_private_data *data, int err)
+{
+ vpn_provider_connect_cb_t cb;
+ void *user_data;
+
+ if (!data || !data->cb)
+ return;
+
+ /* Ensure that callback is called only once */
+ cb = data->cb;
+ user_data = data->user_data;
+ data->cb = NULL;
+ data->user_data = NULL;
+ cb(data->provider, user_data, err);
+}
+
+static void free_private_data(struct l2tp_private_data *data)
+{
+ if (vpn_provider_get_plugin_data(data->provider) == data)
+ vpn_provider_set_plugin_data(data->provider, NULL);
+
+ l2tp_connect_done(data, EIO);
+ vpn_provider_unref(data->provider);
+ g_free(data->if_name);
+ g_free(data);
+}
+
static DBusMessage *l2tp_get_sec(struct connman_task *task,
DBusMessage *msg, void *user_data)
{
@@ -164,6 +193,9 @@ static int l2tp_notify(DBusMessage *msg, struct vpn_provider *provider)
char *addressv4 = NULL, *netmask = NULL, *gateway = NULL;
char *ifname = NULL, *nameservers = NULL;
struct connman_ipaddress *ipaddress = NULL;
+ struct l2tp_private_data *data;
+
+ data = vpn_provider_get_plugin_data(provider);
dbus_message_iter_init(msg, &iter);
@@ -182,11 +214,22 @@ static int l2tp_notify(DBusMessage *msg, struct vpn_provider *provider)
vpn_provider_set_string_hide_value(provider, "L2TP.Password",
NULL);
+ l2tp_connect_done(data, EACCES);
return VPN_STATE_AUTH_FAILURE;
}
- if (strcmp(reason, "connect"))
+ if (strcmp(reason, "connect")) {
+ l2tp_connect_done(data, EIO);
+
+ /*
+ * Stop the task to avoid potential looping of this state when
+ * authentication fails.
+ */
+ if (data && data->task)
+ connman_task_stop(data->task);
+
return VPN_STATE_DISCONNECT;
+ }
dbus_message_iter_recurse(&iter, &dict);
@@ -257,6 +300,8 @@ static int l2tp_notify(DBusMessage *msg, struct vpn_provider *provider)
g_free(nameservers);
connman_ipaddress_free(ipaddress);
+ l2tp_connect_done(data, 0);
+
return VPN_STATE_CONNECT;
}
@@ -476,9 +521,10 @@ static int l2tp_write_config(struct vpn_provider *provider,
static void l2tp_died(struct connman_task *task, int exit_code, void *user_data)
{
+ struct l2tp_private_data *data = user_data;
char *conf_file;
- vpn_died(task, exit_code, user_data);
+ vpn_died(task, exit_code, data->provider);
conf_file = g_strdup_printf(VPN_STATEDIR "/connman-xl2tpd.conf");
unlink(conf_file);
@@ -487,6 +533,8 @@ static void l2tp_died(struct connman_task *task, int exit_code, void *user_data)
conf_file = g_strdup_printf(VPN_STATEDIR "/connman-ppp-option.conf");
unlink(conf_file);
g_free(conf_file);
+
+ free_private_data(data);
}
struct request_input_reply {
@@ -646,12 +694,12 @@ static int request_input(struct vpn_provider *provider,
return -EINPROGRESS;
}
-static int run_connect(struct vpn_provider *provider,
- struct connman_task *task, const char *if_name,
- vpn_provider_connect_cb_t cb, void *user_data,
+static int run_connect(struct l2tp_private_data *data,
const char *username, const char *password)
{
- char *l2tp_name, *pppd_name;
+ struct vpn_provider *provider = data->provider;
+ struct connman_task *task = data->task;
+ char *l2tp_name, *ctrl_name, *pppd_name;
int l2tp_fd, pppd_fd;
int err;
@@ -674,12 +722,24 @@ static int run_connect(struct vpn_provider *provider,
goto done;
}
- pppd_name = g_strdup_printf(VPN_STATEDIR "/connman-ppp-option.conf");
+ ctrl_name = g_strconcat(VPN_STATEDIR, "/connman-xl2tpd-control", NULL);
+
+ if (mkfifo(ctrl_name, S_IRUSR|S_IWUSR) != 0 && errno != EEXIST) {
+ connman_error("Error creating xl2tp control pipe");
+ g_free(l2tp_name);
+ g_free(ctrl_name);
+ close(l2tp_fd);
+ err = -EIO;
+ goto done;
+ }
+
+ pppd_name = g_strconcat(VPN_STATEDIR, "/connman-ppp-option.conf", NULL);
pppd_fd = open(pppd_name, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
if (pppd_fd < 0) {
connman_error("Error writing pppd config");
g_free(l2tp_name);
+ g_free(ctrl_name);
g_free(pppd_name);
close(l2tp_fd);
err = -EIO;
@@ -691,34 +751,28 @@ static int run_connect(struct vpn_provider *provider,
write_pppd_option(provider, pppd_fd);
connman_task_add_argument(task, "-D", NULL);
+ connman_task_add_argument(task, "-C", ctrl_name);
connman_task_add_argument(task, "-c", l2tp_name);
g_free(l2tp_name);
+ g_free(ctrl_name);
g_free(pppd_name);
close(l2tp_fd);
close(pppd_fd);
- err = connman_task_run(task, l2tp_died, provider,
- NULL, NULL, NULL);
+ err = connman_task_run(task, l2tp_died, data, NULL, NULL, NULL);
if (err < 0) {
connman_error("l2tp failed to start");
err = -EIO;
- goto done;
}
done:
- if (cb)
- cb(provider, user_data, err);
+ if (err)
+ l2tp_connect_done(data, -err);
return err;
}
-static void free_private_data(struct l2tp_private_data *data)
-{
- g_free(data->if_name);
- g_free(data);
-}
-
static void request_input_cb(struct vpn_provider *provider,
const char *username,
const char *password,
@@ -736,10 +790,7 @@ static void request_input_cb(struct vpn_provider *provider,
vpn_provider_set_string_hide_value(provider, "L2TP.Password",
password);
- run_connect(provider, data->task, data->if_name, data->cb,
- data->user_data, username, password);
-
- free_private_data(data);
+ run_connect(data, username, password);
}
static int l2tp_connect(struct vpn_provider *provider,
@@ -747,9 +798,21 @@ static int l2tp_connect(struct vpn_provider *provider,
vpn_provider_connect_cb_t cb, const char *dbus_sender,
void *user_data)
{
+ struct l2tp_private_data *data;
const char *username, *password;
int err;
+ data = g_try_new0(struct l2tp_private_data, 1);
+ if (!data)
+ return -ENOMEM;
+
+ data->provider = vpn_provider_ref(provider);
+ data->task = task;
+ data->if_name = g_strdup(if_name);
+ data->cb = cb;
+ data->user_data = user_data;
+ vpn_provider_set_plugin_data(provider, data);
+
if (connman_task_set_notify(task, "getsec",
l2tp_get_sec, provider) != 0) {
err = -ENOMEM;
@@ -762,33 +825,19 @@ static int l2tp_connect(struct vpn_provider *provider,
DBG("user %s password %p", username, password);
if (!username || !*username || !password || !*password) {
- struct l2tp_private_data *data;
-
- data = g_try_new0(struct l2tp_private_data, 1);
- if (!data)
- return -ENOMEM;
-
- data->task = task;
- data->if_name = g_strdup(if_name);
- data->cb = cb;
- data->user_data = user_data;
-
err = request_input(provider, request_input_cb, dbus_sender,
data);
- if (err != -EINPROGRESS) {
- free_private_data(data);
- goto done;
- }
+ if (err != -EINPROGRESS)
+ goto error;
+
return err;
}
-done:
- return run_connect(provider, task, if_name, cb, user_data,
- username, password);
+ return run_connect(data, username, password);
error:
- if (cb)
- cb(provider, user_data, err);
+ l2tp_connect_done(data, -err);
+ free_private_data(data);
return err;
}
diff --git a/vpn/plugins/openconnect.c b/vpn/plugins/openconnect.c
index fc6ceff0..fb63a1a3 100755
--- a/vpn/plugins/openconnect.c
+++ b/vpn/plugins/openconnect.c
@@ -110,6 +110,7 @@ struct oc_private_data {
GIOChannel *err_ch;
enum oc_connect_type connect_type;
bool tried_passphrase;
+ bool group_set;
};
typedef void (*request_input_reply_cb_t) (DBusMessage *reply,
@@ -473,6 +474,7 @@ static void clear_provider_credentials(struct vpn_provider *provider,
const char *keys[] = { "OpenConnect.PKCSPassword",
"OpenConnect.Username",
"OpenConnect.Password",
+ "OpenConnect.SecondPassword",
"OpenConnect.Cookie",
NULL
};
@@ -794,13 +796,46 @@ static gboolean process_auth_form(void *user_data)
{
struct process_form_data *form_data = user_data;
struct oc_private_data *data = form_data->data;
+ struct oc_form_opt_select *authgroup_opt;
struct oc_form_opt *opt;
const char *password;
+ const char *group;
+ int i;
g_mutex_lock(&form_data->mutex);
DBG("");
+ /*
+ * Special handling for "GROUP:" field, if present.
+ * Different group selections can make other fields disappear/appear
+ */
+ if (form_data->form->authgroup_opt) {
+ group = vpn_provider_get_string(data->provider, "OpenConnect.Group");
+ authgroup_opt = form_data->form->authgroup_opt;
+
+ if (group && !data->group_set) {
+ for (i = 0; i < authgroup_opt->nr_choices; i++) {
+ struct oc_choice *choice = authgroup_opt->choices[i];
+
+ if (!strcmp(group, choice->label)) {
+ DBG("Switching to auth group: %s", group);
+ openconnect_set_option_value(&authgroup_opt->form,
+ choice->name);
+ data->group_set = true;
+ form_data->status = OC_FORM_RESULT_NEWGROUP;
+ goto out;
+ }
+ }
+
+ connman_warn("Group choice %s not present", group);
+ data->err = -EACCES;
+ clear_provider_credentials(data->provider, true);
+ form_data->status = OC_FORM_RESULT_ERR;
+ goto out;
+ }
+ }
+
switch (data->connect_type) {
case OC_CONNECT_USERPASS:
case OC_CONNECT_COOKIE_WITH_USERPASS:
@@ -872,12 +907,21 @@ static gboolean process_auth_form(void *user_data)
"OpenConnect.Username");
if (user)
opt->_value = strdup(user);
- } else if (opt->type == OC_FORM_OPT_PASSWORD) {
+ } else if (opt->type == OC_FORM_OPT_PASSWORD &&
+ g_str_has_prefix(opt->name, "password")) {
+
const char *pass = vpn_provider_get_string(
data->provider,
"OpenConnect.Password");
if (pass)
opt->_value = strdup(pass);
+ } else if (opt->type == OC_FORM_OPT_PASSWORD &&
+ g_str_has_prefix(opt->name, "secondary_password")) {
+ const char *pass = vpn_provider_get_string(
+ data->provider,
+ "OpenConnect.SecondPassword");
+ if (pass)
+ opt->_value = strdup(pass);
}
}
@@ -1201,6 +1245,7 @@ static void request_input_credentials_reply(DBusMessage *reply, void *user_data)
const char *vpnhost = NULL;
const char *username = NULL;
const char *password = NULL;
+ const char *second_password = NULL;
const char *pkcspassword = NULL;
const char *key;
DBusMessageIter iter, dict;
@@ -1298,6 +1343,19 @@ static void request_input_credentials_reply(DBusMessage *reply, void *user_data)
dbus_message_iter_get_basic(&value, &password);
vpn_provider_set_string_hide_value(data->provider,
"OpenConnect.Password", password);
+ } else if (g_str_equal(key, "OpenConnect.SecondPassword")) {
+ dbus_message_iter_next(&entry);
+ if (dbus_message_iter_get_arg_type(&entry)
+ != DBUS_TYPE_VARIANT)
+ break;
+ dbus_message_iter_recurse(&entry, &value);
+ if (dbus_message_iter_get_arg_type(&value)
+ != DBUS_TYPE_STRING)
+ break;
+ dbus_message_iter_get_basic(&value, &second_password);
+ vpn_provider_set_string_hide_value(data->provider,
+ "OpenConnect.SecondPassword",
+ second_password);
} else if (g_str_equal(key, "OpenConnect.PKCSPassword")) {
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry)
@@ -1374,6 +1432,7 @@ static int request_input_credentials_full(
DBusMessageIter dict;
int err;
void *agent;
+ bool use_second_password = false;
if (!data || !cb)
return -ESRCH;
@@ -1440,6 +1499,16 @@ static int request_input_credentials_full(
username = vpn_provider_get_string(data->provider,
"OpenConnect.Username");
vpn_agent_append_user_info(&dict, data->provider, username);
+
+ use_second_password = vpn_provider_get_boolean(data->provider,
+ "OpenConnect.UseSecondPassword",
+ false);
+
+ if (use_second_password)
+ request_input_append_to_dict(data->provider, &dict,
+ request_input_append_password,
+ "OpenConnect.SecondPassword");
+
break;
case OC_CONNECT_PUBLICKEY:
return -EINVAL;
@@ -1520,8 +1589,10 @@ static int oc_connect(struct vpn_provider *provider,
const char *certificate;
const char *username;
const char *password;
+ const char *second_password = NULL;
const char *private_key;
int err;
+ bool use_second_password = false;
connman_info("provider %p task %p", provider, task);
@@ -1551,8 +1622,18 @@ static int oc_connect(struct vpn_provider *provider,
"OpenConnect.Username");
password = vpn_provider_get_string(provider,
"OpenConnect.Password");
+
+ use_second_password = vpn_provider_get_boolean(provider,
+ "OpenConnect.UseSecondPassword",
+ false);
+
+ if (use_second_password)
+ second_password = vpn_provider_get_string(provider,
+ "OpenConnect.SecondPassword");
+
if (!username || !password || !g_strcmp0(username, "-") ||
- !g_strcmp0(password, "-"))
+ !g_strcmp0(password, "-") ||
+ (use_second_password && !second_password))
goto request_input;
break;
diff --git a/vpn/plugins/openvpn.c b/vpn/plugins/openvpn.c
index 8c8d3162..5ab5c5c4 100755
--- a/vpn/plugins/openvpn.c
+++ b/vpn/plugins/openvpn.c
@@ -56,36 +56,48 @@
static DBusConnection *connection;
+enum opt_type {
+ OPT_NONE = 0,
+ OPT_STRING = 1,
+ OPT_BOOL = 2,
+};
+
struct {
- const char *cm_opt;
- const char *ov_opt;
- char has_value;
+ const char *cm_opt;
+ const char *ov_opt;
+ const char *ov_opt_to_null;
+ enum opt_type opt_type;
} ov_options[] = {
- { "Host", "--remote", 1 },
- { "OpenVPN.CACert", "--ca", 1 },
- { "OpenVPN.Cert", "--cert", 1 },
- { "OpenVPN.Key", "--key", 1 },
- { "OpenVPN.MTU", "--tun-mtu", 1 },
- { "OpenVPN.NSCertType", "--ns-cert-type", 1 },
- { "OpenVPN.Proto", "--proto", 1 },
- { "OpenVPN.Port", "--port", 1 },
- { "OpenVPN.AuthUserPass", "--auth-user-pass", 1 },
- { "OpenVPN.AskPass", "--askpass", 1 },
- { "OpenVPN.AuthNoCache", "--auth-nocache", 0 },
- { "OpenVPN.TLSRemote", "--tls-remote", 1 },
- { "OpenVPN.TLSAuth", NULL, 1 },
- { "OpenVPN.TLSAuthDir", NULL, 1 },
- { "OpenVPN.TLSCipher", "--tls-cipher", 1},
- { "OpenVPN.Cipher", "--cipher", 1 },
- { "OpenVPN.Auth", "--auth", 1 },
- { "OpenVPN.CompLZO", "--comp-lzo", 0 },
- { "OpenVPN.RemoteCertTls", "--remote-cert-tls", 1 },
- { "OpenVPN.ConfigFile", "--config", 1 },
- { "OpenVPN.DeviceType", NULL, 1 },
- { "OpenVPN.Verb", "--verb", 1 },
- { "OpenVPN.Ping", "--ping", 1},
- { "OpenVPN.PingExit", "--ping-exit", 1},
- { "OpenVPN.RemapUsr1", "--remap-usr1", 1},
+ { "Host", "--remote", NULL, OPT_STRING},
+ { "OpenVPN.CACert", "--ca", NULL, OPT_STRING},
+ { "OpenVPN.Cert", "--cert", NULL, OPT_STRING},
+ { "OpenVPN.Key", "--key", NULL, OPT_STRING},
+ { "OpenVPN.MTU", "--tun-mtu", NULL, OPT_STRING},
+ { "OpenVPN.NSCertType", "--ns-cert-type", NULL, OPT_STRING},
+ { "OpenVPN.Proto", "--proto", NULL, OPT_STRING},
+ { "OpenVPN.Port", "--port", NULL, OPT_STRING},
+ /*
+ * If the AuthUserPass option is "-", provide the input via management
+ * interface. To facilitate this set the option as NULL.
+ */
+ { "OpenVPN.AuthUserPass", "--auth-user-pass", "-", OPT_STRING},
+ { "OpenVPN.AskPass", "--askpass", NULL, OPT_STRING},
+ { "OpenVPN.AuthNoCache", "--auth-nocache", NULL, OPT_BOOL},
+ { "OpenVPN.TLSRemote", "--tls-remote", NULL, OPT_STRING},
+ { "OpenVPN.TLSAuth", NULL, NULL, OPT_NONE},
+ { "OpenVPN.TLSCipher", "--tls-cipher", NULL, OPT_STRING},
+ { "OpenVPN.TLSAuthDir", NULL, NULL, OPT_NONE},
+ { "OpenVPN.Cipher", "--cipher", NULL, OPT_STRING},
+ { "OpenVPN.Auth", "--auth", NULL, OPT_STRING},
+ /* Is set to adaptive by default if value is omitted */
+ { "OpenVPN.CompLZO", "--comp-lzo", NULL, OPT_STRING},
+ { "OpenVPN.RemoteCertTls", "--remote-cert-tls", NULL, OPT_STRING},
+ { "OpenVPN.ConfigFile", "--config", NULL, OPT_STRING},
+ { "OpenVPN.DeviceType", NULL, NULL, OPT_NONE},
+ { "OpenVPN.Verb", "--verb", NULL, OPT_STRING},
+ { "OpenVPN.Ping", "--ping", NULL, OPT_STRING},
+ { "OpenVPN.PingExit", "--ping-exit", NULL, OPT_STRING},
+ { "OpenVPN.RemapUsr1", "--remap-usr1", NULL, OPT_STRING},
};
struct ov_private_data {
@@ -362,29 +374,49 @@ static int ov_save(struct vpn_provider *provider, GKeyFile *keyfile)
static int task_append_config_data(struct vpn_provider *provider,
struct connman_task *task)
{
- const char *option;
int i;
for (i = 0; i < (int)ARRAY_SIZE(ov_options); i++) {
- if (!ov_options[i].ov_opt)
- continue;
+ const char *ov_opt = ov_options[i].ov_opt;
+ const char *cm_opt = ov_options[i].cm_opt;
+ const char *option = NULL;
+ const char *opt_to_null;
- option = vpn_provider_get_string(provider,
- ov_options[i].cm_opt);
- if (!option)
+ switch (ov_options[i].opt_type) {
+ case OPT_NONE:
continue;
- /*
- * If the AuthUserPass option is "-", provide the input
- * via management interface
- */
- if (!strcmp(ov_options[i].cm_opt, "OpenVPN.AuthUserPass") &&
- !strcmp(option, "-"))
- option = NULL;
+ case OPT_STRING:
+ if (!ov_opt)
+ continue;
+
+ option = vpn_provider_get_string(provider, cm_opt);
+ /*
+ * A string option may be used alone without a value
+ * in which case the default value is used by OpenVPN.
+ */
+ if (!option && !vpn_provider_setting_key_exists(
+ provider, ov_opt))
+ continue;
- if (connman_task_add_argument(task,
- ov_options[i].ov_opt,
- ov_options[i].has_value ? option : NULL) < 0)
+ opt_to_null = ov_options[i].ov_opt_to_null;
+ if (opt_to_null && !g_strcmp0(option, opt_to_null))
+ option = NULL;
+
+ break;
+
+ case OPT_BOOL:
+ if (!ov_opt)
+ continue;
+
+ /* Ignore the boolean toggle if option is disabled. */
+ if (!vpn_provider_get_boolean(provider, cm_opt, false))
+ continue;
+
+ break;
+ }
+
+ if (connman_task_add_argument(task, ov_opt, option))
return -EIO;
}
@@ -1108,6 +1140,15 @@ static int ov_connect(struct vpn_provider *provider,
const char *tmpdir;
struct ov_private_data *data;
+ /*
+ * Explicitly set limit of 10 for authentication errors. This defines
+ * the authentication error message limit from the server before VPN
+ * agent is instructed to clear the credentials. This is effective only
+ * after a successful connection has been made within CONNECT_OK_DIFF
+ * time. User defined value for "AuthErrorLimit" overrides this.
+ */
+ vpn_provider_set_auth_error_limit(provider, 10);
+
data = g_try_new0(struct ov_private_data, 1);
if (!data)
return -ENOMEM;
diff --git a/vpn/plugins/pptp.c b/vpn/plugins/pptp.c
index 4a704bb1..7274376f 100755
--- a/vpn/plugins/pptp.c
+++ b/vpn/plugins/pptp.c
@@ -4,6 +4,7 @@
*
* Copyright (C) 2010,2013-2014 BMW Car IT GmbH.
* Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
+ * Copyright (C) 2019-2021 Jolla Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -86,12 +87,40 @@ struct {
static DBusConnection *connection;
struct pptp_private_data {
+ struct vpn_provider *provider;
struct connman_task *task;
char *if_name;
vpn_provider_connect_cb_t cb;
void *user_data;
};
+static void pptp_connect_done(struct pptp_private_data *data, int err)
+{
+ vpn_provider_connect_cb_t cb;
+ void *user_data;
+
+ if (!data || !data->cb)
+ return;
+
+ /* Ensure that callback is called only once */
+ cb = data->cb;
+ user_data = data->user_data;
+ data->cb = NULL;
+ data->user_data = NULL;
+ cb(data->provider, user_data, err);
+}
+
+static void free_private_data(struct pptp_private_data *data)
+{
+ if (vpn_provider_get_plugin_data(data->provider) == data)
+ vpn_provider_set_plugin_data(data->provider, NULL);
+
+ pptp_connect_done(data, EIO);
+ vpn_provider_unref(data->provider);
+ g_free(data->if_name);
+ g_free(data);
+}
+
static DBusMessage *pptp_get_sec(struct connman_task *task,
DBusMessage *msg, void *user_data)
{
@@ -125,6 +154,9 @@ static int pptp_notify(DBusMessage *msg, struct vpn_provider *provider)
char *addressv4 = NULL, *netmask = NULL, *gateway = NULL;
char *ifname = NULL, *nameservers = NULL;
struct connman_ipaddress *ipaddress = NULL;
+ struct pptp_private_data *data;
+
+ data = vpn_provider_get_plugin_data(provider);
dbus_message_iter_init(msg, &iter);
@@ -143,11 +175,22 @@ static int pptp_notify(DBusMessage *msg, struct vpn_provider *provider)
vpn_provider_set_string_hide_value(provider, "PPTP.Password",
NULL);
+ pptp_connect_done(data, EACCES);
return VPN_STATE_AUTH_FAILURE;
}
- if (strcmp(reason, "connect"))
+ if (strcmp(reason, "connect")) {
+ pptp_connect_done(data, EIO);
+
+ /*
+ * Stop the task to avoid potential looping of this state when
+ * authentication fails.
+ */
+ if (data && data->task)
+ connman_task_stop(data->task);
+
return VPN_STATE_DISCONNECT;
+ }
dbus_message_iter_recurse(&iter, &dict);
@@ -217,6 +260,7 @@ static int pptp_notify(DBusMessage *msg, struct vpn_provider *provider)
g_free(nameservers);
connman_ipaddress_free(ipaddress);
+ pptp_connect_done(data, 0);
return VPN_STATE_CONNECT;
}
@@ -278,6 +322,16 @@ static void pptp_write_bool_option(struct connman_task *task,
}
}
+static void pptp_died(struct connman_task *task, int exit_code,
+ void *user_data)
+{
+ struct pptp_private_data *data = user_data;
+
+ vpn_died(task, exit_code, data->provider);
+
+ free_private_data(data);
+}
+
struct request_input_reply {
struct vpn_provider *provider;
vpn_provider_password_cb_t callback;
@@ -435,18 +489,18 @@ static int request_input(struct vpn_provider *provider,
return -EINPROGRESS;
}
-static int run_connect(struct vpn_provider *provider,
- struct connman_task *task, const char *if_name,
- vpn_provider_connect_cb_t cb, void *user_data,
- const char *username, const char *password)
+static int run_connect(struct pptp_private_data *data, const char *username,
+ const char *password)
{
+ struct vpn_provider *provider = data->provider;
+ struct connman_task *task = data->task;
GString *pptp_opt_s;
const char *opt_s;
const char *host;
char *str;
int err, i;
- if (!username || !password) {
+ if (!username || !*username || !password || !*password) {
DBG("Cannot connect username %s password %p",
username, password);
err = -EINVAL;
@@ -498,27 +552,19 @@ static int run_connect(struct vpn_provider *provider,
connman_task_add_argument(task, "plugin",
SCRIPTDIR "/libppp-plugin.so");
- err = connman_task_run(task, vpn_died, provider,
- NULL, NULL, NULL);
+ err = connman_task_run(task, pptp_died, data, NULL, NULL, NULL);
if (err < 0) {
connman_error("pptp failed to start");
err = -EIO;
- goto done;
}
done:
- if (cb)
- cb(provider, user_data, err);
+ if (err)
+ pptp_connect_done(data, -err);
return err;
}
-static void free_private_data(struct pptp_private_data *data)
-{
- g_free(data->if_name);
- g_free(data);
-}
-
static void request_input_cb(struct vpn_provider *provider,
const char *username,
const char *password,
@@ -526,7 +572,7 @@ static void request_input_cb(struct vpn_provider *provider,
{
struct pptp_private_data *data = user_data;
- if (!username || !password)
+ if (!username || !*username || !password || !*password)
DBG("Requesting username %s or password failed, error %s",
username, error);
else if (error)
@@ -536,10 +582,7 @@ static void request_input_cb(struct vpn_provider *provider,
vpn_provider_set_string_hide_value(provider, "PPTP.Password",
password);
- run_connect(provider, data->task, data->if_name, data->cb,
- data->user_data, username, password);
-
- free_private_data(data);
+ run_connect(data, username, password);
}
static int pptp_connect(struct vpn_provider *provider,
@@ -547,9 +590,21 @@ static int pptp_connect(struct vpn_provider *provider,
vpn_provider_connect_cb_t cb, const char *dbus_sender,
void *user_data)
{
+ struct pptp_private_data *data;
const char *username, *password;
int err;
+ data = g_try_new0(struct pptp_private_data, 1);
+ if (!data)
+ return -ENOMEM;
+
+ data->provider = vpn_provider_ref(provider);
+ data->task = task;
+ data->if_name = g_strdup(if_name);
+ data->cb = cb;
+ data->user_data = user_data;
+ vpn_provider_set_plugin_data(provider, data);
+
DBG("iface %s provider %p user %p", if_name, provider, user_data);
if (connman_task_set_notify(task, "getsec",
@@ -563,34 +618,20 @@ static int pptp_connect(struct vpn_provider *provider,
DBG("user %s password %p", username, password);
- if (!username || !password) {
- struct pptp_private_data *data;
-
- data = g_try_new0(struct pptp_private_data, 1);
- if (!data)
- return -ENOMEM;
-
- data->task = task;
- data->if_name = g_strdup(if_name);
- data->cb = cb;
- data->user_data = user_data;
-
+ if (!username || !*username || !password || !*password) {
err = request_input(provider, request_input_cb, dbus_sender,
data);
- if (err != -EINPROGRESS) {
- free_private_data(data);
- goto done;
- }
+ if (err != -EINPROGRESS)
+ goto error;
+
return err;
}
-done:
- return run_connect(provider, task, if_name, cb, user_data,
- username, password);
+ return run_connect(data, username, password);
error:
- if (cb)
- cb(provider, user_data, err);
+ pptp_connect_done(data, -err);
+ free_private_data(data);
return err;
}
diff --git a/vpn/vpn-provider.c b/vpn/vpn-provider.c
index 8092b5d6..6defbf27 100755
--- a/vpn/vpn-provider.c
+++ b/vpn/vpn-provider.c
@@ -3,7 +3,7 @@
* ConnMan VPN daemon
*
* Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
- * Copyright (C) 2019 Jolla Ltd. All rights reserved.
+ * Copyright (C) 2019-2021 Jolla Ltd. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -24,6 +24,21 @@
#include <config.h>
#endif
+/*
+ * One hour difference in seconds between connections for checking whether to
+ * treat the authentication error as a real error or as a result of rapid
+ * transport change.
+ */
+#define CONNECT_OK_DIFF ((time_t)60*60)
+#define AUTH_ERROR_LIMIT_DEFAULT 1
+
+#define STATE_INTERVAL_DEFAULT 0
+
+#define CONNMAN_STATE_ONLINE "online"
+#define CONNMAN_STATE_OFFLINE "offline"
+#define CONNMAN_STATE_READY "ready"
+#define CONNMAN_STATE_IDLE "idle"
+
#include <errno.h>
#include <stdio.h>
#include <string.h>
@@ -32,6 +47,7 @@
#include <connman/log.h>
#include <gweb/gresolv.h>
#include <netdb.h>
+#include <time.h>
#include "../src/connman.h"
#include "connman/agent.h"
@@ -89,15 +105,57 @@ struct vpn_provider {
struct connman_ipaddress *prev_ipv4_addr;
struct connman_ipaddress *prev_ipv6_addr;
void *plugin_data;
+ unsigned int do_connect_timeout;
unsigned int auth_error_counter;
unsigned int conn_error_counter;
unsigned int signal_watch;
+ unsigned int auth_error_limit;
+ time_t previous_connect_time;
+};
+
+struct vpn_provider_connect_data {
+ DBusConnection *conn;
+ DBusMessage *msg;
+ struct vpn_provider *provider;
};
+static unsigned int get_connman_state_timeout;
+
+static guint connman_signal_watch;
+static guint connman_service_watch;
+
+static bool connman_online;
+static bool state_query_completed;
+
static void append_properties(DBusMessageIter *iter,
struct vpn_provider *provider);
static int vpn_provider_save(struct vpn_provider *provider);
+static void get_connman_state(void);
+
+static void set_state(const char *new_state)
+{
+ if (!new_state || !*new_state)
+ return;
+
+ DBG("old state %s new state %s",
+ connman_online ?
+ CONNMAN_STATE_ONLINE "/" CONNMAN_STATE_READY :
+ CONNMAN_STATE_OFFLINE "/" CONNMAN_STATE_IDLE,
+ new_state);
+
+ /* States "online" and "ready" mean connman is online */
+ if (!g_ascii_strcasecmp(new_state, CONNMAN_STATE_ONLINE) ||
+ !g_ascii_strcasecmp(new_state, CONNMAN_STATE_READY))
+ connman_online = true;
+ /* Everything else means connman is offline */
+ else
+ connman_online = false;
+
+ DBG("set state %s connman_online=%s ", new_state,
+ connman_online ? "true" : "false");
+}
+
static void free_route(gpointer data)
{
struct vpn_route *route = data;
@@ -740,6 +798,61 @@ static DBusMessage *clear_property(DBusConnection *conn, DBusMessage *msg,
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
}
+static gboolean do_connect_timeout_function(gpointer data)
+{
+ struct vpn_provider_connect_data *cdata = data;
+ struct vpn_provider *provider = cdata->provider;
+ int err;
+
+ DBG("");
+
+ /* Keep in main loop if connman is not online. */
+ if (!connman_online)
+ return G_SOURCE_CONTINUE;
+
+ provider->do_connect_timeout = 0;
+ err = __vpn_provider_connect(provider, cdata->msg);
+
+ if (err < 0 && err != -EINPROGRESS) {
+ g_dbus_send_message(cdata->conn,
+ __connman_error_failed(cdata->msg, -err));
+ cdata->msg = NULL;
+ }
+
+ return G_SOURCE_REMOVE;
+}
+
+static void do_connect_timeout_free(gpointer data)
+{
+ struct vpn_provider_connect_data *cdata = data;
+
+ if (cdata->msg)
+ g_dbus_send_message(cdata->conn,
+ __connman_error_operation_aborted(cdata->msg));
+
+ dbus_connection_unref(cdata->conn);
+ g_free(data);
+}
+
+static void do_connect_later(struct vpn_provider *provider,
+ DBusConnection *conn, DBusMessage *msg)
+{
+ struct vpn_provider_connect_data *cdata =
+ g_new0(struct vpn_provider_connect_data, 1);
+
+ cdata->conn = dbus_connection_ref(conn);
+ cdata->msg = dbus_message_ref(msg);
+ cdata->provider = provider;
+
+ if (provider->do_connect_timeout)
+ g_source_remove(provider->do_connect_timeout);
+
+ provider->do_connect_timeout =
+ g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1,
+ do_connect_timeout_function, cdata,
+ do_connect_timeout_free);
+}
+
static DBusMessage *do_connect(DBusConnection *conn, DBusMessage *msg,
void *data)
{
@@ -748,6 +861,25 @@ static DBusMessage *do_connect(DBusConnection *conn, DBusMessage *msg,
DBG("conn %p provider %p", conn, provider);
+ if (!connman_online) {
+ if (state_query_completed) {
+ DBG("%s not started - ConnMan not online/ready",
+ provider->identifier);
+ return __connman_error_failed(msg, ENOLINK);
+ }
+
+ DBG("%s start delayed - ConnMan state not queried",
+ provider->identifier);
+ do_connect_later(provider, conn, msg);
+ return NULL;
+ }
+
+ /* Cancel delayed connection if connmand is online. */
+ if (provider->do_connect_timeout) {
+ g_source_remove(provider->do_connect_timeout);
+ provider->do_connect_timeout = 0;
+ }
+
err = __vpn_provider_connect(provider, msg);
if (err < 0 && err != -EINPROGRESS)
return __connman_error_failed(msg, -err);
@@ -1117,12 +1249,15 @@ static void reset_error_counters(struct vpn_provider *provider)
if (!provider)
return;
+ DBG("provider %p", provider);
+
provider->auth_error_counter = provider->conn_error_counter = 0;
}
static int vpn_provider_save(struct vpn_provider *provider)
{
GKeyFile *keyfile;
+ const char *value;
DBG("provider %p immutable %s", provider,
provider->immutable ? "yes" : "no");
@@ -1153,6 +1288,11 @@ static int vpn_provider_save(struct vpn_provider *provider)
g_key_file_set_string(keyfile, provider->identifier,
"VPN.Domain", provider->domain);
+ value = vpn_provider_get_string(provider, "AuthErrorLimit");
+ if (value)
+ g_key_file_set_string(keyfile, provider->identifier,
+ "AuthErrorLimit", value);
+
if (provider->user_networks) {
gchar **networks;
gsize network_count;
@@ -1269,6 +1409,9 @@ static void provider_destruct(struct vpn_provider *provider)
{
DBG("provider %p", provider);
+ if (provider->do_connect_timeout)
+ g_source_remove(provider->do_connect_timeout);
+
if (provider->notify_id != 0)
g_source_remove(provider->notify_id);
@@ -1658,6 +1801,18 @@ static void append_dns(DBusMessageIter *iter, void *user_data)
append_nameservers(iter, provider->nameservers);
}
+static time_t get_uptime(void)
+{
+ struct timespec t = { 0 };
+
+ if (clock_gettime(CLOCK_BOOTTIME, &t) == -1) {
+ connman_warn("clock_gettime() error %d, uptime failed", errno);
+ return 0;
+ }
+
+ return t.tv_sec;
+}
+
static int provider_indicate_state(struct vpn_provider *provider,
enum vpn_provider_state state)
{
@@ -1673,6 +1828,8 @@ static int provider_indicate_state(struct vpn_provider *provider,
provider->state = state;
if (state == VPN_PROVIDER_STATE_READY) {
+ provider->previous_connect_time = get_uptime();
+
connman_dbus_property_changed_basic(provider->path,
VPN_CONNECTION_INTERFACE, "Index",
DBUS_TYPE_INT32, &provider->index);
@@ -1885,8 +2042,10 @@ void vpn_provider_add_error(struct vpn_provider *provider,
{
switch (error) {
case VPN_PROVIDER_ERROR_UNKNOWN:
+ provider->previous_connect_time = 0;
break;
case VPN_PROVIDER_ERROR_CONNECT_FAILED:
+ provider->previous_connect_time = 0;
++provider->conn_error_counter;
break;
case VPN_PROVIDER_ERROR_LOGIN_FAILED:
@@ -1894,6 +2053,10 @@ void vpn_provider_add_error(struct vpn_provider *provider,
++provider->auth_error_counter;
break;
}
+
+ DBG("%p connect errors %d auth errors %d", provider,
+ provider->conn_error_counter,
+ provider->auth_error_counter);
}
int vpn_provider_indicate_error(struct vpn_provider *provider,
@@ -1902,6 +2065,21 @@ int vpn_provider_indicate_error(struct vpn_provider *provider,
DBG("provider %p id %s error %d", provider, provider->identifier,
error);
+ /*
+ * Ignore adding of errors when the VPN is idle or not set. Calls may
+ * happen in a case when networks are rapidly changed and the call to
+ * vpn_died() is done before executing the connect_cb() from the
+ * plugin. Then vpn.c:vpn_died() executes the plugin specific died()
+ * function which may free the plugin private data, containing also
+ * the callback which hasn't yet been called. As a result the provider
+ * might already been reset to idle state when the callback is executed
+ * resulting in unnecessary reset of the previous successful connect
+ * timer and adding of an error for already disconnected VPN.
+ */
+ if (provider->state == VPN_PROVIDER_STATE_IDLE ||
+ provider->state == VPN_PROVIDER_STATE_UNKNOWN)
+ return 0;
+
vpn_provider_set_state(provider, VPN_PROVIDER_STATE_FAILURE);
vpn_provider_add_error(provider, error);
@@ -2053,6 +2231,7 @@ static void provider_initialize(struct vpn_provider *provider)
g_free, free_route);
provider->setting_strings = g_hash_table_new_full(g_str_hash,
g_str_equal, g_free, free_setting);
+ provider->auth_error_limit = AUTH_ERROR_LIMIT_DEFAULT;
}
static struct vpn_provider *vpn_provider_new(void)
@@ -2788,6 +2967,21 @@ bool vpn_provider_get_string_immutable(struct vpn_provider *provider,
return setting->immutable;
}
+bool vpn_provider_setting_key_exists(struct vpn_provider *provider,
+ const char *key)
+{
+ return g_hash_table_contains(provider->setting_strings, key);
+}
+
+void vpn_provider_set_auth_error_limit(struct vpn_provider *provider,
+ unsigned int limit)
+{
+ if (!provider)
+ return;
+
+ provider->auth_error_limit = limit;
+}
+
bool __vpn_provider_check_routes(struct vpn_provider *provider)
{
if (!provider)
@@ -3100,9 +3294,70 @@ const char *vpn_provider_get_path(struct vpn_provider *provider)
return provider->path;
}
+/*
+ * This crude heuristic is meant to mitigate an issue with certain VPN
+ * providers that allow only one authentication per account at a time. These
+ * providers require the VPN client shuts down cleanly by sending an exit
+ * notification. In many cases this is not possible as the transport may
+ * already be gone and there is no route to the VPN server. In such case server
+ * may return authentication error to indicate that an other client is active
+ * and reserves the slot.
+ *
+ * By allowing the VPN client to try again with the following conditons the
+ * unnecessary credential resets done by VPN agent can be avoided. VPN client
+ * is allowed to retry if 1) there was a successful connection to the server
+ * within the specified CONNECT_OK_DIFF time and 2) the provider specific
+ * limit for auth errors is not reached the unnecessary credential resets in
+ * this case are avoided.
+ *
+ * This feature is controlled by the provider specific value for
+ * "AuthErrorLimit". Setting the value to 0 feature is disabled. User defined
+ * value is preferred if set, otherwise plugin default set with
+ * vpn_provider_set_auth_error_limit() is used, which defaults to
+ * AUTH_ERROR_LIMIT_DEFAULT.
+ */
+static bool ignore_authentication_errors(struct vpn_provider *provider)
+{
+ const char *val;
+ unsigned int limit;
+ time_t uptime;
+ time_t diff;
+
+ val = vpn_provider_get_string(provider, "AuthErrorLimit");
+ if (val)
+ limit = g_ascii_strtoull(val, NULL, 10);
+ else
+ limit = provider->auth_error_limit;
+
+ if (!limit || !provider->previous_connect_time) {
+ DBG("%p errors %u %s", provider, provider->auth_error_counter,
+ !limit ?
+ "disabled by 0 limit" :
+ "no previous ok conn");
+ return false;
+ }
+
+ uptime = get_uptime();
+ diff = uptime - provider->previous_connect_time;
+
+ DBG("%p errors %u limit %u uptime %jd time diff %jd", provider,
+ provider->auth_error_counter, limit,
+ (intmax_t)uptime, (intmax_t)diff);
+
+ if (diff <= CONNECT_OK_DIFF && provider->auth_error_counter <= limit) {
+ DBG("ignore auth errors");
+ return true;
+ }
+
+ return false;
+}
+
unsigned int vpn_provider_get_authentication_errors(
struct vpn_provider *provider)
{
+ if (ignore_authentication_errors(provider))
+ return 0;
+
return provider->auth_error_counter;
}
@@ -3248,6 +3503,215 @@ static void remove_unprovisioned_providers(void)
g_strfreev(providers);
}
+static gboolean connman_property_changed(DBusConnection *conn,
+ DBusMessage *message,
+ void *user_data)
+{
+ DBusMessageIter iter, value;
+ const char *key;
+ const char *signature = DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING;
+
+ if (!dbus_message_has_signature(message, signature)) {
+ connman_error("vpn connman property signature \"%s\" "
+ "does not match expected \"%s\"",
+ dbus_message_get_signature(message),
+ signature);
+ return TRUE;
+ }
+
+ if (!dbus_message_iter_init(message, &iter))
+ return TRUE;
+
+ dbus_message_iter_get_basic(&iter, &key);
+
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_recurse(&iter, &value);
+
+ DBG("key %s", key);
+
+ if (g_str_equal(key, "State")) {
+ const char *str;
+
+ if (dbus_message_iter_get_arg_type(&value) != DBUS_TYPE_STRING)
+ return TRUE;
+
+ dbus_message_iter_get_basic(&value, &str);
+ set_state(str);
+ }
+
+ return TRUE;
+}
+
+static void get_connman_state_reply(DBusPendingCall *call, void *user_data)
+{
+ DBusMessage *reply = NULL;
+ DBusError error;
+ DBusMessageIter iter, array, dict, value;
+
+ const char *signature = DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING
+ DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
+
+ const char *key;
+ const char *str;
+
+ DBG("");
+
+ if (!dbus_pending_call_get_completed(call))
+ goto done;
+
+ reply = dbus_pending_call_steal_reply(call);
+
+ dbus_error_init(&error);
+
+ if (dbus_set_error_from_message(&error, reply)) {
+ connman_error("%s", error.message);
+
+ /*
+ * In case of timeout re-add the state function to main
+ * event loop.
+ */
+ if (g_ascii_strcasecmp(error.name, DBUS_ERROR_TIMEOUT) == 0) {
+ DBG("D-Bus timeout, re-add get_connman_state()");
+ get_connman_state();
+ } else {
+ dbus_error_free(&error);
+ goto done;
+ }
+ }
+
+ if (!dbus_message_has_signature(reply, signature)) {
+ connman_error("vpnd signature \"%s\" does not match "
+ "expected \"%s\"",
+ dbus_message_get_signature(reply),
+ signature);
+
+ goto done;
+ }
+
+ if (!dbus_message_iter_init(reply, &array))
+ goto done;
+
+ dbus_message_iter_recurse(&array, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ dbus_message_iter_recurse(&dict, &iter);
+
+ dbus_message_iter_get_basic(&iter, &key);
+
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_recurse(&iter, &value);
+
+ if (g_ascii_strcasecmp(key, "State") == 0 &&
+ dbus_message_iter_get_arg_type(&value) ==
+ DBUS_TYPE_STRING) {
+ dbus_message_iter_get_basic(&value, &str);
+
+ DBG("Got initial state %s", str);
+
+ set_state(str);
+
+ /* No need to process further */
+ break;
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ state_query_completed = true;
+
+done:
+ if (reply)
+ dbus_message_unref(reply);
+
+ if (call)
+ dbus_pending_call_unref(call);
+}
+
+static gboolean run_get_connman_state(gpointer user_data)
+{
+ const char *path = "/";
+ const char *method = "GetProperties";
+ gboolean rval = FALSE;
+
+ DBusMessage *msg = NULL;
+ DBusPendingCall *call = NULL;
+
+ DBG("");
+
+ msg = dbus_message_new_method_call(CONNMAN_SERVICE, path,
+ CONNMAN_MANAGER_INTERFACE, method);
+ if (!msg)
+ goto out;
+
+ rval = g_dbus_send_message_with_reply(connection, msg, &call, -1);
+ if (!rval) {
+ connman_error("Cannot call %s on %s", method,
+ CONNMAN_MANAGER_INTERFACE);
+ goto out;
+ }
+
+ if (!call) {
+ connman_error("set pending call failed");
+ rval = FALSE;
+ goto out;
+ }
+
+ if (!dbus_pending_call_set_notify(call, get_connman_state_reply,
+ NULL, NULL)) {
+ connman_error("set notify to pending call failed");
+
+ if (call)
+ dbus_pending_call_unref(call);
+
+ rval = FALSE;
+ }
+
+out:
+ if (msg)
+ dbus_message_unref(msg);
+
+ /* In case sending was success, unset timeout function id */
+ if (rval) {
+ DBG("unsetting get_connman_state_timeout id");
+ get_connman_state_timeout = 0;
+ }
+
+ /* Return FALSE in case of success to remove from main event loop */
+ return !rval;
+}
+
+static void get_connman_state(void)
+{
+ if (get_connman_state_timeout)
+ return;
+
+ get_connman_state_timeout = g_timeout_add(STATE_INTERVAL_DEFAULT,
+ run_get_connman_state, NULL);
+}
+
+static void connman_service_watch_connected(DBusConnection *conn,
+ void *user_data)
+{
+ DBG("");
+
+ get_connman_state();
+}
+
+static void connman_service_watch_disconnected(DBusConnection *conn,
+ void *user_data)
+{
+ DBG("");
+
+ set_state(CONNMAN_STATE_IDLE);
+
+ /* Set state query variable to initial state */
+ state_query_completed = false;
+}
+
int __vpn_provider_init(void)
{
int err;
@@ -3267,6 +3731,20 @@ int __vpn_provider_init(void)
provider_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, unregister_provider);
+
+ connman_service_watch = g_dbus_add_service_watch(connection,
+ CONNMAN_SERVICE,
+ connman_service_watch_connected,
+ connman_service_watch_disconnected,
+ NULL, NULL);
+
+ connman_signal_watch = g_dbus_add_signal_watch(connection,
+ CONNMAN_SERVICE, NULL,
+ CONNMAN_MANAGER_INTERFACE,
+ PROPERTY_CHANGED,
+ connman_property_changed,
+ NULL, NULL);
+
return 0;
}
@@ -3281,5 +3759,13 @@ void __vpn_provider_cleanup(void)
g_hash_table_destroy(provider_hash);
provider_hash = NULL;
+ if (get_connman_state_timeout) {
+ if (!g_source_remove(get_connman_state_timeout))
+ connman_error("connman state timeout not removed");
+ }
+
+ g_dbus_remove_watch(connection, connman_service_watch);
+ g_dbus_remove_watch(connection, connman_signal_watch);
+
dbus_connection_unref(connection);
}
diff --git a/vpn/vpn-provider.h b/vpn/vpn-provider.h
index f7fa8591..5d1455da 100755
--- a/vpn/vpn-provider.h
+++ b/vpn/vpn-provider.h
@@ -88,6 +88,10 @@ int vpn_provider_set_boolean(struct vpn_provider *provider, const char *key,
bool force_change);
bool vpn_provider_get_boolean(struct vpn_provider *provider, const char *key,
bool default_value);
+bool vpn_provider_setting_key_exists(struct vpn_provider *provider,
+ const char *key);
+void vpn_provider_set_auth_error_limit(struct vpn_provider *provider,
+ unsigned int limit);
int vpn_provider_set_state(struct vpn_provider *provider,
enum vpn_provider_state state);
diff --git a/vpn/vpn-rtnl.c b/vpn/vpn-rtnl.c
index 295c05ce..5a02d779 100755
--- a/vpn/vpn-rtnl.c
+++ b/vpn/vpn-rtnl.c
@@ -797,75 +797,71 @@ static const char *type2string(uint16_t type)
static GIOChannel *channel = NULL;
-struct rtnl_request {
- struct nlmsghdr hdr;
- struct rtgenmsg msg;
-};
-#define RTNL_REQUEST_SIZE (sizeof(struct nlmsghdr) + sizeof(struct rtgenmsg))
+#define RTNL_REQUEST_SIZE (NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(struct rtgenmsg)))
static GSList *request_list = NULL;
static guint32 request_seq = 0;
-static struct rtnl_request *find_request(guint32 seq)
+static struct nlmsghdr *find_request(guint32 seq)
{
GSList *list;
for (list = request_list; list; list = list->next) {
- struct rtnl_request *req = list->data;
+ struct nlmsghdr *hdr = list->data;
- if (req->hdr.nlmsg_seq == seq)
- return req;
+ if (hdr->nlmsg_seq == seq)
+ return hdr;
}
return NULL;
}
-static int send_request(struct rtnl_request *req)
+static int send_request(struct nlmsghdr *hdr)
{
struct sockaddr_nl addr;
int sk;
debug("%s len %d type %d flags 0x%04x seq %d",
- type2string(req->hdr.nlmsg_type),
- req->hdr.nlmsg_len, req->hdr.nlmsg_type,
- req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
+ type2string(hdr->nlmsg_type),
+ hdr->nlmsg_len, hdr->nlmsg_type,
+ hdr->nlmsg_flags, hdr->nlmsg_seq);
sk = g_io_channel_unix_get_fd(channel);
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
- return sendto(sk, req, req->hdr.nlmsg_len, 0,
+ return sendto(sk, hdr, hdr->nlmsg_len, 0,
(struct sockaddr *) &addr, sizeof(addr));
}
-static int queue_request(struct rtnl_request *req)
+static int queue_request(struct nlmsghdr *hdr)
{
- request_list = g_slist_append(request_list, req);
+ request_list = g_slist_append(request_list, hdr);
if (g_slist_length(request_list) > 1)
return 0;
- return send_request(req);
+ return send_request(hdr);
}
static int process_response(guint32 seq)
{
- struct rtnl_request *req;
+ struct nlmsghdr *hdr;
debug("seq %d", seq);
- req = find_request(seq);
- if (req) {
- request_list = g_slist_remove(request_list, req);
- g_free(req);
+ hdr = find_request(seq);
+ if (hdr) {
+ request_list = g_slist_remove(request_list, hdr);
+ g_free(hdr);
}
- req = g_slist_nth_data(request_list, 0);
- if (!req)
+ hdr = g_slist_nth_data(request_list, 0);
+ if (!hdr)
return 0;
- return send_request(req);
+ return send_request(hdr);
}
static void rtnl_message(void *buf, size_t len)
@@ -960,62 +956,65 @@ static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data
static int send_getlink(void)
{
- struct rtnl_request *req;
+ struct nlmsghdr *hdr;
+ struct rtgenmsg *msg;
debug("");
- req = g_try_malloc0(RTNL_REQUEST_SIZE);
- if (!req)
- return -ENOMEM;
+ hdr = g_malloc0(RTNL_REQUEST_SIZE);
+
+ hdr->nlmsg_len = RTNL_REQUEST_SIZE;
+ hdr->nlmsg_type = RTM_GETLINK;
+ hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ hdr->nlmsg_pid = 0;
+ hdr->nlmsg_seq = request_seq++;
- req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
- req->hdr.nlmsg_type = RTM_GETLINK;
- req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
- req->hdr.nlmsg_pid = 0;
- req->hdr.nlmsg_seq = request_seq++;
- req->msg.rtgen_family = AF_INET;
+ msg = (struct rtgenmsg *) NLMSG_DATA(hdr);
+ msg->rtgen_family = AF_INET;
- return queue_request(req);
+ return queue_request(hdr);
}
static int send_getaddr(void)
{
- struct rtnl_request *req;
+ struct nlmsghdr *hdr;
+ struct rtgenmsg *msg;
debug("");
- req = g_try_malloc0(RTNL_REQUEST_SIZE);
- if (!req)
- return -ENOMEM;
+ hdr = g_malloc0(RTNL_REQUEST_SIZE);
- req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
- req->hdr.nlmsg_type = RTM_GETADDR;
- req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
- req->hdr.nlmsg_pid = 0;
- req->hdr.nlmsg_seq = request_seq++;
- req->msg.rtgen_family = AF_INET;
+ hdr->nlmsg_len = RTNL_REQUEST_SIZE;
+ hdr->nlmsg_type = RTM_GETADDR;
+ hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ hdr->nlmsg_pid = 0;
+ hdr->nlmsg_seq = request_seq++;
- return queue_request(req);
+ msg = (struct rtgenmsg *) NLMSG_DATA(hdr);
+ msg->rtgen_family = AF_INET;
+
+ return queue_request(hdr);
}
static int send_getroute(void)
{
- struct rtnl_request *req;
+ struct nlmsghdr *hdr;
+ struct rtgenmsg *msg;
debug("");
- req = g_try_malloc0(RTNL_REQUEST_SIZE);
- if (!req)
- return -ENOMEM;
+ hdr = g_malloc0(RTNL_REQUEST_SIZE);
+
+ hdr->nlmsg_len = RTNL_REQUEST_SIZE;
+ hdr->nlmsg_type = RTM_GETROUTE;
+ hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ hdr->nlmsg_pid = 0;
+ hdr->nlmsg_seq = request_seq++;
- req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
- req->hdr.nlmsg_type = RTM_GETROUTE;
- req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
- req->hdr.nlmsg_pid = 0;
- req->hdr.nlmsg_seq = request_seq++;
- req->msg.rtgen_family = AF_INET;
+ msg = (struct rtgenmsg *) NLMSG_DATA(hdr);
+ msg->rtgen_family = AF_INET;
- return queue_request(req);
+ return queue_request(hdr);
}
static gboolean update_timeout_cb(gpointer user_data)
@@ -1158,14 +1157,14 @@ void __vpn_rtnl_cleanup(void)
update_list = NULL;
for (list = request_list; list; list = list->next) {
- struct rtnl_request *req = list->data;
+ struct nlmsghdr *hdr = list->data;
debug("%s len %d type %d flags 0x%04x seq %d",
- type2string(req->hdr.nlmsg_type),
- req->hdr.nlmsg_len, req->hdr.nlmsg_type,
- req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
+ type2string(hdr->nlmsg_type),
+ hdr->nlmsg_len, hdr->nlmsg_type,
+ hdr->nlmsg_flags, hdr->nlmsg_seq);
- g_free(req);
+ g_free(hdr);
list->data = NULL;
}