summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorNishant Chaprana <n.chaprana@samsung.com>2019-09-17 19:00:55 +0530
committerNishant Chaprana <n.chaprana@samsung.com>2019-09-18 19:23:41 +0530
commit26cc90dfaf2ad149b702626f9552c81abbb26862 (patch)
tree2524c8994cf58358350fde67dfba5c3b8cb58f7d /plugins
parent9e3beb21876b6e63bd8acf53e751480d7a1cc16f (diff)
parent6b2381a2adabea7d8309ff158ef675ff88184305 (diff)
downloadconnman-submit/tizen/20190920.082459.tar.gz
connman-submit/tizen/20190920.082459.tar.bz2
connman-submit/tizen/20190920.082459.zip
Imported Upstream version 1.37submit/tizen/20190920.082459
Change-Id: Idb47c1ddbedc9f97181b8e9a5eeac04ddd832a2c Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
Diffstat (limited to 'plugins')
-rwxr-xr-xplugins/bluetooth.c1
-rw-r--r--plugins/ethernet.c4
-rwxr-xr-xplugins/gadget.c89
-rwxr-xr-xplugins/iospm.c2
-rw-r--r--plugins/iwd.c97
-rwxr-xr-xplugins/loopback.c73
-rwxr-xr-xplugins/nmcompat.c2
-rwxr-xr-xplugins/ofono.c5
-rwxr-xr-xplugins/pacrunner.c2
-rwxr-xr-xplugins/session_policy_local.c6
-rwxr-xr-xplugins/tist.c1
-rwxr-xr-xplugins/vpn.c233
-rw-r--r--plugins/wifi.c355
13 files changed, 538 insertions, 332 deletions
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index 76c15e59..9e19de08 100755
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -556,7 +556,6 @@ static void device_enable_cb(const DBusError *error, void *user_data)
#if !defined TIZEN_EXT
enable_device(device, path);
#endif
-
out:
g_free(path);
}
diff --git a/plugins/ethernet.c b/plugins/ethernet.c
index aadfe897..9e157467 100644
--- a/plugins/ethernet.c
+++ b/plugins/ethernet.c
@@ -27,6 +27,7 @@
#include <net/if.h>
#include <string.h>
#include <sys/ioctl.h>
+#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
@@ -190,11 +191,12 @@ static void add_network(struct connman_device *device,
if (connman_device_add_network(device, network) < 0) {
connman_network_unref(network);
+ g_free(ifname);
return;
}
if (!eth_tethering) {
- char group[16] = "cable";
+ char group[25] = "cable";
int vid, dsaport;
vid = get_vlan_vid(ifname);
diff --git a/plugins/gadget.c b/plugins/gadget.c
index cce51e26..1b44bbb5 100755
--- a/plugins/gadget.c
+++ b/plugins/gadget.c
@@ -25,8 +25,6 @@
#include <errno.h>
#include <net/if.h>
-#include <stdio.h>
-#include <string.h>
#ifndef IFF_LOWER_UP
#define IFF_LOWER_UP 0x10000
@@ -228,71 +226,6 @@ static struct connman_device_driver gadget_dev_driver = {
};
static GList *cdc_interface_list = NULL;
-static GHashTable *cdc_mac_hash = NULL;
-
-static void add_station(int index)
-{
- char *path, line[128] = {'\0'};
- char *ifname = connman_inet_ifname(index);
- char *mac;
- FILE *f;
-
- if (ifname == NULL)
- return;
-
- path = g_strdup_printf("/sys/class/usb_mode/%s/f_rndis/ethaddr",
- ifname);
-
- f = fopen(path, "re");
-
- g_free(ifname);
- g_free(path);
-
- if (f == NULL)
- return;
-
- if (fgets(line, sizeof(line), f) == NULL) {
- fclose(f);
- return;
- }
-
- fclose(f);
-
- mac = g_ascii_strdown(line, strlen(line) - 1);
- DBG("Add station %s in Technology %d", mac,
- CONNMAN_SERVICE_TYPE_GADGET);
-
- g_hash_table_insert(cdc_mac_hash, GINT_TO_POINTER(index),
- mac);
-
- connman_technology_tethering_add_station(CONNMAN_SERVICE_TYPE_GADGET,
- mac);
-}
-
-static void remove_station(int index)
-{
- char *mac;
- mac = g_hash_table_lookup(cdc_mac_hash, GINT_TO_POINTER(index));
- if (mac == NULL)
- return;
-
- connman_technology_tethering_remove_station(mac);
-
- g_hash_table_remove(cdc_mac_hash, GINT_TO_POINTER(index));
-}
-
-static gboolean remove_all_station(gpointer key, gpointer value, gpointer user_data)
-{
- char *mac;
- mac = value;
- if (mac == NULL)
- return TRUE;
-
- connman_technology_tethering_remove_station(mac);
-
- return TRUE;
-}
-
static void gadget_tech_add_interface(struct connman_technology *technology,
int index, const char *name, const char *ident)
@@ -313,8 +246,6 @@ static void gadget_tech_remove_interface(struct connman_technology *technology,
cdc_interface_list = g_list_remove(cdc_interface_list,
GINT_TO_POINTER((int) index));
-
- remove_station(index);
}
static void gadget_tech_enable_tethering(struct connman_technology *technology,
@@ -340,7 +271,7 @@ static void gadget_tech_enable_tethering(struct connman_technology *technology,
connman_inet_add_to_bridge(index, bridge);
- add_station(index);
+ gadget_tethering = true;
}
}
@@ -354,11 +285,11 @@ static void gadget_tech_disable_tethering(struct connman_technology *technology,
connman_inet_remove_from_bridge(index, bridge);
- remove_station(index);
-
connman_inet_ifdown(index);
connman_technology_tethering_notify(technology, false);
+
+ gadget_tethering = false;
}
}
@@ -378,28 +309,14 @@ static int gadget_tech_set_tethering(struct connman_technology *technology,
static int gadget_tech_probe(struct connman_technology *technology)
{
- DBG("tech probe %p", technology);
-
- cdc_mac_hash = g_hash_table_new_full(g_direct_hash,
- g_direct_equal, NULL, g_free);
-
return 0;
}
static void gadget_tech_remove(struct connman_technology *technology)
{
- DBG("tech remove %p", technology);
-
g_list_free(cdc_interface_list);
cdc_interface_list = NULL;
-
- if (cdc_mac_hash) {
- g_hash_table_foreach_remove(cdc_mac_hash, remove_all_station,
- NULL);
- g_hash_table_destroy(cdc_mac_hash);
- cdc_mac_hash = NULL;
- }
}
static struct connman_technology_driver gadget_tech_driver = {
diff --git a/plugins/iospm.c b/plugins/iospm.c
index fcb4cea1..cded9e00 100755
--- a/plugins/iospm.c
+++ b/plugins/iospm.c
@@ -86,7 +86,7 @@ static void iospm_offline_mode(bool enabled)
send_indication(IOSPM_FLIGHT_MODE, enabled);
}
-static struct connman_notifier iospm_notifier = {
+static const struct connman_notifier iospm_notifier = {
.name = "iospm",
.priority = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
.service_enabled= iospm_service_enabled,
diff --git a/plugins/iwd.c b/plugins/iwd.c
index b5191654..ddc9201d 100644
--- a/plugins/iwd.c
+++ b/plugins/iwd.c
@@ -55,14 +55,6 @@ static bool agent_registered;
#define IWD_AGENT_ERROR_INTERFACE "net.connman.iwd.Agent.Error"
#define AGENT_PATH "/net/connman/iwd_agent"
-enum iwd_device_state {
- IWD_DEVICE_STATE_UNKNOWN,
- IWD_DEVICE_STATE_CONNECTED,
- IWD_DEVICE_STATE_DISCONNECTED,
- IWD_DEVICE_STATE_CONNECTING,
- IWD_DEVICE_STATE_DISCONNECTING,
-};
-
struct iwd_adapter {
GDBusProxy *proxy;
char *path;
@@ -77,7 +69,6 @@ struct iwd_device {
char *adapter;
char *name;
char *address;
- enum iwd_device_state state;
bool powered;
bool scanning;
@@ -96,38 +87,6 @@ struct iwd_network {
struct connman_network *network;
};
-static enum iwd_device_state string2state(const char *str)
-{
- if (!strcmp(str, "connected"))
- return IWD_DEVICE_STATE_CONNECTED;
- else if (!strcmp(str, "disconnected"))
- return IWD_DEVICE_STATE_DISCONNECTED;
- else if (!strcmp(str, "connecting"))
- return IWD_DEVICE_STATE_CONNECTING;
- else if (!strcmp(str, "disconnecting"))
- return IWD_DEVICE_STATE_DISCONNECTING;
-
- return IWD_DEVICE_STATE_UNKNOWN;
-}
-
-static const char *state2string(enum iwd_device_state state)
-{
- switch (state) {
- case IWD_DEVICE_STATE_CONNECTED:
- return "connected";
- case IWD_DEVICE_STATE_DISCONNECTED:
- return "disconnected";
- case IWD_DEVICE_STATE_CONNECTING:
- return "connecting";
- case IWD_DEVICE_STATE_DISCONNECTING:
- return "disconnecting";
- default:
- break;
- }
-
- return "unknown";
-}
-
static const char *proxy_get_string(GDBusProxy *proxy, const char *property)
{
DBusMessageIter iter;
@@ -484,17 +443,53 @@ static void update_signal_strength(struct iwd_device *iwdd)
DBG("GetOrderedNetworks() failed");
}
+static const char *security_remap(const char *security)
+{
+ if (!g_strcmp0(security, "open"))
+ return "none";
+ else if (!g_strcmp0(security, "psk"))
+ return "psk";
+ else if (!g_strcmp0(security, "8021x"))
+ return "ieee8021x";
+
+ return "unknown";
+}
+
+static char *create_identifier(const char *path, const char *security)
+{
+ char *start, *end, *identifier;
+ char *_path = g_strdup(path);
+
+ /*
+ * _path is something like
+ * /0/4/5363686970686f6c5f427573696e6573735f454150_8021x
+ */
+ start = strrchr(_path, '/');
+ start++;
+ end = strchr(start, '_');
+ *end = '\0';
+
+ /*
+ * Create an ident which is identical to the corresponding
+ * wpa_supplicant identifier.
+ */
+ identifier = g_strdup_printf("%s_managed_%s", start,
+ security_remap(security));
+ g_free(_path);
+
+ return identifier;
+}
+
static void add_network(const char *path, struct iwd_network *iwdn)
{
struct iwd_device *iwdd;
- const char *identifier;
+ char *identifier;
iwdd = g_hash_table_lookup(devices, iwdn->device);
if (!iwdd)
return;
- identifier = strrchr(path, '/');
- identifier++; /* strip leading slash as well */
+ identifier = create_identifier(path, iwdn->type);
iwdn->network = connman_network_create(identifier,
CONNMAN_NETWORK_TYPE_WIFI);
connman_network_set_data(iwdn->network, iwdn);
@@ -504,6 +499,7 @@ static void add_network(const char *path, struct iwd_network *iwdn)
strlen(iwdn->name));
connman_network_set_string(iwdn->network, "WiFi.Security",
iwdn->type);
+ connman_network_set_string(iwdn->network, "WiFi.Mode", "managed");
if (connman_device_add_network(iwdd->device, iwdn->network) < 0) {
connman_network_unref(iwdn->network);
@@ -514,6 +510,8 @@ static void add_network(const char *path, struct iwd_network *iwdn)
connman_network_set_available(iwdn->network, true);
connman_network_set_group(iwdn->network, identifier);
+
+ g_free(identifier);
}
static void remove_network(struct iwd_network *iwdn)
@@ -625,13 +623,6 @@ static void device_property_change(GDBusProxy *proxy, const char *name,
iwdd->name = g_strdup(name);
DBG("%p name %s", path, iwdd->name);
- } else if (!strcmp(name, "State")) {
- const char *state;
-
- dbus_message_iter_get_basic(iter, &state);
- iwdd->state = string2state(state);
-
- DBG("%s state %s", path, state2string(iwdd->state));
} else if (!strcmp(name, "Powered")) {
dbus_bool_t powered;
@@ -790,13 +781,11 @@ static void create_device(GDBusProxy *proxy)
iwdd->adapter = g_strdup(proxy_get_string(proxy, "Adapter"));
iwdd->name = g_strdup(proxy_get_string(proxy, "Name"));
iwdd->address = g_strdup(proxy_get_string(proxy, "Address"));
- iwdd->state = string2state(proxy_get_string(proxy, "State"));
iwdd->powered = proxy_get_bool(proxy, "Powered");
iwdd->scanning = proxy_get_bool(proxy, "Scanning");
- DBG("adapter %s name %s address %s state %s powered %d scanning %d",
+ DBG("adapter %s name %s address %s powered %d scanning %d",
iwdd->adapter, iwdd->name, iwdd->address,
- state2string(iwdd->state),
iwdd->powered, iwdd->scanning);
g_dbus_proxy_set_property_watch(iwdd->proxy,
diff --git a/plugins/loopback.c b/plugins/loopback.c
index 44100c64..55c8a218 100755
--- a/plugins/loopback.c
+++ b/plugins/loopback.c
@@ -23,8 +23,6 @@
#include <config.h>
#endif
-#include <stdio.h>
-
#include <errno.h>
#include <unistd.h>
#include <limits.h>
@@ -34,11 +32,11 @@
#include <sys/socket.h>
#include <arpa/inet.h>
#include <net/if.h>
+#include <stdio.h>
#include <glib.h>
#include <glib/gprintf.h>
-
#define CONNMAN_API_SUBJECT_TO_CHANGE
#include <connman/plugin.h>
#include <connman/utsname.h>
@@ -67,46 +65,47 @@ static int setup_hostname(void)
memset(system_hostname, 0, sizeof(system_hostname));
#if defined TIZEN_EXT
- FILE *fp = NULL;
+ FILE *fp = NULL;
#define WIFI_MAC "/opt/etc/.mac.info"
- {
- char* rv = 0;
- gchar* dev_id = "TIZEN";
- char wifi_mac[HOST_NAME_MAX + 1];
-
- fp = fopen(WIFI_MAC, "r");
- if(!fp){
- connman_error("Failed to get current hostname");
- strncpy(system_hostname, dev_id, strlen(dev_id));
- goto host_name_end;
- }
-
- 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));
- fclose(fp);
- goto host_name_end;
- }
-
- dev_id = g_base64_encode((const guchar *)wifi_mac, strlen(wifi_mac));
- g_sprintf(system_hostname, "TIZEN-%s", dev_id);
- g_free(dev_id);
- fclose(fp);
+ {
+ char* rv = 0;
+ gchar* dev_id = "TIZEN";
+ char wifi_mac[HOST_NAME_MAX + 1];
+
+ fp = fopen(WIFI_MAC, "r");
+ if(!fp){
+ connman_error("Failed to get current hostname");
+ strncpy(system_hostname, dev_id, strlen(dev_id));
+ goto host_name_end;
}
- host_name_end :
-#else
- if (gethostname(system_hostname, HOST_NAME_MAX) < 0) {
+ rv = fgets(wifi_mac, HOST_NAME_MAX, fp);
+ if(!rv){
connman_error("Failed to get current hostname");
- return -EIO;
+ strncpy(system_hostname, dev_id, strlen(dev_id));
+ fclose(fp);
+ goto host_name_end;
}
+
+ dev_id = g_base64_encode((const guchar *)wifi_mac, strlen(wifi_mac));
+ g_sprintf(system_hostname, "TIZEN-%s", dev_id);
+ g_free(dev_id);
+ fclose(fp);
+ }
+
+host_name_end:
+#else
+ if (gethostname(system_hostname, HOST_NAME_MAX) < 0) {
+ connman_error("Failed to get current hostname");
+ return -EIO;
+ }
#endif
- if (strlen(system_hostname) > 0 &&
- strcmp(system_hostname, "(none)") != 0)
- connman_info("System hostname is %s", system_hostname);
- else
- create_hostname();
+
+ if (strlen(system_hostname) > 0 &&
+ strcmp(system_hostname, "(none)") != 0)
+ connman_info("System hostname is %s", system_hostname);
+ else
+ create_hostname();
memset(name, 0, sizeof(name));
diff --git a/plugins/nmcompat.c b/plugins/nmcompat.c
index 883ce9bd..274baab4 100755
--- a/plugins/nmcompat.c
+++ b/plugins/nmcompat.c
@@ -173,7 +173,7 @@ static void offline_mode(bool enabled)
current_service = NULL;
}
-static struct connman_notifier notifier = {
+static const struct connman_notifier notifier = {
.name = "nmcompat",
.priority = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
.default_changed = default_changed,
diff --git a/plugins/ofono.c b/plugins/ofono.c
index 78f8f196..82413b6e 100755
--- a/plugins/ofono.c
+++ b/plugins/ofono.c
@@ -1301,10 +1301,13 @@ static void remove_all_contexts(struct modem_data *modem)
if (modem->context_list == NULL)
return;
- for (list = modem->context_list; list; list = list->next) {
+ list = modem->context_list;
+ while (list) {
struct network_context *context = list->data;
remove_cm_context(modem, context);
+
+ list = modem->context_list;
}
g_slist_free(modem->context_list);
modem->context_list = NULL;
diff --git a/plugins/pacrunner.c b/plugins/pacrunner.c
index d2464a5e..9c652f3b 100755
--- a/plugins/pacrunner.c
+++ b/plugins/pacrunner.c
@@ -277,7 +277,7 @@ static void proxy_changed(struct connman_service *service)
create_proxy_configuration();
}
-static struct connman_notifier pacrunner_notifier = {
+static const struct connman_notifier pacrunner_notifier = {
.name = "pacrunner",
.default_changed = default_service_changed,
.proxy_changed = proxy_changed,
diff --git a/plugins/session_policy_local.c b/plugins/session_policy_local.c
index f003c0e1..9beb0980 100755
--- a/plugins/session_policy_local.c
+++ b/plugins/session_policy_local.c
@@ -271,10 +271,8 @@ static void get_uid_reply(unsigned int uid, void *user_data, int err)
DBG("session %p uid %d", policy->session, uid);
- if (err < 0) {
- cleanup_config(policy);
+ if (err < 0)
goto err;
- }
pwd = getpwuid((uid_t)uid);
if (!pwd) {
@@ -333,7 +331,7 @@ static void get_uid_reply(unsigned int uid, void *user_data, int err)
return;
err:
- failed_create(NULL, cb, cbd->user_data, err);
+ failed_create(policy, cb, cbd->user_data, err);
g_free(cbd);
g_free(groups);
}
diff --git a/plugins/tist.c b/plugins/tist.c
index ad5ef79e..cc2800a1 100755
--- a/plugins/tist.c
+++ b/plugins/tist.c
@@ -23,7 +23,6 @@
#include <config.h>
#endif
-#define _GNU_SOURCE
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
diff --git a/plugins/vpn.c b/plugins/vpn.c
index d3d75b81..11bab154 100755
--- a/plugins/vpn.c
+++ b/plugins/vpn.c
@@ -38,6 +38,7 @@
#include <connman/dbus.h>
#include <connman/provider.h>
#include <connman/ipaddress.h>
+#include <connman/notifier.h>
#include <connman/vpn-dbus.h>
#include <connman/inet.h>
#include <gweb/gresolv.h>
@@ -71,8 +72,10 @@ struct connection_data {
struct connman_provider *provider;
int index;
DBusPendingCall *call;
+ DBusPendingCall *disconnect_call;
bool connect_pending;
struct config_create_data *cb_data;
+ char *service_ident;
char *state;
char *type;
@@ -249,6 +252,12 @@ static void free_config_cb_data(struct config_create_data *cb_data)
g_free(cb_data);
}
+static bool provider_is_connected(struct connection_data *data)
+{
+ return data && (g_str_equal(data->state, "ready") ||
+ g_str_equal(data->state, "configuration"));
+}
+
static void set_provider_state(struct connection_data *data)
{
enum connman_provider_state state = CONNMAN_PROVIDER_STATE_UNKNOWN;
@@ -256,6 +265,11 @@ static void set_provider_state(struct connection_data *data)
DBG("provider %p new state %s", data->provider, data->state);
+ if (!provider_is_connected(data)) {
+ g_free(data->service_ident);
+ data->service_ident = NULL;
+ }
+
if (g_str_equal(data->state, "ready")) {
state = CONNMAN_PROVIDER_STATE_READY;
goto set;
@@ -484,19 +498,19 @@ static void connect_reply(DBusPendingCall *call, void *user_data)
if (dbus_set_error_from_message(&error, reply)) {
int err = errorstr2val(error.name);
+
if (err != -EINPROGRESS) {
connman_error("Connect reply: %s (%s)", error.message,
error.name);
- dbus_error_free(&error);
-
DBG("data %p cb_data %p", data, cb_data);
+
if (cb_data) {
cb_data->callback(cb_data->message, err, NULL);
free_config_cb_data(cb_data);
data->cb_data = NULL;
}
- goto done;
}
+
dbus_error_free(&error);
}
@@ -506,7 +520,6 @@ static void connect_reply(DBusPendingCall *call, void *user_data)
* state.
*/
-done:
dbus_message_unref(reply);
dbus_pending_call_unref(call);
@@ -518,24 +531,31 @@ static int connect_provider(struct connection_data *data, void *user_data,
DBusPendingCall *call;
DBusMessage *message;
struct config_create_data *cb_data = user_data;
+ struct connman_service *transport = connman_service_get_default();
DBG("data %p user %p path %s sender %s", data, cb_data, data->path,
dbus_sender);
- data->connect_pending = false;
+ if (!transport) {
+ DBG("no default service, refusing to connect");
+ return -EINVAL;
+ }
-#define VPN_CONNECT2 "Connect2"
+ data->connect_pending = false;
/* We need to pass original dbus sender to connman-vpnd,
- * use a Connect2 method for that.
+ * use a Connect2 method for that if the original dbus sender is set.
+ * Connect method requires no parameter, Connect2 requires dbus sender
+ * name to be set.
*/
message = dbus_message_new_method_call(VPN_SERVICE, data->path,
VPN_CONNECTION_INTERFACE,
- VPN_CONNECT2);
+ dbus_sender && *dbus_sender ?
+ VPN_CONNECT2 : VPN_CONNECT);
if (!message)
return -ENOMEM;
- if (dbus_sender)
+ if (dbus_sender && *dbus_sender)
dbus_message_append_args(message, DBUS_TYPE_STRING,
&dbus_sender, NULL);
else
@@ -544,7 +564,8 @@ static int connect_provider(struct connection_data *data, void *user_data,
if (!dbus_connection_send_with_reply(connection, message,
&call, DBUS_TIMEOUT)) {
connman_error("Unable to call %s.%s()",
- VPN_CONNECTION_INTERFACE, VPN_CONNECT2);
+ VPN_CONNECTION_INTERFACE, dbus_sender && *dbus_sender ?
+ VPN_CONNECT2 : VPN_CONNECT);
dbus_message_unref(message);
return -EINVAL;
}
@@ -559,6 +580,15 @@ static int connect_provider(struct connection_data *data, void *user_data,
cb_data->path = g_strdup(data->path);
}
+ /*
+ * This is the service which (most likely) will be used
+ * as a transport for VPN connection.
+ */
+ g_free(data->service_ident);
+ data->service_ident =
+ g_strdup(connman_service_get_identifier(transport));
+ DBG("transport %s", data->service_ident);
+
dbus_pending_call_set_notify(call, connect_reply, data, NULL);
dbus_message_unref(message);
@@ -891,12 +921,10 @@ static int provider_connect(struct connman_provider *provider,
static void disconnect_reply(DBusPendingCall *call, void *user_data)
{
+ struct connection_data *data = user_data;
DBusMessage *reply;
DBusError error;
- if (!dbus_pending_call_get_completed(call))
- return;
-
DBG("user %p", user_data);
reply = dbus_pending_call_steal_reply(call);
@@ -911,50 +939,47 @@ static void disconnect_reply(DBusPendingCall *call, void *user_data)
done:
dbus_message_unref(reply);
-
dbus_pending_call_unref(call);
+ data->disconnect_call = NULL;
}
static int disconnect_provider(struct connection_data *data)
{
- DBusPendingCall *call;
+ bool sent;
DBusMessage *message;
DBG("data %p path %s", data, data->path);
+ if (data->disconnect_call) {
+ DBG("already disconnecting");
+ return -EINVAL;
+ }
+
message = dbus_message_new_method_call(VPN_SERVICE, data->path,
VPN_CONNECTION_INTERFACE,
VPN_DISCONNECT);
if (!message)
return -ENOMEM;
- if (!dbus_connection_send_with_reply(connection, message,
- &call, DBUS_TIMEOUT)) {
+ sent = dbus_connection_send_with_reply(connection, message,
+ &data->disconnect_call, DBUS_TIMEOUT);
+ dbus_message_unref(message);
+
+ if (!sent || !data->disconnect_call) {
connman_error("Unable to call %s.%s()",
VPN_CONNECTION_INTERFACE, VPN_DISCONNECT);
- dbus_message_unref(message);
return -EINVAL;
}
- if (!call) {
- dbus_message_unref(message);
- return -EINVAL;
- }
-
- dbus_pending_call_set_notify(call, disconnect_reply, NULL, NULL);
+ dbus_pending_call_set_notify(data->disconnect_call, disconnect_reply,
+ data, NULL);
- dbus_message_unref(message);
+ g_free(data->service_ident);
+ data->service_ident = NULL;
connman_provider_set_state(data->provider,
CONNMAN_PROVIDER_STATE_DISCONNECT);
- /*
- * We return 0 here instead of -EINPROGRESS because
- * __connman_service_disconnect() needs to return something
- * to gdbus so that gdbus will not call Disconnect() more
- * than once. This way we do not need to pass the dbus reply
- * message around the code.
- */
- return 0;
+ return -EINPROGRESS;
}
static int provider_disconnect(struct connman_provider *provider)
@@ -967,8 +992,7 @@ static int provider_disconnect(struct connman_provider *provider)
if (!data)
return -EINVAL;
- if (g_str_equal(data->state, "ready") ||
- g_str_equal(data->state, "configuration"))
+ if (provider_is_connected(data))
return disconnect_provider(data);
return 0;
@@ -1476,17 +1500,11 @@ static void destroy_provider(struct connection_data *data)
{
DBG("data %p", data);
- if (g_str_equal(data->state, "ready") ||
- g_str_equal(data->state, "configuration"))
+ if (provider_is_connected(data))
connman_provider_disconnect(data->provider);
- if (data->call)
- dbus_pending_call_cancel(data->call);
-
connman_provider_set_data(data->provider, NULL);
-
connman_provider_remove(data->provider);
-
data->provider = NULL;
}
@@ -1499,13 +1517,24 @@ static void connection_destroy(gpointer hash_data)
if (data->provider)
destroy_provider(data);
+ if (data->call) {
+ dbus_pending_call_cancel(data->call);
+ dbus_pending_call_unref(data->call);
+ }
+
+ if (data->disconnect_call) {
+ dbus_pending_call_cancel(data->disconnect_call);
+ dbus_pending_call_unref(data->disconnect_call);
+ }
+
+ g_free(data->service_ident);
g_free(data->path);
g_free(data->ident);
g_free(data->state);
g_free(data->type);
g_free(data->name);
g_free(data->host);
- g_free(data->host_ip);
+ g_strfreev(data->host_ip);
g_free(data->domain);
g_hash_table_destroy(data->server_routes);
g_hash_table_destroy(data->user_routes);
@@ -1726,7 +1755,7 @@ static gboolean property_changed(DBusConnection *conn,
struct connection_data *data = NULL;
DBusMessageIter iter, value;
bool ip_set = false;
- int err = 0;
+ int err;
char *str;
const char *key;
const char *signature = DBUS_TYPE_STRING_AS_STRING
@@ -1813,6 +1842,120 @@ static gboolean property_changed(DBusConnection *conn,
return TRUE;
}
+static int vpn_find_online_transport_cb(struct connman_service *service,
+ void *user_data)
+{
+ if (connman_service_get_type(service) != CONNMAN_SERVICE_TYPE_VPN) {
+ switch (connman_service_get_state(service)) {
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ *((struct connman_service**)user_data) = service;
+ return 1;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static struct connman_service *vpn_find_online_transport()
+{
+ struct connman_service *service = NULL;
+
+ connman_service_iterate_services(vpn_find_online_transport_cb,
+ &service);
+ return service;
+}
+
+static bool vpn_is_valid_transport(struct connman_service *transport)
+{
+ if (transport) {
+ struct connman_service *online;
+
+ switch (connman_service_get_state(transport)) {
+ case CONNMAN_SERVICE_STATE_READY:
+ online = vpn_find_online_transport();
+
+ /* Stay connected if there are no online services */
+ if (!online)
+ return true;
+
+ DBG("%s is ready, %s is online, disconnecting",
+ connman_service_get_identifier(transport),
+ connman_service_get_identifier(online));
+ break;
+
+ case CONNMAN_SERVICE_STATE_ONLINE:
+ online = vpn_find_online_transport();
+
+ /* Check if our transport is still the default */
+ if (online == transport)
+ return true;
+
+ DBG("%s is replaced by %s as default, disconnecting",
+ connman_service_get_identifier(transport),
+ connman_service_get_identifier(online));
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ DBG("transport gone");
+ }
+
+ return false;
+}
+
+static void vpn_disconnect_check_provider(struct connection_data *data)
+{
+ if (data->service_ident && provider_is_connected(data)) {
+ struct connman_service *service =
+ connman_service_lookup_from_identifier
+ (data->service_ident);
+
+ if (!vpn_is_valid_transport(service)) {
+ disconnect_provider(data);
+ }
+ }
+}
+
+static void vpn_disconnect_check()
+{
+ GHashTableIter iter;
+ gpointer value;
+
+ DBG("");
+ g_hash_table_iter_init(&iter, vpn_connections);
+ while (g_hash_table_iter_next(&iter, NULL, &value))
+ vpn_disconnect_check_provider(value);
+}
+
+static void vpn_service_add(struct connman_service *service, const char *name)
+{
+ vpn_disconnect_check();
+}
+
+static void vpn_service_list_changed(struct connman_service *service)
+{
+ vpn_disconnect_check();
+}
+
+static void vpn_service_state_changed(struct connman_service *service,
+ enum connman_service_state state)
+{
+ vpn_disconnect_check();
+}
+
+static const struct connman_notifier vpn_notifier = {
+ .name = "vpn",
+ .priority = CONNMAN_NOTIFIER_PRIORITY_DEFAULT,
+ .default_changed = vpn_service_list_changed,
+ .service_add = vpn_service_add,
+ .service_remove = vpn_service_list_changed,
+ .service_state_changed = vpn_service_state_changed
+};
+
static int vpn_init(void)
{
int err;
@@ -1853,6 +1996,7 @@ static int vpn_init(void)
vpnd_created(connection, &provider_driver);
}
+ connman_notifier_register(&vpn_notifier);
return err;
remove:
@@ -1873,6 +2017,7 @@ static void vpn_exit(void)
g_dbus_remove_watch(connection, removed_watch);
g_dbus_remove_watch(connection, property_watch);
+ connman_notifier_unregister(&vpn_notifier);
connman_provider_driver_unregister(&provider_driver);
if (vpn_connections)
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 8da1da56..f4e6d59f 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -30,9 +30,8 @@
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
-#include <linux/if_arp.h>
-#include <linux/wireless.h>
#include <net/ethernet.h>
+#include <linux/wireless.h>
#ifndef IFF_LOWER_UP
#define IFF_LOWER_UP 0x10000
@@ -56,6 +55,7 @@
#include <connman/provision.h>
#include <connman/utsname.h>
#include <connman/machine.h>
+#include <connman/tethering.h>
#include <gsupplicant/gsupplicant.h>
@@ -64,7 +64,8 @@
#define FAVORITE_MAXIMUM_RETRIES 2
#define BGSCAN_DEFAULT "simple:30:-45:300"
-#define AUTOSCAN_DEFAULT "exponential:3:300"
+#define AUTOSCAN_EXPONENTIAL "exponential:3:300"
+#define AUTOSCAN_SINGLE "single:3"
#define P2P_FIND_TIMEOUT 30
#define P2P_CONNECTION_TIMEOUT 100
@@ -91,6 +92,12 @@ enum wifi_ap_capability{
WIFI_AP_NOT_SUPPORTED = 2,
};
+enum wifi_scanning_type {
+ WIFI_SCANNING_UNKNOWN = 0,
+ WIFI_SCANNING_PASSIVE = 1,
+ WIFI_SCANNING_ACTIVE = 2,
+};
+
struct hidden_params {
char ssid[32];
unsigned int ssid_len;
@@ -151,7 +158,7 @@ struct wifi_data {
* autoscan "emulation".
*/
struct autoscan_params *autoscan;
-
+ enum wifi_scanning_type scanning_type;
GSupplicantScanParams *scan_params;
unsigned int p2p_find_timeout;
unsigned int p2p_connection_timeout;
@@ -193,10 +200,9 @@ static GList *iface_list = NULL;
static GList *pending_wifi_device = NULL;
static GList *p2p_iface_list = NULL;
-bool wfd_service_registered = false;
+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);
@@ -1252,10 +1258,8 @@ static int peer_register_service(const unsigned char *specification,
params = fill_in_peer_service_params(specification,
specification_length, query,
query_length, version);
- if (!params) {
- ret = -ENOMEM;
+ if (!params)
continue;
- }
if (!found) {
ret_f = g_supplicant_interface_p2p_add_service(iface,
@@ -1340,10 +1344,8 @@ static int peer_unregister_service(const unsigned char *specification,
params = fill_in_peer_service_params(specification,
specification_length, query,
query_length, version);
- if (!params) {
- ret = -ENOMEM;
+ if (!params)
continue;
- }
ret = g_supplicant_interface_p2p_del_service(iface, params);
if (ret != 0 && ret != -EINPROGRESS)
@@ -1487,13 +1489,13 @@ static void reset_autoscan(struct connman_device *device)
autoscan = wifi->autoscan;
- if (autoscan->timeout == 0 && autoscan->interval == 0)
+ autoscan->interval = 0;
+
+ if (autoscan->timeout == 0)
return;
g_source_remove(autoscan->timeout);
-
autoscan->timeout = 0;
- autoscan->interval = 0;
connman_device_unref(device);
}
@@ -1581,7 +1583,7 @@ static void wifi_remove(struct connman_device *device)
remove_pending_wifi_device(wifi);
- if (wifi->p2p_find_timeout) {
+ if (connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_P2P)) {
g_source_remove(wifi->p2p_find_timeout);
connman_device_unref(wifi->device);
}
@@ -1745,7 +1747,11 @@ static int get_hidden_connections(GSupplicantScanParams *scan_data)
{
struct connman_config_entry **entries;
GKeyFile *keyfile;
+#if defined TIZEN_EXT
+ gchar **services = NULL;
+#else
gchar **services;
+#endif /* defined TIZEN_EXT */
char *ssid, *name;
int i, ret;
bool value;
@@ -2002,10 +2008,12 @@ static int throw_wifi_scan(struct connman_device *device,
if (wifi->tethering)
return -EBUSY;
+
#if defined TIZEN_EXT
- if (connman_device_get_scanning(device) && !wifi->allow_full_scan)
+ if (connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_WIFI)
+ && !wifi->allow_full_scan)
#else
- if (connman_device_get_scanning(device))
+ if (connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_WIFI))
#endif
return -EALREADY;
@@ -2145,10 +2153,12 @@ static void scan_callback(int result, GSupplicantInterface *interface,
}
#endif
- scanning = connman_device_get_scanning(device);
- if (scanning)
+ scanning = connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_WIFI);
+
+ if (scanning) {
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_WIFI, false);
+ }
if (result != -ENOLINK)
#if defined TIZEN_EXT
@@ -2214,7 +2224,6 @@ static void scan_callback_hidden(int result,
scan_callback_hidden,
#endif
device);
-
if (ret == 0)
return;
}
@@ -2252,6 +2261,21 @@ static gboolean autoscan_timeout(gpointer data)
throw_wifi_scan(wifi->device, scan_callback_hidden);
+ /*
+ * In case BackgroundScanning is disabled, interval will reach the
+ * limit exactly after the very first passive scanning. It allows
+ * to ensure at most one passive scan is performed in such cases.
+ */
+ if (!connman_setting_get_bool("BackgroundScanning") &&
+ interval == autoscan->limit) {
+ g_source_remove(autoscan->timeout);
+ autoscan->timeout = 0;
+
+ connman_device_unref(device);
+
+ return FALSE;
+ }
+
set_interval:
DBG("interval %d", interval);
@@ -2298,19 +2322,25 @@ static struct autoscan_params *parse_autoscan_params(const char *params)
int limit;
int base;
- DBG("Emulating autoscan");
+ DBG("");
list_params = g_strsplit(params, ":", 0);
if (list_params == 0)
return NULL;
- if (g_strv_length(list_params) < 3) {
+ if (!g_strcmp0(list_params[0], "exponential") &&
+ g_strv_length(list_params) == 3) {
+ base = atoi(list_params[1]);
+ limit = atoi(list_params[2]);
+ } else if (!g_strcmp0(list_params[0], "single") &&
+ g_strv_length(list_params) == 2)
+ base = limit = atoi(list_params[1]);
+ else {
g_strfreev(list_params);
return NULL;
}
- base = atoi(list_params[1]);
- limit = atoi(list_params[2]);
+ DBG("Setup %s autoscanning", list_params[0]);
g_strfreev(list_params);
@@ -2329,10 +2359,37 @@ static struct autoscan_params *parse_autoscan_params(const char *params)
static void setup_autoscan(struct wifi_data *wifi)
{
- if (!wifi->autoscan)
- wifi->autoscan = parse_autoscan_params(AUTOSCAN_DEFAULT);
+ /*
+ * If BackgroundScanning is enabled, setup exponential
+ * autoscanning if it has not been previously done.
+ */
+ if (connman_setting_get_bool("BackgroundScanning")) {
+ wifi->autoscan = parse_autoscan_params(AUTOSCAN_EXPONENTIAL);
+ return;
+ }
- start_autoscan(wifi->device);
+ /*
+ * On the contrary, if BackgroundScanning is disabled, update autoscan
+ * parameters based on the type of scanning that is being performed.
+ */
+ if (wifi->autoscan) {
+ g_free(wifi->autoscan);
+ wifi->autoscan = NULL;
+ }
+
+ switch (wifi->scanning_type) {
+ case WIFI_SCANNING_PASSIVE:
+ /* Do not setup autoscan. */
+ break;
+ case WIFI_SCANNING_ACTIVE:
+ /* Setup one single passive scan after active. */
+ wifi->autoscan = parse_autoscan_params(AUTOSCAN_SINGLE);
+ break;
+ case WIFI_SCANNING_UNKNOWN:
+ /* Setup autoscan in this case but we should never fall here. */
+ wifi->autoscan = parse_autoscan_params(AUTOSCAN_SINGLE);
+ break;
+ }
}
static void finalize_interface_creation(struct wifi_data *wifi)
@@ -2346,13 +2403,13 @@ static void finalize_interface_creation(struct wifi_data *wifi)
connman_device_set_powered(wifi->device, true);
- if (!connman_setting_get_bool("BackgroundScanning"))
- return;
-
if (wifi->p2p_device)
return;
- setup_autoscan(wifi);
+ if (!wifi->autoscan)
+ setup_autoscan(wifi);
+
+ start_autoscan(wifi->device);
}
static void interface_create_callback(int result,
@@ -2424,7 +2481,7 @@ static int wifi_disable(struct connman_device *device)
stop_autoscan(device);
- if (wifi->p2p_find_timeout) {
+ if (connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_P2P)) {
g_source_remove(wifi->p2p_find_timeout);
wifi->p2p_find_timeout = 0;
connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_P2P, false);
@@ -2439,7 +2496,7 @@ static int wifi_disable(struct connman_device *device)
#endif
/* In case of a user scan, device is still referenced */
- if (connman_device_get_scanning(device)) {
+ if (connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_WIFI)) {
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_WIFI, false);
connman_device_unref(wifi->device);
@@ -2567,10 +2624,29 @@ static int get_latest_connections(int max_ssids,
return num_ssids;
}
+static void wifi_update_scanner_type(struct wifi_data *wifi,
+ enum wifi_scanning_type new_type)
+{
+ DBG("");
+
+ if (!wifi || wifi->scanning_type == new_type)
+ return;
+
+ wifi->scanning_type = new_type;
+
+ setup_autoscan(wifi);
+}
+
static int wifi_scan_simple(struct connman_device *device)
{
+ struct wifi_data *wifi = connman_device_get_data(device);
+
reset_autoscan(device);
+ /* Distinguish between devices performing passive and active scanning */
+ if (wifi)
+ wifi_update_scanner_type(wifi, WIFI_SCANNING_PASSIVE);
+
return throw_wifi_scan(device, scan_callback_hidden);
}
@@ -2590,7 +2666,7 @@ static gboolean p2p_find_stop(gpointer data)
connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_P2P, false);
connman_device_unref(device);
- reset_autoscan(device);
+ start_autoscan(device);
return FALSE;
}
@@ -2670,7 +2746,8 @@ static void specific_scan_callback(int result, GSupplicantInterface *interface,
wifi->scan_params = NULL;
}
- scanning = connman_device_get_scanning(device);
+ scanning = connman_device_get_scanning(device,
+ CONNMAN_SERVICE_TYPE_WIFI);
if (scanning) {
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_WIFI, false);
@@ -2704,7 +2781,9 @@ static int wifi_specific_scan(enum connman_service_type type,
if (wifi->tethering)
return 0;
- scanning = connman_device_get_scanning(device);
+ scanning =
+ connman_device_get_scanning(device,
+ CONNMAN_SERVICE_TYPE_WIFI);
if (scanning)
return -EALREADY;
@@ -2841,7 +2920,8 @@ static void mesh_scan_callback(int result, GSupplicantInterface *interface,
DBG("result %d wifi %p", result, wifi);
- scanning = connman_device_get_scanning(device);
+ scanning = connman_device_get_scanning(device,
+ CONNMAN_SERVICE_TYPE_MESH);
if (scanning)
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_MESH, false);
@@ -2905,7 +2985,8 @@ static int mesh_abort_scan(enum connman_service_type type,
mesh_info = wifi->mesh_info;
- scanning = connman_device_get_scanning(device);
+ scanning = connman_device_get_scanning(device,
+ CONNMAN_SERVICE_TYPE_MESH);
if (!scanning)
return -EEXIST;
@@ -2937,7 +3018,8 @@ static int mesh_specific_scan(enum connman_service_type type,
mesh_info = wifi->mesh_info;
- scanning = connman_device_get_scanning(device);
+ scanning = connman_device_get_scanning(device,
+ CONNMAN_SERVICE_TYPE_MESH);
if (scanning)
return -EALREADY;
@@ -2988,11 +3070,8 @@ static int mesh_specific_scan(enum connman_service_type type,
* Note that the hidden scan is only used when connecting to this specific
* hidden AP first time. It is not used when system autoconnects to hidden AP.
*/
-static int wifi_scan(enum connman_service_type type,
- struct connman_device *device,
- const char *ssid, unsigned int ssid_len,
- const char *identity, const char* passphrase,
- const char *security, void *user_data)
+static int wifi_scan(struct connman_device *device,
+ struct connman_device_scan_params *params)
{
struct wifi_data *wifi = connman_device_get_data(device);
GSupplicantScanParams *scan_params = NULL;
@@ -3012,19 +3091,20 @@ static int wifi_scan(enum connman_service_type type,
if (wifi->tethering)
return -EBUSY;
- if (type == CONNMAN_SERVICE_TYPE_P2P)
+ if (params->type == CONNMAN_SERVICE_TYPE_P2P)
return p2p_find(device);
#if defined TIZEN_EXT_WIFI_MESH
- if (type == CONNMAN_SERVICE_TYPE_MESH)
+ if (params->type == CONNMAN_SERVICE_TYPE_MESH)
return mesh_scan(device);
#endif
- DBG("device %p wifi %p hidden ssid %s", device, wifi->interface, ssid);
+ DBG("device %p wifi %p hidden ssid %s", device, wifi->interface,
+ params->ssid);
- scanning = connman_device_get_scanning(device);
+ scanning = connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_WIFI);
- if (!ssid || ssid_len == 0 || ssid_len > 32) {
+ if (!params->ssid || params->ssid_len == 0 || params->ssid_len > 32) {
if (scanning)
return -EALREADY;
@@ -3053,8 +3133,8 @@ static int wifi_scan(enum connman_service_type type,
return -ENOMEM;
}
- memcpy(scan_ssid->ssid, ssid, ssid_len);
- scan_ssid->ssid_len = ssid_len;
+ memcpy(scan_ssid->ssid, params->ssid, params->ssid_len);
+ scan_ssid->ssid_len = params->ssid_len;
scan_params->ssids = g_slist_prepend(scan_params->ssids,
scan_ssid);
scan_params->num_ssids = 1;
@@ -3070,12 +3150,12 @@ static int wifi_scan(enum connman_service_type type,
wifi->hidden = NULL;
}
- memcpy(hidden->ssid, ssid, ssid_len);
- hidden->ssid_len = ssid_len;
- hidden->identity = g_strdup(identity);
- hidden->passphrase = g_strdup(passphrase);
- hidden->security = g_strdup(security);
- hidden->user_data = user_data;
+ memcpy(hidden->ssid, params->ssid, params->ssid_len);
+ hidden->ssid_len = params->ssid_len;
+ hidden->identity = g_strdup(params->identity);
+ hidden->passphrase = g_strdup(params->passphrase);
+ hidden->security = g_strdup(params->security);
+ hidden->user_data = params->user_data;
wifi->hidden = hidden;
if (scanning) {
@@ -3089,7 +3169,7 @@ static int wifi_scan(enum connman_service_type type,
} else if (wifi->connected) {
g_supplicant_free_scan_params(scan_params);
return wifi_scan_simple(device);
- } else {
+ } else if (!params->force_full_scan) {
ret = get_latest_connections(driver_max_ssids, scan_params);
if (ret <= 0) {
g_supplicant_free_scan_params(scan_params);
@@ -3097,13 +3177,15 @@ static int wifi_scan(enum connman_service_type type,
}
}
+ /* Distinguish between devices performing passive and active scanning */
+ wifi_update_scanner_type(wifi, WIFI_SCANNING_ACTIVE);
+
connman_device_ref(device);
reset_autoscan(device);
ret = g_supplicant_interface_scan(wifi->interface, scan_params,
scan_callback, device);
-
if (ret == 0) {
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_WIFI, true);
@@ -3128,6 +3210,24 @@ static int wifi_scan(enum connman_service_type type,
return ret;
}
+static void wifi_stop_scan(enum connman_service_type type,
+ struct connman_device *device)
+{
+ struct wifi_data *wifi = connman_device_get_data(device);
+
+ DBG("device %p wifi %p", device, wifi);
+
+ if (!wifi)
+ return;
+
+ if (type == CONNMAN_SERVICE_TYPE_P2P) {
+ if (connman_device_get_scanning(device, CONNMAN_SERVICE_TYPE_P2P)) {
+ g_source_remove(wifi->p2p_find_timeout);
+ p2p_find_stop(device);
+ }
+ }
+}
+
static void wifi_regdom_callback(int result,
const char *alpha2,
void *user_data)
@@ -3167,6 +3267,7 @@ static struct connman_device_driver wifi_ng_driver = {
.enable = wifi_enable,
.disable = wifi_disable,
.scan = wifi_scan,
+ .stop_scan = wifi_stop_scan,
.set_regdom = wifi_set_regdom,
#if defined TIZEN_EXT
.specific_scan = wifi_specific_scan,
@@ -3336,6 +3437,7 @@ static void ssid_init(GSupplicantSSID *ssid, struct connman_network *network)
#endif
ssid->passphrase = connman_network_get_string(network,
"WiFi.Passphrase");
+
ssid->eap = connman_network_get_string(network, "WiFi.EAP");
/*
@@ -3529,10 +3631,9 @@ found:
return;
}
- if (wifi->network) {
+ if (wifi->network != wifi->pending_network)
connman_network_set_connected(wifi->network, false);
- wifi->network = NULL;
- }
+ wifi->network = NULL;
wifi->disconnecting = false;
wifi->connected = false;
@@ -4032,17 +4133,20 @@ static void interface_state(GSupplicantInterface *interface)
if (!wifi)
return;
+ device = wifi->device;
+ if (!device)
+ return;
+
if (state == G_SUPPLICANT_STATE_COMPLETED) {
if (wifi->tethering_param) {
g_free(wifi->tethering_param->ssid);
g_free(wifi->tethering_param);
wifi->tethering_param = NULL;
}
- }
- device = wifi->device;
- if (!device)
- return;
+ if (wifi->tethering)
+ stop_autoscan(device);
+ }
if (g_supplicant_interface_get_ready(interface) &&
!wifi->interface_ready) {
@@ -4084,7 +4188,8 @@ static void interface_state(GSupplicantInterface *interface)
wifi->scan_pending_network = NULL;
/* should be cleared scanning flag */
- bool scanning = connman_device_get_scanning(device);
+ bool scanning = connman_device_get_scanning(device,
+ CONNMAN_SERVICE_TYPE_WIFI);
if (scanning){
connman_device_set_scanning(device,
CONNMAN_SERVICE_TYPE_WIFI, false);
@@ -4200,8 +4305,10 @@ static void interface_state(GSupplicantInterface *interface)
}
#endif
- connman_network_set_connected(network, false);
- connman_network_set_associating(network, false);
+ if (network != wifi->pending_network) {
+ connman_network_set_connected(network, false);
+ connman_network_set_associating(network, false);
+ }
wifi->disconnecting = false;
start_autoscan(device);
@@ -4427,8 +4534,6 @@ static void ap_create_fail(GSupplicantInterface *interface)
g_free(wifi->tethering_param);
wifi->tethering_param = NULL;
}
-
- return;
}
static unsigned char calculate_strength(GSupplicantNetwork *supplicant_network)
@@ -4436,11 +4541,11 @@ static unsigned char calculate_strength(GSupplicantNetwork *supplicant_network)
unsigned char strength;
strength = 120 + g_supplicant_network_get_signal(supplicant_network);
-
#if !defined TIZEN_EXT
if (strength > 100)
strength = 100;
#endif
+
return strength;
}
@@ -4623,22 +4728,24 @@ static void network_added(GSupplicantNetwork *supplicant_network)
connman_network_set_strength(network,
calculate_strength(supplicant_network));
connman_network_set_bool(network, "WiFi.WPS", wps);
+ connman_network_set_bool(network, "WiFi.WPSAdvertising",
+ wps_advertizing);
if (wps) {
/* Is AP advertizing for WPS association?
* If so, we decide to use WPS by default */
if (wps_ready && wps_pbc &&
- wps_advertizing) {
+ wps_advertizing)
#if !defined TIZEN_EXT
connman_network_set_bool(network, "WiFi.UseWPS", true);
#else
DBG("wps is activating by ap but ignore it.");
#endif
- }
}
connman_network_set_frequency(network,
g_supplicant_network_get_frequency(supplicant_network));
+
#if defined TIZEN_EXT
connman_network_set_bssid(network,
g_supplicant_network_get_bssid(supplicant_network));
@@ -4744,6 +4851,7 @@ static void network_changed(GSupplicantNetwork *network, const char *property)
struct wifi_data *wifi;
const char *name, *identifier;
struct connman_network *connman_network;
+ bool update_needed;
#if defined TIZEN_EXT
const unsigned char *bssid;
@@ -4769,11 +4877,42 @@ static void network_changed(GSupplicantNetwork *network, const char *property)
if (!connman_network)
return;
- if (g_str_equal(property, "Signal")) {
- connman_network_set_strength(connman_network,
+ if (g_str_equal(property, "WPSCapabilities")) {
+ bool wps;
+ bool wps_pbc;
+ bool wps_ready;
+ bool wps_advertizing;
+
+ wps = g_supplicant_network_get_wps(network);
+ wps_pbc = g_supplicant_network_is_wps_pbc(network);
+ wps_ready = g_supplicant_network_is_wps_active(network);
+ wps_advertizing =
+ g_supplicant_network_is_wps_advertizing(network);
+
+ connman_network_set_bool(connman_network, "WiFi.WPS", wps);
+ connman_network_set_bool(connman_network,
+ "WiFi.WPSAdvertising", wps_advertizing);
+
+ if (wps) {
+ /*
+ * Is AP advertizing for WPS association?
+ * If so, we decide to use WPS by default
+ */
+ if (wps_ready && wps_pbc && wps_advertizing)
+ connman_network_set_bool(connman_network,
+ "WiFi.UseWPS", true);
+ }
+
+ update_needed = true;
+ } else if (g_str_equal(property, "Signal")) {
+ connman_network_set_strength(connman_network,
calculate_strength(network));
- connman_network_update(connman_network);
- }
+ update_needed = true;
+ } else
+ update_needed = false;
+
+ if (update_needed)
+ connman_network_update(connman_network);
#if defined TIZEN_EXT
bssid = g_supplicant_network_get_bssid(network);
@@ -4815,6 +4954,10 @@ static void network_associated(GSupplicantNetwork *network)
if (!wifi)
return;
+ /* P2P networks must not be treated as WiFi networks */
+ if (wifi->p2p_connecting || wifi->p2p_device)
+ return;
+
identifier = g_supplicant_network_get_identifier(network);
connman_network = connman_device_get_network(wifi->device, identifier);
@@ -4849,6 +4992,32 @@ static void network_associated(GSupplicantNetwork *network)
interface_state(interface);
}
+static void sta_authorized(GSupplicantInterface *interface,
+ const char *addr)
+{
+ struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
+
+ DBG("wifi %p station %s authorized", wifi, addr);
+
+ if (!wifi || !wifi->tethering)
+ return;
+
+ __connman_tethering_client_register(addr);
+}
+
+static void sta_deauthorized(GSupplicantInterface *interface,
+ const char *addr)
+{
+ struct wifi_data *wifi = g_supplicant_interface_get_data(interface);
+
+ DBG("wifi %p station %s deauthorized", wifi, addr);
+
+ if (!wifi || !wifi->tethering)
+ return;
+
+ __connman_tethering_client_unregister(addr);
+}
+
static void apply_peer_services(GSupplicantPeer *peer,
struct connman_peer *connman_peer)
{
@@ -4866,17 +5035,6 @@ static void apply_peer_services(GSupplicantPeer *peer,
}
}
-static void add_station(const char *mac)
-{
- connman_technology_tethering_add_station(CONNMAN_SERVICE_TYPE_WIFI,
- mac);
-}
-
-static void remove_station(const char *mac)
-{
- connman_technology_tethering_remove_station(mac);
-}
-
static void peer_found(GSupplicantPeer *peer)
{
GSupplicantInterface *iface = g_supplicant_peer_get_interface(peer);
@@ -4884,6 +5042,7 @@ static void peer_found(GSupplicantPeer *peer)
struct connman_peer *connman_peer;
const char *identifier, *name;
int ret;
+
#if defined TIZEN_EXT
if (!wifi)
return;
@@ -5182,8 +5341,8 @@ static const GSupplicantCallbacks callbacks = {
.network_removed = network_removed,
.network_changed = network_changed,
.network_associated = network_associated,
- .add_station = add_station,
- .remove_station = remove_station,
+ .sta_authorized = sta_authorized,
+ .sta_deauthorized = sta_deauthorized,
.peer_found = peer_found,
.peer_lost = peer_lost,
.peer_changed = peer_changed,
@@ -5218,8 +5377,7 @@ 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 char *ssid, const char *passphrase)
{
GSupplicantSSID *ap;
@@ -5321,7 +5479,7 @@ static void sta_remove_callback(int result,
DBG("ifname %s result %d ", info->ifname, result);
- if (result < 0 || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
+ if ((result < 0) || (info->wifi->ap_supported != WIFI_AP_SUPPORTED)) {
info->wifi->tethering = false;
connman_technology_tethering_notify(info->technology, false);
@@ -5367,10 +5525,9 @@ static int enable_wifi_tethering(struct connman_technology *technology,
if (!interface)
continue;
- if (wifi->ap_supported == WIFI_AP_NOT_SUPPORTED)
- continue;
-
ifname = g_supplicant_interface_get_ifname(wifi->interface);
+ if (!ifname)
+ continue;
if (wifi->ap_supported == WIFI_AP_NOT_SUPPORTED) {
DBG("%s does not support AP mode (detected)", ifname);
@@ -5405,8 +5562,6 @@ static int enable_wifi_tethering(struct connman_technology *technology,
goto failed;
info->ifname = g_strdup(ifname);
- if (!info->ifname)
- goto failed;
wifi->tethering_param->technology = technology;
wifi->tethering_param->ssid = ssid_ap_init(identifier, passphrase);