diff options
author | Nishant Chaprana <n.chaprana@samsung.com> | 2019-09-17 19:00:55 +0530 |
---|---|---|
committer | Nishant Chaprana <n.chaprana@samsung.com> | 2019-09-18 19:23:41 +0530 |
commit | 26cc90dfaf2ad149b702626f9552c81abbb26862 (patch) | |
tree | 2524c8994cf58358350fde67dfba5c3b8cb58f7d /plugins | |
parent | 9e3beb21876b6e63bd8acf53e751480d7a1cc16f (diff) | |
parent | 6b2381a2adabea7d8309ff158ef675ff88184305 (diff) | |
download | connman-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-x | plugins/bluetooth.c | 1 | ||||
-rw-r--r-- | plugins/ethernet.c | 4 | ||||
-rwxr-xr-x | plugins/gadget.c | 89 | ||||
-rwxr-xr-x | plugins/iospm.c | 2 | ||||
-rw-r--r-- | plugins/iwd.c | 97 | ||||
-rwxr-xr-x | plugins/loopback.c | 73 | ||||
-rwxr-xr-x | plugins/nmcompat.c | 2 | ||||
-rwxr-xr-x | plugins/ofono.c | 5 | ||||
-rwxr-xr-x | plugins/pacrunner.c | 2 | ||||
-rwxr-xr-x | plugins/session_policy_local.c | 6 | ||||
-rwxr-xr-x | plugins/tist.c | 1 | ||||
-rwxr-xr-x | plugins/vpn.c | 233 | ||||
-rw-r--r-- | plugins/wifi.c | 355 |
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); |